Чтобы добавить каскадные слои в существующий CSS, сначала решите, где должны находиться старые правила. Обычные правила вне слоёв имеют приоритет над всеми именованными слоями, поэтому новые переопределения в слоях будут работать только после перемещения конкурирующих устаревших правил в слой с более низким приоритетом.
Это руководство предназначено для тех, кто редактирует созданную веб-страницу на Mac и проверяет её в настольном браузере. Конкретная задача — поместить существующую таблицу стилей ниже новых стилей компонентов, сохранив понятный путь миграции. В примерах используются локальные файлы, условные названия и простая структура CSS.
Почему новые стили в слоях уступают существующим правилам?
Для конкурирующих обычных объявлений в авторских таблицах стилей CSS вне слоёв имеет приоритет над CSS в любом явно заданном слое. Более специфичный селектор или более поздняя позиция внутри слоя не могут преодолеть эту границу. Спецификация CSS демонстрирует такое поведение на примере правила вне слоя, которое переопределяет более специфичное правило в слое. CSS Cascading and Inheritance Level 5.
Рассмотрим этот фрагмент CSS, предназначенный для элемента с классом tile:
.tile {
background-color: #b8bdc5;
}
@layer components {
.tile {
background-color: #246a73;
}
}
Фон останется серым. Если назвать слой overrides, переместить его блок ниже в файле или повысить специфичность селектора, приоритет обычного правила вне слоя не изменится. Имена слоёв не имеют встроенного значения; их взаимный порядок определяется порядком объявления. MDN: Cascade layers.
В таблице ниже предполагаются конкурирующие объявления таблиц стилей одного авторского источника и контекста, на свойство не влияют встроенные стили, анимации или переходы. Строки перечислены от более низкого приоритета к более высокому.
| Тип объявления | От более низкого к более высокому приоритету |
|---|---|
| Обычное | Сначала объявленные слои → позже объявленные слои → правила вне слоёв |
!important |
Правила вне слоёв → позже объявленные слои → сначала объявленные слои |
Приоритет слоя определяется до специфичности селектора. Внутри выигравшего слоя специфичность по-прежнему имеет значение; при равенстве объявлений решающим может стать порядок в исходном коде. Обратный порядок для важных объявлений означает, что при миграции нужно отдельно учитывать обычные и важные правила. MDN: Cascade layers.
Какую границу миграции выбрать?
Начните с одного элемента и одного свойства, которыми должен управлять новый CSS. Проверьте, какое правило сейчас побеждает, определите его таблицу стилей и решите, можете ли вы изменить этот файл или способ его подключения на странице. Так вы установите минимальную полезную границу миграции.
| Ваша ситуация | Практический следующий шаг | Последствие |
|---|---|---|
| Существующий CSS должен сохранить приоритет | Оставьте его вне слоёв и добавьте слои с низкоприоритетными значениями по умолчанию | Новые слои задают значения, если правила с более высоким приоритетом не конкурируют |
| Вы можете редактировать существующий CSS | Поместите подходящие устаревшие правила в @layer legacy |
Более поздние слои смогут переопределять обычные устаревшие объявления |
| Вы можете изменить точку входа таблиц стилей | Импортируйте существующий файл с помощью layer(legacy) |
Импортированная таблица стилей войдёт в этот слой, и её селекторы не придётся переписывать |
| Вы не можете изменить конкурирующий устаревший CSS или способ его загрузки | Временно оставьте необходимое переопределение вне слоёв | Вам всё равно нужно учитывать специфичность и другие факторы каскада |
Эти варианты соответствуют трём механизмам слоёв, задокументированным в CSS: оператор объявляет имена слоёв, блок назначает правила слою, а слоистый импорт назначает импортированную таблицу стилей слою. Сам по себе оператор не перемещает существующие правила. CSS Cascading and Inheritance Level 5: Declaring Cascade Layers.
Для небольшой таблицы стилей может быть удобно обернуть обычные правила в блок. Для существующего внешнего файла слоистый импорт задаёт чёткую границу. Не помещайте существующие правила @import внутрь блока @layer: импорты должны располагаться на верхнем уровне и имеют ограничения по размещению. MDN: @import.
В рекомендуемом ниже варианте миграции устаревший файл импортируется в именованный слой. Это меняет его приоритет относительно других таблиц стилей, поэтому перед применением такого изменения за пределами тестовой страницы проверьте, какой ещё CSS загружается.
Как создать полноценный локальный пример на Mac?
Создайте папку с тремя обычными текстовыми файлами, перечисленными ниже. Используйте редактор кода и сохраните расширения .html и .css. Для этих файлов не нужны пакеты, скрипты, шрифты или скачанные ресурсы. Их названия — локальные примеры.
Сохраните этот полный документ как sample.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Layer sample</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main id="sample">
<h1>Shape sample</h1>
<p>Tile A</p>
<div class="tile" aria-label="Sample shape"></div>
</main>
</body>
</html>
Документ ссылается только на styles.css. В HTML атрибуты rel="stylesheet" и href связывают внешнюю таблицу стилей со страницей. Действующий стандарт HTML не определяет атрибут layer для элемента link; назначьте ресурс слою через CSS. HTML Standard: The link element.
Сохраните эту полную таблицу стилей как legacy.css. Она представляет существующие правила, селекторы которых остаются без изменений:
body {
margin: 2rem;
font-family: system-ui, sans-serif;
color: #26313a;
background-color: #f4f5f7;
}
#sample .tile {
width: 6rem;
height: 6rem;
background-color: #b8bdc5;
border-radius: 0;
}
Сохраните эту полную входную таблицу стилей как styles.css:
@layer legacy, components;
@import url("legacy.css") layer(legacy);
@layer components {
.tile {
background-color: #246a73;
border-radius: 50%;
}
}
Откройте sample.html в актуальной настольной версии Safari или Firefox. Ожидаемый результат — бирюзовый круг под надписью Tile A. Устаревший слой задаёт размеры, а более поздний слой компонентов — фон и закруглённую форму. Селектор с одним классом побеждает устаревший селектор с идентификатором, поскольку объявления находятся в разных слоях. MDN: @layer.
Входной файл сначала задаёт порядок слоёв, затем размещает импорт перед блоком и после этого добавляет правила компонентов. Это соответствует задокументированному синтаксису и правилам размещения импорта. Оператор объявления слоя может предшествовать импортам; блок слоя — нет. MDN: @import.
Что изменить на существующей странице?
При переходе на эту схему замените прямую ссылку страницы на таблицу стилей новой входной таблицей стилей. Если страница по-прежнему напрямую загружает legacy.css и одновременно импортирует её в слой, прямая загрузка предоставляет объявления вне слоёв, которые могут помешать миграции.
На примере можно предсказать сбой: добавьте отдельную прямую ссылку на таблицу стилей legacy.css, и её обычные объявления могут вернуть серый квадрат. Если убрать эту прямую загрузку, устаревшие правила останутся в предназначенном для них слое. Это следует из правила спецификации: при обычном приоритете правила вне слоёв располагаются после явных слоёв. CSS Cascading and Inheritance Module Level 5: Layer Ordering.
В этом примере держите все три файла вместе. При адаптации подхода сохраните условия подключения ресурсов, например ограничения по медиа, и убедитесь, что все указанные таблицы стилей загружены, прежде чем диагностировать конфликт каскада.
Как проверить миграцию в Firefox на macOS?
Откройте панель разработчика Firefox сочетанием Command–Option–I и выберите Inspector. Найдите фигуру примера в дереве документа, затем откройте представление Rules. В документации Mozilla описаны сочетание клавиш для панели на Mac и средства Inspector для просмотра CSS. All keyboard shortcuts, Examine and edit CSS.
Проверяйте свойства примера по одному:
- Найдите
background-color. Объявление компонента должно победить устаревшее серое значение. - Найдите
border-radius. Значение компонента должно придать фигуре форму круга. - Проверьте
widthиheight. Их значения должны по-прежнему поступать из устаревшего файла. - Временно отключите объявление фона компонента. Должен появиться устаревший серый цвет, а фигура останется закруглённой.
Firefox зачёркивает переопределённые объявления и предоставляет флажки для их временного отключения. Он также показывает ссылки на исходные файлы с правилами. Используйте эти средства, чтобы найти конкурирующее объявление, а не считать любую неожиданную картинку проблемой селектора. Mozilla: Examine and edit CSS.
Для настоящей страницы повторите эту проверку для изменённых состояний: более узких окон, соответствующих медиаусловий и вариантов компонента. Сохраняйте постоянные изменения в исходных файлах и перезагружайте страницу; временные изменения в Inspector удобны для диагностики.
Что может неожиданно измениться при миграции?
Важные объявления меняют предполагаемый порядок на обратный
При @layer legacy, components важное объявление в legacy побеждает конкурирующее важное объявление в components. Поэтому перенос важных устаревших правил в ранний слой может затруднить их переопределение. Все важные объявления в слоистых таблицах стилей также имеют приоритет над конкурирующими важными объявлениями вне слоёв в том же авторском источнике и контексте. MDN: @layer.
Перед переносом файла найдите в нём !important и проверьте каждый относящийся к делу конфликт. Если вы контролируете оба объявления, выясните, нужно ли по-прежнему использовать важность после введения слоёв. Не добавляйте важность ко всем новым правилам компонентов: это меняет используемую систему приоритетов.
Встроенным стилям нужно уделить отдельное внимание. Обычные встроенные стили имеют приоритет над обычными правилами авторских таблиц стилей, а важные встроенные стили — над другими важными авторскими объявлениями. Перемещение таблицы стилей в слой не затрагивает атрибут style элемента. MDN: Introduction to the CSS cascade.
Позднее объявление не может изменить порядок существующих слоёв
Порядок слоёв определяется их первым объявлением. Повторное открытие именованного слоя добавляет правила, но не перемещает его. Задайте желаемый порядок до того, как страница впервые создаст эти слои, в том числе через импортированные таблицы стилей. CSS Cascading and Inheritance Module Level 5.
Для постепенной миграции задайте короткий и явный исходный порядок. Переместите согласованную группу правил, проверьте, какие из них побеждают, а затем продолжайте. Перенос одного правила с сохранением конкурирующей копии вне слоя обычно оставляет в силе именно ту границу приоритета, которую вы хотели устранить.
Какие ограничения поддержки браузеров важны на Mac?
MDN отмечает, что @layer широко поддерживается браузерами с марта 2022 года. WebKit указывает, что Safari поддерживает каскадные слои начиная с версии 15.4. Эти даты описывают доступность функции, но не гарантируют, что на каждом Mac установлен совместимый браузер. Проверьте версии, которые действительно должны поддерживать вашу страницу. MDN: @layer, WebKit: New WebKit Features in Safari 15.4.
Браузер, который не распознаёт блок слоя, не применяет содержащиеся в нём стили как обычные правила вне слоёв. Согласно правилам разбора CSS неподдерживаемый синтаксис отбрасывается. Поэтому помещение всего необходимого CSS в слои не является запасным вариантом для старых браузеров. MDN: CSS error handling.
Если старые браузеры по-прежнему нужно поддерживать, оставьте для них отдельную таблицу стилей с правилами вне слоёв и разрешайте конфликты с помощью селекторов и порядка в исходном коде. В браузерах с поддержкой слоёв не загружайте одновременно слоистую версию и её копию вне слоёв: это изменит только что настроенный вами каскад.
Начните с минимальной миграции, которая даёт новому компоненту контроль над нужными свойствами. Задайте порядок слоёв, назначьте конкурирующие устаревшие правила слою, удалите дублирующую загрузку вне слоёв и проверьте, какие правила побеждают. Такая последовательность позволяет увидеть каждое изменение приоритета до переноса остального CSS.
Источники
- CSS Cascading and Inheritance Level 5 — W3C.
- CSS Cascading and Inheritance Module Level 5 — CSS Working Group.
- HTML Standard — WHATWG.
@layerCSS at-rule — MDN Web Docs.@importCSS at-rule — MDN Web Docs.- Cascade layers — MDN Web Docs.
- Introduction to the CSS cascade — MDN Web Docs.
- CSS error handling — MDN Web Docs.
- All keyboard shortcuts — Mozilla.
- Examine and edit CSS — Mozilla.
- New WebKit Features in Safari 15.4 — WebKit.