@scope Это правило, наконец, дает разработчикам уверенность в том, что они смогут писать CSS, который сможет соответствовать современным интерфейсам?
Изучая базовые принципы CSS, вас учат писать модульные, многократно используемые и описательные стили, чтобы обеспечить удобство сопровождения. Но когда разработчики приступают к работе с реальными приложениями, часто кажется невозможным добавить функции пользовательского интерфейса без утечки стилей в непредусмотренных областях.
Эта проблема часто превращается в замкнутый круг; Стили, которые теоретически ограничены одним элементом или категорией, начинают появляться там, где им не место. Это вынуждает разработчика создавать еще более конкретные селекторы для переопределения просочившихся стилей, которые затем случайно переопределяют глобальные стили и так далее.
Строгие соглашения об именах классов, такие как БЭМ, являются теоретическим решением этой проблемы. Метод БЭМ (Блок, Элемент, Модификатор) CSS — это систематический способ именования классов, обеспечивающий возможность повторного использования и структуру файлов CSS. Такие соглашения об именах могут снизить когнитивную нагрузку за счет использования предметного языка для описания элементов и их состояния, а при правильной реализации могут упростить поддержку стилей для более крупных приложений.
Однако в реальном мире не всегда так получается. Приоритеты могут измениться, и реализация станет несовместимой с этими изменениями. Небольшие изменения в структуре HTML могут потребовать нескольких изменений имени класса CSS. В высокоинтерактивных интерфейсных приложениях имена классов, соответствующие шаблону БЭМ, могут стать длинными и громоздкими (например, app-user-overview__status--is-authenticating), а несоблюдение правил именования в полной мере нарушает структуру системы, сводя на нет ее преимущества.
Учитывая эти проблемы, неудивительно, что разработчики обратились к фреймворкам, причем Tailwind является самым популярным фреймворком CSS. Вместо того, чтобы вести безнадежную войну специфичности между стилями, проще пропустить каскад CSS и использовать инструменты, гарантирующие полное разделение.
Разработчики больше полагаются на утилиты
Откуда мы знаем, что некоторые разработчики готовы избегать каскадных стилей? Это появление «современных» интерфейсных инструментов, таких как фреймворки CSS-in-JS, разработанных специально для этой цели. Работа с разными стилями, ограниченными конкретными компонентами, может показаться глотком свежего воздуха. Это избавляет от необходимости давать названия вещам (по-прежнему одна из самых ненавистных и трудоемких задач интерфейса) и позволяет разработчикам работать продуктивно без необходимости полностью понимать или использовать преимущества наследования CSS.
Но пропуск каскада CSS имеет свои проблемы. Например, составление стилей в JavaScript требует сложной настройки сборки, и часто стили неудобно смешиваются с разметкой компонентов или HTML. Вместо тщательно продуманных соглашений об именах мы позволяем инструментам автоматически генерировать для нас селекторы и идентификаторы (например, .jsx-3130221066), требуя от разработчиков использовать другой псевдоязык. (Как будто когнитивная нагрузка понимания всех компонентов вашего useEffectСделать это уже было недостаточно!)
Дальнейшее абстрагирование работы по присвоению имен классам к инструментам означает, что встроенная отладка часто ограничивается конкретными версиями приложений, скомпилированными для разработки, вместо того, чтобы использовать преимущества инструментов разработчика, таких как встроенные функции браузера, поддерживающие живую отладку.
К счастью, современные функции CSS не только делают написание стандартного CSS более гибким, но и дают таким разработчикам, как мы, гораздо больше возможностей для управления каскадом и заставить его работать на нас. Каскадные слои CSS — отличный пример, но есть еще одна особенность, которой на удивление не уделяется много внимания — хотя в последнее время она меняется. базовая совместимость.
CSS @scope по правилам
Я считаю CSS @scope по правилам Чтобы стать потенциальным лекарством от беспокойства, вызванного утечкой стилей, которое мы рассмотрели, это не заставляет нас жертвовать основными веб-преимуществами ради абстракции и дополнительных инструментов сборки.
”
@scopeCSS-код «правило за правилом» позволяет выбирать элементы в определенных поддеревьях DOM, точно нацеливать элементы без написания гиперспецифичных селекторов, которые трудно переопределить, и без слишком жесткой привязки селекторов к структуре DOM.– МДН
Другими словами, мы можем работать с изолированными стилями в конкретных случаях. Не жертвуя наследованием, каскадированием или даже базовым разделением задач. Это давний руководящий принцип фронтенд-разработки.
Кроме того, он имеет отличное покрытие браузера. Фактически, в Firefox 146 добавлена поддержка @scope В декабре он впервые стал совместим с Baseline. Вот простое сравнение кнопок, использующих шаблон БЭМ, и кнопок @scope Правило:
@scope Правила это позволяют точность с меньшей сложностью. Разработчикам больше не нужно создавать границы, используя имена классов, что, в свою очередь, позволяет им писать селекторы на основе собственных элементов HTML, устраняя необходимость в предписывающих шаблонах имен классов CSS. Устранив необходимость управления именами классов, @scope Может уменьшить страх, связанный с CSS в крупных проектах.
основная функция
Для начала добавьте @scope Создайте правило в своем CSS и поместите корневой селектор, который будет иметь область действия стилей:
@scope () {
/* Styles scoped to the */
}
Так, например, если мы хотим расширить область применения стилей
@scope (nav) {
a { /* Link styles within nav scope */ }
a:active { /* Active link styles */ }
a:active::before { /* Active link with pseudo-element for extra styling */ }
@media (max-width: 768px) {
a { /* Responsive adjustments */ }
}
}
Это само по себе не является новаторской особенностью. Однако в область действия можно добавить второй аргумент для создания нижний пределЭффективное определение начальной и конечной точек области действия.
/* Any `a` element inside `ul` will not have the styles applied */
@scope (nav) to (ul) {
a {
font-size: 14px;
}
}
Эта практика называется пончикИ существует ряд подходов, которые можно использовать, включая серию похожих, очень специфических селекторов, тесно связанных со структурой DOM. :not Псевдоселектор или указание конкретного имени класса элементы внутри
Несмотря на эти другие точки зрения, @scope Метод более краток. Что еще более важно, это предотвращает риск поломки стилей в случае изменения или неправильного использования имен классов или изменения структуры HTML. Теперь, когда @scope Базовая версия совместима, обходные пути нам больше не нужны!
Мы можем развить эту идею дальше, добавив несколько окончательных границ, чтобы создать «стиль восьмерки»:
Сравните его с необработанной версией @scope Правила, по которым разработчик должен «сбросить» стили до значений по умолчанию:
main a {
font-size: 14px;
}
main p {
line-height: 16px;
color: darkgrey;
}
main aside a,
main nav a {
font-size: inherit; /* or whatever the default should be */
}
main aside p,
main nav p {
line-height: inherit; /* or whatever the default should be */
color: inherit; /* or a specific color */
}
См. следующий пример. Вы заметили, как легко выбрать одни вложенные селекторы и исключить другие?
увидеть ручку [@scope example [forked]](https://codepen.io/smashingmag/pen/wBWXggN) Блейк Лундквист.
Рассмотрим сценарий, в котором уникальные стили необходимо применить к содержимому, размещенному в веб-компонентах. При размещении контента в веб-компоненте этот контент становится частью теневого DOM, но по-прежнему наследует стили исходного документа. В зависимости от того, в каком веб-компоненте размещен контент, разработчик может захотеть применить разные стили:
Jane Doe
Jane Doe
В этом примере разработчик может захотеть Наличие разных стилей возможно только тогда, когда они представлены в : :
@scope (team-roster) {
user-card {
display: inline-flex;
align-items: center;
gap: 0.5rem;
}
user-card img {
border-radius: 50%;
width: 40px;
height: 40px;
}
}
больше прибыли
Есть дополнительные способы @scope Это может устранить необходимость в управлении классами, не прибегая к утилитам или именам классов, генерируемым JavaScript. Например, @scope открывает возможность более легкого Целевые потомки любого селектораНе только имена классов:
/* Only div elements with a direct child button are included in the root scope */
@scope (div:has(> button)) {
p {
font-size: 14px;
}
}
они и может быть вложеннымСоздание области внутри области:
@scope (main) {
p {
font-size: 16px;
color: black;
}
@scope (section) {
p {
font-size: 14px;
color: blue;
}
@scope (.highlight) {
p {
background-color: yellow;
font-weight: bold;
}
}
}
}
Кроме того, на родительскую область можно легко ссылаться. @scope Правило:
/* Applies to elements inside direct child `section` elements of `main`, but stops at any direct `aside` that is a direct chiled of those sections */
@scope (main > section) to (:scope > aside) {
p {
background-color: lightblue;
color: blue;
}
/* Applies to ul elements that are immediate siblings of root scope */
:scope + ul {
list-style: none;
}
}
@scope Правило at также вводит новый Близость Размеры разрешения спецификации CSS. В традиционном CSS, когда два селектора соответствуют одному и тому же элементу, побеждает селектор с более высокой специфичностью. с @scopeКогда два элемента имеют одинаковую специфичность, побеждает тот, чей корень области действия находится ближе к соответствующему элементу. Это устраняет необходимость переопределять собственные стили путем ручного повышения специфичности элемента, поскольку внутренние компоненты естественным образом заменяют стили внешних элементов.
заключение
CSS-фреймворки, ориентированные на утилиты, такие как Tailwind, хорошо подходят для прототипирования и небольших проектов. Однако при использовании в крупных проектах с участием нескольких разработчиков их преимущества быстро уменьшаются.
С годами фронтенд-разработка становится все более сложной, и CSS не является исключением. Когда @scope Это правило не исправит все, оно может уменьшить потребность в сложных инструментах. При использовании вместо стратегического именования классов или вместе с ним @scope Поддерживаемый CSS может сделать написание кода проще и увлекательнее.
Дальнейшее чтение
(ГГ, ЮК)