CSS :: Наследование, каскадирование и приоритетность стилей
Наследование в CSS
Все свойства CSS делятся на те, которые наследуются элементами-потомками от своих элементов-предков, и те, которые не наследуются. Так, например, если для параграфа задать границу (сформировать рамку), то все вложенные в него элементы (элементы-потомки) не унаследуют это свойство CSS, поскольку в данном случае наследование не имеет положительного эффекта. Согласитесь, не совсем разумно было бы переопределять для каждого элемента-потомка унаследованные от абзаца-родителя границы. Но, если мы зададим для абзаца, например, синий цвет шрифта, то он будет унаследован всеми элементами потомками до тех пор, пока мы не переопределим его в случае необходимости для конкретного элемента, а это эффективнее, чем определять шрифт отдельно для каждого элемента-потомка. Узнать, какие стилевые свойства наследуются, а какие нет, можно в нашем справочнике CSS здесь.
Каскадирование стилей CSS
Каскадирование стилей – это встроенная особенность CSS, которая заключается в том, что если к элементу применяется сразу несколько стилей, то результирующий стиль будет сформирован из всех присутствующих в этих стилях видов свойств, при чем в случае наличия двух или более одинаковых свойств к элементу будет применено значение свойства с наибольшим в данной ситуации приоритетом.
Давайте для начала рассмотрим простейший случай, показанный в примере №1.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Наследование стилей</title> <style> p{ color: red; background-color: black; } /* Для абзацев с атрибутом class="yellow_back" добавляем ширину и переопределяем фон */ p.yellow_back{ background-color: yellow; width: 200px; } </style> </head> <body> <p> Текст простого абзаца. </p> <p class="yellow_back"> Текст абзаца с классом. </p> <p class="yellow_back" style="color: blue; width: 400px;"> Переопределяем и цвет шрифта, и ширину абзаца. </p> </body> </html>
Пример №1. Простейший случай каскадности стилей CSS
Как видно из примера, к первому абзацу применяется только первый стиль из внутренней таблицы стилей, который задает ему черный фон и красный цвет шрифта. Ко второму абзацу применяется уже два стиля из внутренней таблицы стилей, поэтому результирующий стиль формируется следующим образом: сперва берутся все свойства стиля, у которого специфичность (конкретность) селектора больше (в нашем случае это второй стиль), затем добавляются отсутствующие в нем свойства из других, применяемых к данному элементу стилей, у которых специфичность (конкретность) селектора меньше (в нашем случае это первый стиль). Таким образом, для второго абзаца будет добавлена ширина, а фон будет переопределен с черного на желтый. К третьему абзацу применяется сразу три стиля: два из внутренней таблицы стилей и собственный встроенный стиль. Встроенный стиль обладает наибольшим приоритетом, поэтому он переопределит цвет шрифта, заданный в первом стиле, и ширину, заданную во втором стиле внутренней таблицы стилей.
Таким образом, чтобы правильно рассчитать результирующий стиль, применяемый к элементу, необходимо знать правила формирования этого стиля в случае наложения нескольких стилей сразу. Правила эти сводятся к расчету специфичности селекторов применяемых к элементу стилей, содержащих одинаковые css-свойства с разными значениями, а также, в случае равенства специфичности селекторов, к сравнению видов стилей, сравнению расположения таблиц с этими стилями или же, если они окажутся в одной и той же таблице стилей, сравнению их расположения в коде этой таблицы. Рассмотрим этот вопрос подробнее.
Специфичность селекторов CSS
Если к одному и тому же элементу применяются два правила, содержащие одинаковые свойства CSS, но имеющие разные значения, возникает конфликт, который может быть решен при помощи сравнения специфичности селекторов этих правил. В результате этого решения к элементу будет применено свойство правила, у которого специфичность селектора больше.
Расчет специфичности селектора производится при помощи трех чисел (a, b, c). Происходит это следующим образом:
- числу a присваивается количество идентификаторов в селекторе;
- числу b присваивается суммарное количество классов, атрибутов и псевдоклассов в селекторе;
- числу c присваивается суммарное количество элементов и псевдоэлементов.
После подсчета чисел у всех сравниваемых селекторов, селектором с большей специфичностью будет считаться тот, у которого больше число a, в независимости от величины чисел b и c. Если же у сравниваемых селекторов число a окажется одинаковым, будет сравниваться их число b, а в случае необходимости и число c (см. пример №2).
/* Запишем пример кода html */ /* <p class="my_class"> <em id="m_id" title="Город">Текст...</em> </p> */ /* Здесь а=1, т.к. в селекторе есть 1 идентификатор; */ /* b=0, т.к. есть 0 классов, 0 атрибутов и 0 псевдоклассов; */ /* с=0, т.к. есть 0 элементов и 0 псевдоэлементов; */ /* т.о. специфичность равна (1,0,0). */ #m_id{ color: blue; } /* Здесь а=0, т.к. в селекторе отсутствуют идентификаторы; */ /* b=3, т.к. есть 1 класс, 1 атрибут и 1 псевдокласс; */ /* с=2, т.к. присутствуют два элемента: «p» и «em»; */ /* т.о. специфичность равна (0,3,2). */ p.my_class em[title="Город"]:hover{ color: red; } /* Значит цвет текста в примере кода будет синим, т.к. во втором правиле число а=0, а в первом правиле а=1. */ /* А вот если бы специфичности селекторов были равны, то приоритет имел бы стиль нижнего правила. */
Пример №2. Сравнение специфичности селекторов
Виды и приоритет стилей CSS
В случае равенства специфичности селекторов сравниваемых правил, приоритет будет определяться по виду стиля, расположению таблиц стилей или же, если они окажутся в одной и той же таблице стилей, сравнению их расположения в коде этой таблицы. Перечислим основные виды стилей в порядке возрастания их приоритета.
- Стиль браузера обладает наиболее низким приоритетом и применяется по умолчанию к элементам html-кода, к которым не применяется другое форматирование, говоря проще – к «голому» html-коду.
- Стиль пользователя устанавливается в настройках браузера пользователем и по сути представляет собой измененный пользователем стиль браузера по умолчанию. Так что, если пользователь изменил стиль браузера, то по умолчанию станет применяться стиль пользователя.
- Стиль автора устанавливается автором страницы (программистом) и обладает еще большим приоритетом. Именно он нас и будет больше всего интересовать.
Авторский стиль представляет собой результирующий стиль, который формируется из различных видов составляющих его отдельных стилей, опять же, на основе каскадирования. Перечислим их в порядке возрастания приоритета в случае применения к одному и тому же элементу при условии равенства специфичности селекторов.
- Стили, унаследованные элементами-потомками от своих родителей, обладают самым низким приоритетом.
- Стили, заданные во внешних таблицах обладают большим приоритетом. При этом правила, которые идут в коде внешней таблицы стилей ниже (т.е. встречаются позже) имеют больший приоритет перед правилами, которые встречаются в коде этой таблицы выше (т.е. раньше). Кроме того, из нескольких внешних таблиц стилей большим приоритетом обладают таблицы, подключенные к документу при помощи элемента «link» ниже в коде этого документа. Соответственно, если таблица подключена в коде документа выше, то приоритет ее стилей будет ниже.
- Стили внутренних таблиц (расположены внутри контейнеров «style») имеют приоритет перед стилями внешних таблиц, но только если они расположены в коде ниже, чем элемент «link», при помощи которого была подключена внешняя таблица стилей. Опять же, правила, которые идут в коде внутренней таблицы стилей ниже имеют больший приоритет перед правилами, которые встречаются в коде этой таблицы выше. Кроме того, если в документе используется несколько внутренних таблиц стилей, т.е. имеется несколько элементов «style», то большим приоритетом обладают стили тех таблиц, которые расположены в коде документа ниже.
- Еще большим приоритетом обладают встроенные стили, которые преобладают над правилами с любой специфичностью селекторов. Действительно, куда уже конкретнее, если стиль расположен в открывающем теге элемента.
Служебный параметр !important
Отдельно следует сказать про служебный параметр !important (от англ. important – важный), который указывается в случае необходимости во внутренних и внешних таблицах стилей после значения css-свойства через пробел, например, p{color: green !important;} (см. пример №3). Свойство стиля, в котором указан данный параметр, обладает наибольшим приоритетом в независимости от расположения таблицы стилей в коде документа или же самого правила внутри таблицы стилей, но только в ситуации, когда специфичности стилей равны (при этом не следует забывать, что специфичность встроенного стиля следует считать наивысшей в любом случае!). Опять же, если свойств с таким параметром несколько, да еще и специфичности соответствующих селекторов одинаковы, то приоритет будет определяться по виду стиля, расположению таблиц стилей или же, если они окажутся в одной и той же таблице стилей, сравнению их расположения в коде этой таблицы.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Модификатор !important</title> <style> /* Специфичность селектора выше */ div p.green_normal{ color: #007700; font-weight: normal; } /* Специфичность селектора ниже, */ /* плюс отсутствует !important */ .bold_wrong{ font-weight: bold; } /* Специфичность селектора ниже, */ /* но присутствует !important */ .bold_font{ font-weight: bold !important; } </style> </head> <body> <div> <p class="green_normal"> Получаем обычный текст, зеленого цвета. </p> </div> <div> <p class="green_normal bold_wrong"> Начертание не стало полужирным, т.к. приоритет<br> селектора .bold_font ниже, чем селектора div p.green_normal. </p> </div> <div> <p class="green_normal bold_font"> Цвет текста остался зеленым, но начертание стало полужирным,<br> т.к. в подключенном классе .bold_font присутствует !important. </p> </div> <div> <p class="green_normal bold_font"> Цвет текста остался зеленым, но начертание стало полужирным,<br> т.к. в подключенном классе .bold_font присутствует !important.<br> <span style="font-weight: normal">Но мое начертание осталось обычным,<br> т.к. встроенный стиль имеет наивысший приоритет.</span> </p> </div> </body> </html>
Пример №3
Всегда пытайтесь использовать специфичность, а не модификатор !important, т.к. он усложняет отладку, нарушая естественное каскадирование стилей.
Из сказанного выше, следует простой вывод: чем ближе стиль расположен к элементу и чем более конкретнее его селектор, тем большим приоритетом он обладает.
Использование одинаковых свойств CSS в одном правиле
В заключение данного пункта добавим, что в одном и том же правиле иногда задают два одинаковых свойства, но с разными значениями (см. пример №4). Так обычно поступают, когда одно из значений свойства не поддерживается каким-нибудь браузером, тогда его помещают в блоке объявлений (стиле) вторым, а другое правило, которое поддерживается всеми браузерами, помещают первым. В результате, если страница открывается в браузере, в котором второе правило не имеет силы, оно будет проигнорировано, а браузер применит первое правило. Если же страница открывается в браузере, в котором имеют силу и первое и второе правила, то второе правило будет иметь больший приоритет, т.к. следует в коде позже. Таким образом, в любом случае будет реализована задумка программиста, а не применено значение свойства устанавливаемое браузером по умолчанию или наследуемое от родительского элемента.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Одинаковые свойства в одном правиле</title> <style> p{ width: 450px; color: blue; color: superblue; } </style> </head> <body> <p> Цвет текста будет просто синим, т.к. значение superblue не поддерживается браузером и будет просто проигнорировано. </p> </body> </html>
Пример №4
Быстрый переход к другим страницам
- Селекторы CSS
- Наследование, каскадирование и приоритетность стилей CSS
- Единицы измерения, использующиеся в CSS
- Вернуться к оглавлению учебника