- Каскадность в CSS: как высчитываются приоритеты стилей
- Приоритет @media
- Специфичность
- Как вычисляется специфичность?
- Типы селекторов
- Важное исключение из правил — !important
- Не исключение — :not()
- Специфичность основана на форме
- Независимость от расположения
- Непосредственно соответствующие элементы и унаследованные стили
- Дополнительная информация
- Found a content problem with this page?
- Каскадирование и специфичность CSS
Каскадность в CSS: как высчитываются приоритеты стилей
CSS — это каскадные таблицы стилей (Cascading Style Sheets). Каскадность — это главный принцип css — это приоритет одних правил/стилей над другими. Это когда одни стили перебивают другие.
При вычислении приоритета браузер определяет «Вес» каждого CSS правила, который складывается из веса отдельных селекторов этого правила. Стили менее весомых правил перебиваются стилями более весомых. В результате элемент получает собранные стили от самых «весомых» правил. Все это и есть каскадность.
Таблица веса (числа) для каждого селектора:
Тип селектора | Описание селектора | Вес (число) |
---|---|---|
* | универсальный селектор | 0 |
div | тег | 1 |
:first-letter | псевдо-элемент | 1 |
.text | класс | 10 |
:hover | псевдо-класс | 10 |
[атрибут=»значение»] | селектор атрибута | 10 |
#content | селектор по id | 100 |
style=»color:red;» | стили в style атрибуте | 1000 |
!important | суффикс увеличения веса | 10000 |
Из правил с одинаковым весом выбираются те, которые ближе к концу HTML страницы (ниже в коде).
Пример подсчета веса (вес представляет из себя число):
#content .text p < color:red; >/* 100 + 10 + 1 = 111 */ .text p < color:blue; >/* 10 + 1 = 11 */
Тег
внутри элемента .text получит стиль color:red; , а не color:blue; , потому что число 111 больше чем 11.
Теперь давайте посчитаем веса на примере:
* <> /* = 0 */ li <> /* = 1 */ li::first-line <> /* = 2 */ ul li <> /* = 2 */ ul ol + li <> /* = 3 */ ul li.red <> /* = 12 */ li.red.level <> /* = 21 */ li:not(.red)<> /* = 11 */ li:not(.red):not(.green)<> /* = 11 */ #t34 <> /* = 100 */ #content #wrap <> /* = 200 */
Считать приоритеты никогда не нужно на практике, но нужно понимать как это работают и какой из селекторов важнее остальных.
Трюк с увеличением веса. Допустим у нас есть один селектор в правиле, но нам нужно увеличить приоритет стилей, при этом не добавляя каких-то дополнительных селекторов. Сделать это можно просто продублировав селектор или добавишь селектор атрибута или псевдо-класса:
.class.class < color:blue; >/* сильнее чем .class */ .class < color:red; >img[src] < >/* вес = 11 */
Приоритет @media
Медиа правила @media ( max-width:500px ) < >не участвуют в подсчете приоритета (веса).
Поэтому они всегда должны располагаться ниже всех остальных правил, чтобы перебивать предыдущие правила с таким же весом (приоритетом).
.section < width:100%; >@media ( max-width:500px ) < .section < width:50%; >>
@media ( max-width: 500px ) < .section < width:50%; >> .section
Специфичность
Специфичность — это способ, с помощью которого браузеры определяют, какие значения свойств CSS наиболее соответствуют элементу и, следовательно, будут применены. Специфичность основана на правилах соответствия, состоящих из селекторов CSS различных типов.
Как вычисляется специфичность?
Специфичность представляет собой вес, придаваемый конкретному правилу CSS. Вес правила определяется количеством каждого из типов селекторов в данном правиле. Если у нескольких правил специфичность одинакова, то к элементу применяется последнее по порядку правило CSS. Специфичность имеет значение только в том случае, если один элемент соответствует нескольким правилам. Согласно спецификации CSS, правило для непосредственно соответствующего элемента всегда будет иметь больший приоритет, чем правила, унаследованные от предка.
Примечание: Примечание: Взаимное расположение элементов в дереве документа не влияет на специфичность.
Типы селекторов
В следующем списке типы селекторов расположены по возрастанию специфичности:
- селекторы типов элементов (например, h1 ) и псевдоэлементов (например, ::before ).
- селекторы классов (например, .example ), селекторы атрибутов (например, [type=»radio»] ) и псевдоклассов (например, :hover ).
- селекторы идентификаторов (например, #example ).
Универсальный селектор ( * ), комбинаторы ( + , > , ~ , ‘«’) и отрицающий псевдокласс ( :not() ) не влияют на специфичность. (Однако селекторы, объявленные внутри :not() , влияют)
Стили, объявленные в элементе (например, style=»font-weight:bold» ), всегда переопределяют любые правила из внешних файлов стилей и, таким образом, их специфичность можно считать наивысшей.
Важное исключение из правил — !important
Когда при объявлении стиля используется модификатор !important , это объявление получает наивысший приоритет среди всех прочих объявлений. Хотя технически модификатор !important не имеет со специфичностью ничего общего, он непосредственно на неё влияет. Поскольку !important усложняет отладку, нарушая естественное каскадирование ваших стилей, он не приветствуется и следует избегать его использования. Если к элементу применимы два взаимоисключающих стиля с модификатором !important , то применён будет стиль с большей специфичностью.
Несколько практических советов:
- Всегда пытайтесь использовать специфичность, а !important используйте только в крайних случаях
- Используйте !important только в страничных стилях, которые переопределяют стили сайта или внешние стили (стили библиотек, таких как Bootstrap или normalize.css)
- Никогда не используйте !important , если вы пишете плагин или мэшап.
- Никогда не используйте !important в общем CSS сайта.
Вместо !important можно:
- Лучше использовать каскадные свойства CSS
- Использовать более специфичные правила. Чтобы сделать правило более специфичным и повысить его приоритет, укажите один элемент или несколько перед нужным вам элементом:
div id="test"> span>Textspan> div>
div#test span color: green > div span color: blue > span color: red >
Вне зависимости от порядка следования правил, текст всегда будет зелёным, поскольку у этого правила наибольшая специфичность (при этом, правило для голубого цвета имеет преимущество перед правилом для красного, несмотря на порядок следования).
Вам придётся использовать !important если:
- У вас есть общий файл стилей, устанавливающий правила для внешнего вида сайта.
- Вы пользуетесь (или кто-то другой пользуется) весьма сомнительным средством — объявлением стилей непосредственно в элементах
В таком случае вам придётся объявить некоторые стили в вашем общем файле CSS как !important , переопределяя, таким образом, стили, установленные в самих элементах.
Пример из практики: Некоторые плохо написанные плагины jQuery, использующие присваивание стилей самим элементам.
#someElement p color: blue; > p.awesome color: red; >
Как сделать цвет текста в абзацах awesome красным всегда, даже если они расположены внутри #someElement ? Без !important у первого правила специфичность больше и оно имеет преимущество перед вторым.
Как преодолеть !important
A) Просто добавьте ещё одно правило с модификатором !important , у которого селектор имеет большую специфичность (благодаря добавлению типа элемента (тэга), идентификатора (атрибута id) или класса к селектору).
Пример большей специфичности:
table td height: 50px !important;> .myTable td height: 50px !important;> #myTable td height: 50px !important;>
Б) Или добавьте правило с модификатором !important и таким же селектором, но расположенное в файле после существующего (при прочих равных выигрывает последнее объявленное правило):
В) Или перепишите первоначальное правило без использования !important .
С более подробной информацией можно ознакомиться по следующим ссылкам:
Не исключение — :not()
Отрицающий псевдокласс :not не учитывается как псевдокласс при расчёте специфичности. Однако селекторы, расположенные внутри :not , при подсчёте количества по типам селекторов рассматриваются как обычные селекторы и учитываются.
div.outer p color: orange; > div:not(.outer) p color: lime; >
. применённый к такому HTML .
div class="outer"> p>Это div.outerp> div class="inner"> p>Это текст в div.innerp> div> div>
. отобразится на экране так:
Специфичность основана на форме
Специфичность опирается на форму селектора. В следующем примере, при определении специфичности селектора, селектор *[id=»foo»] считается селектором атрибута, даже при том, что ищет идентификатор.
*#foo color: green; > *[id="foo"] color: purple; >
. применённые к нижеследующей разметке .
. в результате выглядят так:
Потому что оба правила соответствуют одному и тому же элементу, но селектор идентификатора имеет большую специфичность.
Независимость от расположения
Взаимное расположение элементов, указанных в селекторе не влияет на специфичность правила. Следующие объявления стилей .
body h1 color: green; > html h1 color: purple; >
. в сочетании со следующим HTML .
html> body> h1>Вот заголовок!h1> body> html>
Потому что, хотя оба объявления имеют одинаковое количество типов селекторов, но селектор html h1 объявлен последним.
Непосредственно соответствующие элементы и унаследованные стили
Стили непосредственно соответствующих элементов всегда предпочитаются унаследованным стилям, независимо от специфичности унаследованного правила. Этот CSS .
#parent color: green; > h1 color: purple; >
html> body id="parent"> h1>Вот заголовок!h1> body> html>
Потому что селектор h1 непосредственно соответствует элементу, а стиль, задающий зелёный цвет, всего лишь унаследован от родителя.
Дополнительная информация
- Калькулятор специфичности: Интерактивный сайт, помогающий вам проверить и понять ваши собственные правила CSS — https://specificity.keegan.st/
- Специфичность селекторов в CSS3 — http://www.w3.org/TR/selectors/#specificity
- Ключевые концепции CSS
- Синтаксис CSS
- @-правила
- комментарии
- специфичность
- наследование
- блочная модель
- режимы компоновки
- модели визуального форматирования
- Схлопывание отступов
- Значения
- начальные
- вычисленные
- используемые
- действительные
Found a content problem with this page?
This page was last modified on 30 нояб. 2022 г. by MDN contributors.
Your blueprint for a better internet.
Каскадирование и специфичность CSS
Наверно у многих, кто занимается (занимался) версткой и в плотную сталкивался с таблицами стилей, наступали моменты когда !important на !important’e сидел, css превращался в вереницу длинных цепочек, но все равно кто-то, где-то, кого-то перебивал (или наоборот). И не совсем ясно, почему так происходит.
Давайте раз и навсегда разберемся с каскадированием стилей и специфичностью селекторов.
Специфичность селекторов определяет их приоритетность в таблице стилей. Чем специфичнее селектор, тем выше его приоритет.
Подсчитать приоритет селектора очень просто.- inline-стили имеют специфичность 1000
- за каждый идентификатор (#) 0100
- за каждый класс (.) и псевдо-класс (. []) 0010
- за каждый тег и псевдо-элемент 0001
- * и стили браузера 0000
* /* специфичность 0000 */ li /* специфичность 0001*/ ul li /* специфичность 0002*/ .list li /* специфичность 0011*/ #list li /* специфичность 0101*/ a[href^="http://"] /* специфичность 0011 */
При добавлении !important приоритет становится главенствующим. Если !important несколько
стоит задуматься о смене профессииони начинают подчиняться тем же правилам.li /* специфичность 0001 - win*/ ul li /* специфичность 0002*/
li /* специфичность 0001*/ ul li /* специфичность 0002 - win*/
После всех манипуляций специфичность совпала — выигрывает последнее (то что ниже) правило.
Ну и конечно же CSS-анимации, имеющие приоритет выше, даже чем !important в inline-стилях.
UPD Почему 11 классов не имеют большего приоритета над идентификатором читать здесь