Обложка статьи «Перестаньте использовать !important. Помогаем разобраться с каскадом CSS»

Перестаньте использовать !important. Помогаем разобраться с каскадом CSS

На основе «The CSS Cascade»

Когда CSS-правило не работает, многие разработчики хотят добавить !important и забыть о проблеме. Рассказываем, почему так делать не стоит и как правильно работать с CSS.

Почему CSS-правило может не работать?

Когда браузер загружает веб-страницу, он собирает все CSS-правила, которые встречает: из внешних файлов, напрямую указанные в HTML-коде, добавленные с помощью JS. У каждого правила есть селектор, которые говорит к каким HTML-элементам его надо применять. Часто так случается, что один и тот же элемент получает не одно правило, а два и больше. И иногда эти правила даже относятся к одним и тем же свойствам.

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

Так как понять, какое CSS-правило «главнее»?

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

Но вернёмся к !important. Это магическое слово сразу же поднимет приоритет вашего CSS-правила до небес. Но так всё равно лучше не делать, потому что:

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

Зачем же всё таки иногда нужен !important?

  • Чтобы переписать inline-свойства. Нужно редко, но иногда пригождается.
  • Чтобы переписать !important сторонней библиотеки. Если её разработчик по какой-то причине его использовал. Возможно как раз потому, что не понимал каскад.
  • Для прототипирования. Чтобы быстро прописать новые стили, вывести их наверх каскада, посмотреть результат и если всё устраивается — переписать правильно.

Как работает каскад CSS?

Общий принцип прост: «Чем специфичнее правило — тем выше оно в каскаде». Например, у нас на сайте в списке статей на главной каждый пост — это контейнер с классом box. У него прописан стиль

.box {
    box-shadow: 0 0 0 1px rgba(0,0,0,.05);
}

Это правило добавляет красивую рамку. Но в тёмной теме это бессмысленно, ибо на тёмном фоне тёмная рамка не нужна. В тёмной теме и так достаточно контраста.

Мы добавили правило

.dark .box {
    box-shadow: initial;
}

И прописали у тега body (родительский тег для всего контента вообще на сайте) класс dark.

В итоге второе правило более специфично, оно даёт путь из двух компонент. И применяется именно оно, перекрывая предыдущее. То есть в тёмной теме рамки у постов нет.

Каскад CSS

1. Важность

Первая ступень каскада рассматривает тип правила.

Есть четыре уровня типов:

  1. transition (переход). Правила, которые применяются к активному переходу, имеют первостепенную важность.
  2. !important. Если поставить !important в конце правила, оно перейдёт на этот уровень каскада. В идеале вы должны использовать !important только для переопределения inline-стилей или других !important из сторонних библиотек.
  3. animation (анимация). Правила, применяющиеся к активной анимации, повышают уровень в каскаде.
  4. normal. На этом уровне находится основная часть правил.

Как видите, эти типы обеспечивают корректную анимацию элементов. Если оба правила относятся к одному уровню, приоритет определяется на другой ступени каскада.

2. Происхождение

Вторая ступень смотрит, где определено правило.

Таких мест может быть три (расположены в порядке приоритета):

  1. Веб-сайт. Единственный уровень, который вы можете контролировать как веб-разработчик.
  2. Пользователь. Стили, которые пользователь подключает через настройки браузера.
  3. Браузер. У каждого браузера есть свой набор стилей — например элемент <button> всегда использует стиль браузера по умолчанию.
    Так выглядит кнопка в вашем браузере

Примечание Важно! Иерархия для правил с !important здесь работает наоборот: !important-правило браузера выигрывает у !important-правила веб-сайта, тогда как обычные правила сайта превосходят правила браузера.

3. Специфичность

На третьей ступени важна специфичность правила. Значение специфичности определяется исходя из уровней селекторов CSS.
Всего уровней четыре:

  1. inline. Стили, объявленные в HTML-свойстве style, обладают наибольшей специфичностью.
  2. id. Можно использовать идентификатор (синтаксис #id) для определения стиля конкретного элемента.
  3. класс | атрибут | псевдокласс. Определять стиль элемента также позволяют классы (синтаксис .class). Этот уровень включает селекторы HTML-атрибутов, например [checked] или [href="https://wattenberger.com"], и псевдоклассы, такие как :hover и :first-of-type.
  4. тип | псевдоэлемент. Тип тега (синтаксис type) тоже используется для определения стиля элементов. Сюда же входят псевдоэлементы вроде :before и :selection.

Стоит отметить, что здесь имеет значение число «вхождений» в какой-либо уровень.

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

4. Позиция

Последняя ступень каскада смотрит на порядок определения правил.

Всегда побеждает то правило, которое объявлено позже (при условии, что всё остальное в каскаде одинаково).

***

Когда в следующий раз вам захочется написать волшебное слово !important, лучше притормозите, оглянитесь назад и выясните, на каких ступенях каскада находятся конфликтующие стили. А ещё можете почитать спецификацию CSS.

А теперь небольшой тест: как думаете, какое из двух правил победит?


Хинт для программистов: если зарегистрируетесь на соревнования Huawei Honor Cup, бесплатно получите доступ к онлайн-школе для участников. Можно прокачаться по разным навыкам и выиграть призы в самом соревновании.

Перейти к регистрации