Каскадность в CSS

В этой статье учебника мы узнаем почему таблицы стилей называют каскадными, как происходит взаимодействие стилей между собой внутри документа, познакомимся с системой приоритетов и конечно рассмотрим необходимые для понимания этой темы примеры.


Прежде всего, что такое каскадность? Каскадность – это правила, по которым определяется какие стилевые свойства задаются браузером элементам на странице (последовательность применения стилей к определённым элементам и разрешение при необходимости, возникающих конфликтов).


Давайте рассмотрим следующее изображение, на нем отображены основные источники информации о стилях, которые образуют каскад:

Рис. 30 Основные источники информации о стилях. Рис. 30 Основные источники информации о стилях.

К основным источникам информации о стилях относятся:

Наименьшим приоритетом из этого списка обладают встроенные стили браузера, а для пользовательских устанавливается наивысший приоритет, но это нас не должно интересовать, ведь кто как хочет, так и стилизует, и это не предмет этой статьи учебника.


Главное надо понять, что если на странице применяется несколько стилей к одному элементу, то браузер объединит свойства этих стилей, при условии, что они не конфликтуют между собой (имеют различные значения для однотипных свойств). А если конфликтуют?


Давайте перейдем к практической части.

Предположим, что у нас есть абзац (элемент <p>), в котором указана определенная гиперссылка (элемент <a>). HTML код может выглядеть следующим образом:

<p class = "main"> Для перехода к основной статье нажмите <a href = "#"> вот на это место. </a></p>

На нашу страницу добавим следующие стили:

a { /* используем селектор типа */
color: brown; /* устанавливаем цвет текста */
}
p a { /* используем селектор потомков */
font-weight: bold; /* устанавливаем жирное начертание шрифта */
}
.main a { /* используем селектор потомков */
background-color: orange; /* задаем цвет заднего фона */
text-decoration: none; /* убираем декорирование текста (нижнее подчеркивание) */
}

Создадим разметку и добавим стили в наш документ:

<!DOCTYPE html>
<html>
<head>
	<meta charset = "UTF-8">
	<title>Каскадность в CSS</title>
<style>
a { /* используем селектор типа */
color: brown; /* устанавливаем цвет текста */
}
p a { /* используем селектор потомков */
font-weight: bold; /* устанавливаем жирное начертание шрифта */
}
.main a { /* используем селектор потомков */
background-color: orange; /* задаем цвет заднего фона */
text-decoration: none; /* убираем декорирование текста (нижнее подчеркивание) */
}
</style>
</head>
	<body>
		<p class = "main">Для перехода к основной статье нажмите <a href = "#"> вот на это место. </a></p>
	</body>
</html> 

Результат нашего примера:

Рис. 30а Каскадность в CSS.
Рис. 30а Каскадность в CSS.

Давайте рассмотрим какие стили были применены к элементу <a>:

Рис. 30б Применение стилей к элементу.
Рис. 30б Применение стилей к элементу.

В данном примере вы можете увидеть, что все три наших селектора с различными стилями были применены к элементу <a>, а встроенные стили элемента - цвет и декорирование текста (нижнее подчеркивание) были заменены на авторские стили (стили автора документа) по той причине, что они имеют больший приоритет.

Система приоритетов в CSS

Давайте рассмотрим пример, где не всё так очевидно и однозначно. К примеру, с использованием свойства font-family зададим элементу <a> различный тип шрифта с использованием аналогичных селекторов:

<!DOCTYPE html>
<html>
<head>
	<meta charset = "UTF-8">
	<title>Конфликты стилей в CSS</title>
<style>
a { /* используем селектор типа */
color: brown; /* устанавливаем цвет текста */
font-family: Arial; /* устанавливаем тип шрифта Arial */
}
p a { /* используем селектор потомков */
font-weight: bold; /* устанавливаем жирное начертание шрифта */
font-family: Helvetica; /* устанавливаем тип шрифта Helvetica */
}
.main a { /* используем селектор потомков */
background-color: orange; /* задаем цвет заднего фона */
text-decoration: none; /* убираем декорирование текста (нижнее подчеркивание) */
font-family: Courier; /* устанавливаем тип шрифта Courier */
}
</style>
</head>
	<body>
		<p class = "main">Для перехода к основной статье нажмите <a href = "#"> вот на это место. </a></p>
	</body>
</html> 

Результат нашего примера:

Рис. 31 Пример конфликтования стилей.
Рис. 31 Пример конфликтования стилей.

Давайте рассмотрим какой шрифт получил элемент <a>:

Рис. 31a Выбор типа шрифта при конфликте стилей.
Рис. 31a Выбор типа шрифта при конфликте стилей.

Обратите внимание, что для нашего элемента был установлен шрифт Courier. Как мы видим в "инструментах разрабочика" браузера Chrome этот шрифт выбран из селектора потомков в котором используется как селектор класса, так и селектор типа (.main a), а в остальных селекторах тип шрифта для элемента перечеркнут. Но почему?


Я уже обращал Ваше внимание на тот факт, что основное правило механизма каскадности - побеждает тот, у кого установлен самый явно определенный стиль. Для этих целей в CSS существует своя система приоритетов, которая основана на присвоении значений в пунктах для каждого типа селекторов, чем выше это значение, тем выше его значимость:


Давайте перейдем к следующему примеру в котором рассмотрим как работает система приоритетов:

<!DOCTYPE html>
<html>
<head>
	<meta charset = "UTF-8">
	<title>Работа системы приоритетов в CSS</title>
<style>
#id_invite { /* id селектор — 100 пунктов */
color: red; /* устанавливаем цвет текста красный */
}
.class_invite { /* селектор класса — 10 пунктов */
color: blue; /* устанавливаем цвет текста синий */
}
p { /* селектор типа — 1 пункт */
color: green; /* устанавливаем цвет текста зеленый */
}
</style>
</head>
	<body>
		<!-- устанавливаем цвет текста внутри элемента span зеленый (inline стиль) -->
		<p class = "class_invite" id = "id_invite">Просто <span style = "color: green;">добавь</span> воды.</p>
	</body>
</html> 

В данном примере для элемента <p> был установлен красный цвет текста благодаря id селектору, который имеет более высокое значение в пунтах чем другие селекторы (100). Кроме того, для демонстрации системы приоритетов мы применили встроенный (inline) стиль для элемента <span> и установили для него зеленый цвет шрифта. Обратите внимание, что на изображении, все значения селекторов перечеркнуты, так как встроенный стиль имеет самое высокое значение в пунктах (1000).

 Рис. 32 Пример системы приоритетов в CSS.
Рис 32 Пример системы приоритетов в CSS.

Чтобы подсчитать специфичность комбинированных селекторов необходимо их просто сложить между собой, например:

#id_invite a { /* id селектор (100 пунктов) + селектор типа (1 пункт) = 101 пункт  */
блок объявлений;
}
p:first-letter { /* селектор типа (1 пункт) + псевдоэлемент (1 пункт) = 2 пункта  */
блок объявлений;
}
.main:first-child { /* селектор класса (10 пунктов) + псевдокласс (10 пунктов) = 20 пунктов  */
блок объявлений;
}

Отмена значимости стилей

В некоторых случаях, два стиля могут иметь одинаковый приоритет (одинаковое количество пунктов), что доставляет сильную головную боль по той причине, что браузер в этом случае выбирает последний определенный стиль в таблице стилей, что может не соответствовать вашим ожиданиям. Если вы поменяете местами конфликтующие стили, то действовать будет тот, который будет указан ниже в таблице стилей. Старайтесь избегать подобных ситуаций и запомните этот момент. Эти знания помогут Вам сэкономить большое количество времени.

В CSS предусмотрена возможность отменить значимость стилей (не учитывать количество пунктов). Для этого необходимо добавить к значению CSS свойства ключевое слово !important.

Давайте рассмотрим пример использования ключевого слова !important:

<!DOCTYPE html>
<html>
<head>
	<meta charset = "UTF-8">
	<title>Пример отмены значимости стилей</title>
<style>
a.rtfm { /* селектор типа (1 пункт) + селектор класса (10 пунков) = 11 пунктов  */
color: green; /* устанавливаем цвет текста зеленый */
}
a { /* селектор типа (1 пункт)  */
color: red !important; /* отменяем значимость стилей и устанавливаем цвет текста красный */
}
</style>
</head>
	<body>
		<a class =  "rtfm"  href =  "http://google.com">Найти</a>
	</body>
</html> 

В этом примере с использованием ключевого слова !important мы отменили значимость стилей и установили цвет текста для гиперссылки красный. В данном случае если бы мы не использовали ключевое слово !important, то цвет бы остался зеленым по той причине, что он имеет большую значимость (задан с использованием селектора класса).

Результат нашего примера:

Рис. 33 Пример отмены значимости стилей.
Рис. 33 Пример отмены значимости стилей.

Обратите внимание, что !important указывается в конце каждого свойства и действует только на одно свойство, а не на весь блок объявлений!


Если вы указали значение !important для двух однотипных свойств различных стилей, то в этом случае браузер рассматривает их по принципу правил значимости (приоритет отдаётся более значимому свойству). Старайтесь избегать подобных ситуаций.

Сброс и нормализация встроенных стилей.

Ещё один необходимый метод для грамотного построения кроссбраузерных страниц - это необходимость сброса встроенных в браузер внутренних стилей (сброс стандартных стилей браузера). Другими словами, независимо какой браузер у пользователей, которые посещают Ваш сайт, отображение должно быть в одном стиле - с одинаковыми отступами, границами и форматированием.

Для этого существуют различные шаблоны, которые сбрасывают внутренние стили (reset.css). Как правило, шаблоны адаптируются под себя (под Ваши нужды) и служат для удаления полей и отступов, устанавливая например 100% размер шрифта, убирая выделения полужирным шрифтом, устанавливают пространство между строками в абзаце, убирают маркеры в списках и тому подобное.

В настоящее время часто в своей работе используют альтернативу традиционному reset.css (сбросу внутренних стилей), нормализовывая таблицы стилей - normalize.css.

Данный проект (normalize.css) появился после глубокого исследования различий между изначальными стилями браузера под руководством Николаса Галахера. Основные задачи normalize.css заключаются в том, чтобы сохранить полезные настройки браузера, а не стирать их, и при этом нормализовать стили для широкого круга HTML элементов.

Как вы понимаете, normalize.css значительно отличается от reset.css. Впоследствии, я Вам рекомендую попробовать в своей работе оба метода, чтобы определиться, соответствует ли конкретный метод вашим предпочтениям в разработке.

Пример CSS reset - http://meyerweb.com/eric/tools/css/reset/
Проект normalize css - https://necolas.github.io/normalize.css/


Вопросы и задачи по теме

Перед тем как перейти к следующей статье ответьте на следующие вопросы:

  • подсчитайте специфичность комбинированного селектора:
    .main a { 
    блок объявлений;
    }
    
    Показать ответ
  • подсчитайте специфичность комбинированного селектора:
    #main #section { 
    блок объявлений;
    }
    
    Показать ответ
  • подсчитайте специфичность комбинированного селектора:
    table.header tr:hover { 
    блок объявлений;
    }
    
    Показать ответ