Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 23 additions & 26 deletions css/cascade/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,21 @@ tags:

![Большой Каскад в Петергофе](images/1.jpg)

Каскад — одно из важнейших понятий в CSS. Само название **CSS** — Cascading Style Sheets, «каскадные таблицы стилей» явно упоминают это неочевидное определение.
Каскад — одно из важнейших понятий в CSS. Само название **CSS** — Cascading Style Sheets, «каскадные таблицы стилей» явно упоминают это неочевидное определение. Суть его в том, что на одну сущность (элемент и его содержимое) могут «претендовать» несколько разных стилевых правил, и специальный алгоритм выбирает из них единственное, которое в итоге и применится.

<aside>

💡 Каскад — не специфичность!

</aside>

Точнее, в определении _каскада_ принимает участие не только специфичность, но и в первую очередь источник этих правил и область видимости. Также имеет важное значение **порядок в коде** (какие свойства были объявлены «позже», те «важнее»).
Точнее, в определении _каскада_ принимает участие не только специфичность, но и в первую очередь источник этих правил и их важность. Также имеет важное значение **порядок в коде** (какие свойства были объявлены «позже», те «важнее»).

<aside>

💡 Эта статья раскрывает лишь основы CSS-каскада. Новые версии спецификации каскада добавляют в него новые критерии, например [каскадные слои](/css/layer/), контекст инкапсуляции (глубину вложенности теневой DOM веб-компонентов), область видимости для [стилей с правилом @scope](/css/scope/). Даже опытный разработчик всегда может найти в CSS-каскаде что-то новое!

</aside>

## Источники правил

Expand All @@ -45,28 +51,11 @@ tags:
7. Обычные пользовательские стили;
8. Обычные браузерные стили.

Иногда браузеры нарушают этот порядок — порой осознанно (например, могут запретить делать слишком мелкий шрифт в полях ввода, как это делал Google Chrome) или по ошибке (до недавнего времени стили при анимации перекрывали остальные стили только в Firefox).

## Область видимости

Понимание области видимости лучше всего начать с указания стилей в атрибуте тега [`style`](/html/global-attrs/#style) — их область видимости ограничена только тем тегом, в котором они указаны. Т. е. если вы описали `style` тегу [`<li>`](/html/li/), то эти стили применятся только к этому тегу, остальные `<li>` не «увидят» эти свойства:

```html
<ul>
<li>Этот пункт имеет CSS-свойства по умолчанию</li>
<li>И этот тоже</li>
<li style="color: #2E9AFF">Текст в этом (и только в этом) теге будет синим</li>
<li>Снова обычное оформление</li>
</ul>
```

<iframe title="Инлайн стили" src="demos/inline-styles/" height="220"></iframe>

Со свойствами, описанными через _классические_ CSS-селекторы ([классы](/css/class-selector/), [теги](/css/tag-selector/), [id](/css/id-selector/), [атрибуты](/css/attribute-selector/)) иначе — чем точнее мы описываем правило для селектора, тем сильнее мы суживаем область видимости (т. е. как бы точнее прицеливаемся), тем самым увеличивая и приоритетность правила. Но это работает до тех пор, пока CSS-правило не содержит «подлого» `!important`. Именно поэтому их использование считается плохой практикой — они «меняют правила игры». Это правило мгновенно становится приоритетнее, но чем _шире область видимости_ — тем оно важнее 🤯
Иногда браузеры нарушают этот порядок — порой осознанно (например, могут запретить делать слишком мелкий шрифт в полях ввода, как это делал Google Chrome) или по ошибке (до недавнего времени стили при анимации уступали !important-стилям только в Firefox).

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

Самое простое и очевидное понятие в определении каскада. Когда мы описываем стили (инлайном в теге или на селектор в [`<style>`](/html/style/) или файле), каждое правило имеет свой вес. Правила, описанные инлайном перебивают правила на селектор, но не отменяют правила с `!important` (отменяют, если инлайн-правило тоже описано с `!important`).
Когда мы описываем стили (инлайном в теге или на селектор в [`<style>`](/html/style/) или файле), каждое правило имеет свой вес. Со свойствами, описанными через _классические_ CSS-селекторы ([классы](/css/class-selector/), [теги](/css/tag-selector/), [id](/css/id-selector/), [атрибуты](/css/attribute-selector/)) общая логика такая: чем точнее мы описываем правило для селектора (как бы точнее прицеливаемся), т.е. чем _специфичнее_ получилось это правило, тем выше его вес. Правила, описанные инлайном (в атрибуте `style`), перебивают правила на любой селектор, но не отменяют правила с `!important` (если только инлайн-правило само не содержит `!important`).

Установим цвет текста абзаца в красный:

Expand All @@ -83,7 +72,7 @@ p {
</p>
```

Теперь переопределим цвет текста более специфичным инлайн-правилом:
Теперь переопределим цвет текста инлайн-правилом (в CSS-каскаде оно считается более специфичным):

```html
<style>
Expand All @@ -97,7 +86,7 @@ p {
</p>
```

Повысим специфичность, добавив `!important` в правила селектора:
Повысим важность правилу из селектора, добавив ему `!important`:

```html
<style>
Expand All @@ -107,7 +96,7 @@ p {
</style>

<p style="color: blue">
Цвет текста снова стал красным за счёт !important в &lt;style&gt;.
Цвет текста снова стал красным за счёт !important.
</p>
```

Expand All @@ -126,7 +115,9 @@ p {
</p>
```

Инлайн-стили и `!important` — крайние меры влияния на стилизацию, правильнее описывать стили в селекторах в файлах. Но разные правила можно описать так, что они будут претендовать на одну и ту же сущность (тег и его содержимое). В этом случае на применимость правила будет влиять специфичность, т. е. тип (тег, класс, id, атрибуты и псевдоклассы) и их совокупность и комбинации. Самый простой способ разобраться в этом разнообразии — использовать так называемый _калькулятор специфичности_. Можно воспользоваться одним из множества онлайн-сервисов:
Инлайн-стили и `!important` — крайние меры влияния на стилизацию, правильнее описывать стили в селекторах в файлах.

Значение специфичности селектора складывается из специфичностей его составляющих (тегов, классов, псевдоклассов, ID и пр.). Самый простой способ разобраться в этом разнообразии — использовать так называемый _калькулятор специфичности_. Можно воспользоваться одним из множества онлайн-сервисов:

- [Specificity Calculator](https://specificity.keegan.st/)
- [CSS Specificity calculator | Polypane Browser for Developers](https://polypane.app/css-specificity-calculator/)
Expand Down Expand Up @@ -194,12 +185,18 @@ p {

### Отмена значения — `unset`

По своему поведению `unset` чем-то похож на `initial` + `inherit` — если это свойство ненаследуемое от родителя — оно сбросится до начального значения, наследуемое — получит значение родителя.
По своему поведению `unset` чем-то похож на `initial` + `inherit` — если это свойство ненаследуемое от родителя — оно сбросится до начального значения, наследуемое — получит значение родителя. Как если бы свойство _вообще нигде_ не было задано.

### Сброс значения — `revert`

Это менее строгий режим сброса — он отменяет все установленные разработчиком значения для данного свойства до значения, которое считается браузером «значением по умолчанию».

<aside>

💡 В частности, элементы, определенные в браузерных стилях как блочные, останутся блочными.

</aside>

## Подсказки

💡 В CSS есть такое волшебное свойство — [`all`](/css/all/) — это своеобразный шорткат (сокращённый формат записи), который внутри себя содержит все-все CSS-свойства. В сочетании с `initial`, `inherit`, `unset` или `revert` это позволяет повлиять на каскад в одну строчку.
Expand Down
Loading