Каскадность в 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 */

Тег <p> внутри элемента .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 { width:100%; }