Каскадность в CSS: как вычисляется специфичность (приорит) стилей
CSS — это каскадные таблицы стилей (Cascading Style Sheets). Каскадность — это главный принцип css — это приоритет одних правил/стилей над другими. Когда одни стили перебивают другие. Это понятие также называется "специфичность селектора".
Читайте также о специфичности: https://developer.mozilla.org/ru/docs/Web/CSS/Specificity
Смотрите также:
При вычислении приоритета браузер определяет «Вес» каждого CSS правила. Вес правила - это сумма весов каждого элемента селектора.
Таблица веса каждого элемента селектора:
Тип селектора | Описание селектора | Вес (число) |
---|---|---|
* | универсальный селектор | 0 |
div | тег | 1 |
:first-letter | псевдо-элемент | 1 |
.class | класс | 10 |
:hover | псевдо-класс | 10 |
[атрибут="значение"] | селектор атрибута | 10 |
#content | селектор по id | 100 |
style="color:red;" | стили в style атрибуте | 1000 |
!important | суффикс увеличения веса | 10000 |
Пример подсчета веса:
#content .text p { color: red; } /* 100 + 10 + 1 = 111 */ .text p { color: blue; } /* 10 + 1 = 11 */
Сильные (по весу) стили заменяют слабые и элемент получает стили от самых «весомых» правил. Это и есть каскадность.
Тег <p> внутри элемента .text получит стиль color:red;
, а не color:blue;
, потому что число 111 больше чем 11.
Если вес одинаковый, то применяются те стили, которые указаны позднее - ближе к концу HTML страницы (ниже в коде).
На практике считать приоритеты не нужно. Но нужно понимать как это работают, и какой из элементов селектора весомее остальных.
Еще примеры подсчета веса:
* {} /* 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 */ .foo {} /* 10 */ .foo[class] {} /* 20 */ #t34 {} /* 100 */ #content #wrap {} /* 200 */
Трюк с увеличением веса. Допустим нам нужно увеличить приоритет стилей, при этом не добавляя не-универсальных селекторов. Сделать это можно:
- продублировав селектор.
- добавив селектор атрибута или псевдо-класса.
.class.class { color:blue; } /* вес = 20 */ .class[class] { color:blue; } /* вес = 20 */ .class { color:red; } /* вес = 10 */ 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 { width:100%; }