Что такое вложенность CSS?

0 Акции
0
0
0
0

Введение

Если вы фронтенд-разработчик, работавший с препроцессором CSS, вы, вероятно, сталкивались или использовали функцию вложенности. Это популярная функция, и для меня она стала одной из тех, что побудила меня использовать препроцессор CSS.

В этом году поддержка вложенности CSS появилась во всех основных браузерах: Chrome, Firefox и Safari. Это ключевая функция CSS, упрощающая написание CSS-кода. В этой статье я расскажу о том, что я узнал о вложенности CSS, и поделюсь своими выводами, а также примерами использования.

Никаких предварительных условий нет, кроме вашего энтузиазма и сосредоточенности.

Вложенность в CSS — долгожданная функция для многих разработчиков. Раньше мы полагались на препроцессоры CSS, такие как Sass или Less. Позвольте мне кратко рассказать о них:

Рассмотрим следующий пример. У нас есть иконка, которая находится в селекторе .nav__item.

.nav__item {
.icon {
display: flex;
padding: 1rem;
}
}

Приведённый выше код является допустимым кодом Sass. После компиляции в браузере он будет выглядеть следующим образом:

.nav__item .icon {
display: flex;
padding: 1rem;
}

При использовании встроенной функции вложенности CSS тот же самый CSS будет работать как есть. На рисунке показано сравнение встроенной функции вложенности CSS и инструментов разработчика браузера.

Обратите внимание, как браузер отображает CSS почти так же, как он отображается в CSS.

Если бы этот CSS-код был скомпилирован в Sass, браузер отобразил бы его следующим образом:

Преимущества вложенности CSS

На мой взгляд, существуют веские причины, по которым вложенные CSS-стили полезны:

  • CSS легче читать.
  • Группировка стилей
  • Ограничение определенных стилей
  • Стилизация HTML-элементов, не имеющих классов или идентификаторов.

Правила вложенности CSS

Чтобы познакомить вас с вложенностью в CSS, я постараюсь привести наглядные примеры различных проблем в CSS и показать, как вложенность может помочь их решить.

Прежде всего, вам нужно узнать о символе амперсанда (&). Существует ряд ситуаций, когда этот символ необходим.

Вложенность элемента без класса или идентификатора

В этом примере элемент <a> Оформление осуществляется с помощью `.nav__item`. Использование тега `&lt;head&gt;` необязательно для корректной работы CSS.

.nav__item {
  & a {
    display: block;
    padding: 1.5rem 1rem;
  }
}

/* Same as: */
.nav__item a {
}

Вы также можете отказаться от проставления галочки:

.nav__item {
a {
display: block;
padding: 1.5rem 1rem;
}
}
/* Same as: */
.nav__item a {
}

Обратите внимание, что это недавнее обновление, и оно называется «Расслабленная вложенность CSS». Оно работает в последних версиях Chrome Canary и Safari Technology Preview. Ознакомьтесь с этой статьей об «Расслабленной вложенности» от Адама Аргила.

Вложенность элемента с классом

Рассмотрим тот же пример, что и раньше, но предположим, что элемент <a> В нём есть HTML-класс.

.nav__item {
.link {
display: block;
padding: 1.5rem 1rem;
}
}
/* Same as: */
.nav__item .link {
}

Здесь нет необходимости использовать символ. Имя класса подойдет идеально.

Вложенные CSS-комбинаторы

Одним из преимуществ нативной вложенности CSS является использование комбинаторов. Давайте рассмотрим несколько примеров.

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

В стандартной CSS-вложенности мы можем использовать символ амперсанда, чтобы имитировать его. Обратите внимание, что я повторил его дважды.

.nav__item {
& + & {
border-left: 2px solid;
}
}

Волшебство происходит во второй итерации амперсанда. Здесь браузер понимает, что я хочу использовать селектор соседнего элемента. Позвольте мне показать вам рисунок, демонстрирующий это:

Еще один пример вложенности — это комбинатор дочерних элементов. Он может выбирать непосредственного потомка элемента.

.nav__item {
> a {
padding: 1rem;
}
}

Символ амперсанда

.nav__item {
& a {
color: blue;
}
}

Это было необходимо в первоначальной спецификации вложенности CSS. В Safari TP 179+ и Chrome Canary 120 амперсанд больше не требуется для вложенных элементов.

В результате работает следующее:

.nav__item {
a {
color: blue;
}
}

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

Вложенность с примером: Active, Focus, Hover

:active, :focus и :hover — это псевдоклассы CSS, которые активируются действиями пользователя.

С помощью вложенности CSS мы можем вкладывать их все одновременно, чтобы избежать дублирования кода. Возьмем в качестве примера :hover:

button {
&:hover {
background-color: var(--bg-color);
}
&:focus {
outline: solid 2px;
}
}

Разница при использовании препроцессора для вложенности заключается в том, что браузер отображает её следующим образом:

button:hover {
background-color: var(--bg-color);
}
button:focus {
outline: solid 2px;
}

Давайте посмотрим, как вложенность CSS отображается в Chrome, Safari и Firefox.

У меня есть несколько соображений по поводу использования инструментов разработчика для вложенных CSS-стилей, и я рассмотрю их позже в статье.

Пример вложенной структуры: публикация контента

Один из первых примеров тестирования вложенных CSS-стилей — это оформление основного содержимого публикации. Представьте себе статью с заголовками, текстом, изображениями, цитатами и многим другим.

Заголовки

Мы обычно оформляем заголовки следующим образом:

.post-content h1,
.post-content h2,
.post-content h3,
.post-content h4 {
/* styles here */
}

С помощью вложенных CSS-стилей это проще:

.post-content {
h1,
h2,
h3,
h4 {
color: var(--heading-color);
font-weight: var(--heading-font-bold);
margin-bottom: var(--size-2);
}
}

То же самое можно сделать и с помощью селектора :is().

.post-content {
:is(h1, h2, h3, h4) {
color: var(--heading-color);
font-weight: var(--heading-font-bold);
margin-bottom: var(--size-2);
}
}

Элемент абзаца

Распространенный пример — оформление ссылки, находящейся внутри абзаца. В таком случае вложенность CSS-стилей работает отлично.

.post-content {
& p {
color: var(--color-black);
& a {
font-weight: bold;
text-decoration: underline;
}
}
}

Для отображения ссылки также может потребоваться эффект наведения курсора или фокусировки.

.post-content {
& p {
color: var(--color-black);
& a {
font-weight: bold;
text-decoration: underline;
&:hover {
/* hover styles */
}
}
}
}

Мы также можем вкладывать медиа-запросы друг в друга.

.post-content {
& p {
/* base styles */
@media (min-width: 400px) {
/* do something */
}
}
}

В некоторых случаях CMS может быть элементом <p> Оберните его в другой элемент, и в целях стиля его следует использовать только для прямых элементов. <p> Создайте стиль.

.post-content {
/* Select the direct <p> elements */
> p {
/* base styles */
}
}

Блочная цитата

В этом примере цитата получает собственный стиль и элемент <p> Внутри цитаты выберите параметр, чтобы сбросить нижнее поле до нуля.

.post-content {
& blockquote {
/* custom quote styling */
& p {
margin-bottom: 0;
}
}
}

Форма столба

Форма для отправки сообщения содержит изображение и

Отображение описания изображения необязательно.

В моем примере, если

У объекта есть заголовок, и мне нужно изменить его стиль. Это можно сделать с помощью CSS-стиля `:has()`.

.post-content {
& figure {
& img {
/* the figure's image styles */
}
/* changes to the <figure> container, if it has a figcaption element */
&:has(figcaption) {
display: flex;
align-items: start;
}
& figcaption {
/* caption styling */
}
}
}

Список сообщений

Мне нужно добавить рамку ко всем элементам списка, кроме последнего. Для этого я использовал селектор :not().

.post-content {
li {
&:not(:last-child) {
border-bottom: 1px solid;
}
}
}

Чтобы использовать `:not()`, необходимо добавить перед ним амперсанд.

Настраиваемое расстояние для заголовков

Следующее расстояние должно быть <h3> и <h4> Я уменьшу количество символов, если за одним из них последует фрагмент кода.

.post-content {
& h3 + [class*="language-"],
& h4 + [class*="language-"] {
margin-top: 0.5rem;
}
}

Как вы убедились на этом практическом примере, использование вложенности CSS очень просто, особенно если вы знакомы с препроцессорами CSS.

Вложенность на примере: компонент Card

Я покажу простой компонент карточки, который использует вложенность CSS для достижения желаемых стилей.

Предположим, что существует элемент `.card` со стилями по умолчанию или базовыми стилями. Я продемонстрирую использование вложенных CSS-стилей.

.card {
/* default card styles */
}

ЗАПРОСЫ ПО КОНТЕЙНЕРАМ ДЛЯ ГНЕЗДАНИИ

Если ширина контейнера превышает 400 пикселей, я хочу, чтобы карточка трансформировалась в гибкий контейнер.

.card {
/* default card styles */
/* if the container width is 400px or bigger */
@container card (min-width: 400px) {
display: flex;
}
}

Оформление элемента абзаца

Я хочу использовать элемент абзаца следующим образом: <h3> Таким образом, я могу задать поля и отступы для элемента. <p> Добавлю. Если этого не будет, то и в пользовательском интерфейсе не будет дополнительного пространства.

.card__content {
& h3 + p {
border-top: 1px solid #000;
padding-top: 0.5rem;
margin-top: 0.5rem;
}
}

Если ширина контейнера составляет 400 пикселей или более, элемент .card__content также должен быть преобразован в гибкий контейнер.

.card__content {
& h3 + p {
border-top: 1px solid #000;
padding-top: 0.5rem;
margin-top: 0.5rem;
}
@container card (min-width: 400px) {
display: flex;
flex-direction: column;
justify-content: center;
}
}

Вложенность на примере: поле ввода формы

Распространенный случай — оформление заполнителя поля ввода. Проблема в том, что у каждого производителя браузеров свой префикс (ой, на дворе 2023 год).

Поскольку для префиксных стилей требуется двоеточие, необходимо использовать символ &, иначе стили не будут работать.

input {
--placeholder-color: #969696;
/* other styles */
&::-webkit-input-placeholder {
color: var(--placeholder-color);
}
&::-moz-placeholder {
color: var(--placeholder-color);
opacity: 1;
}
&:-moz-placeholder {
color: var(--placeholder-color);
}
}

Возможно, вас интересует, в чем разница между использованием вложенных CSS-стилей и написанием префиксного стиля напрямую без них.

/********** Option 1: native nesting **********/
input {
&::-webkit-input-placeholder {
color: var(--placeholder-color);
}
}
/********** Option 2: without nesting **********/
input::-webkit-input-placeholder {
color: var(--placeholder-color);
}

Между ними нет никакой разницы. Оба обладают одинаковыми свойствами (0, 1, 1).

Вложенность с примером: стилизация элемента через его родительский элемент.

Мы можем использовать вложенность CSS для изменения стилей дочернего элемента в зависимости от его местоположения. Например, если элемент `.button` находится внутри родительского элемента `.box`, он должен занимать всю ширину.

<div class="box">
<h2>Get access to all features</h2>
<p>Create an account now and get access to all exclusive features.</p>
<a href="/offer" class="button">Create an account</a>
</div>
.button {
.box & {
width: 100%;
}
}
/* equivalent to */
.box .button {
}

Ошибки, которые я обнаружил при изучении вложенности CSS.

Использование беззнакового глобального селектора

Допустим, у нас есть карточка, и мы хотим выделить все элементы внутри неё. С помощью CSS Native Nesting это должно сработать:

.card {
* {
/* styles here */
}
}

Я заметил, что это не работает в Chrome Stable, но прекрасно функционирует в Chrome Canary 121, Safari 17.1 и Firefox 119.

Решение состоит в добавлении знака препинания.

.card {
& * {
/* styles here */
}
}

Использование беззнаковых атрибутов данных

В данном случае выбор атрибута данных без галочки не дает ожидаемого результата.

.card {
[data-type="featured"] {
/* styles here */
}
}

Я заметил, что это не работает в Chrome Stable, но прекрасно функционирует в Chrome Canary 121, Safari 17.1 и Firefox 119.

Чтобы это исправить, нужно добавить запятую:

.card {
&[data-type="featured"] {
/* styles here */
}
}

Обе эти ошибки были исправлены в версии Chrome Canary, обеспечивающей более свободную вложенность CSS.

Определение поддержки вложенности CSS

Параметр `@supports` можно использовать для проверки поддержки вложенности CSS-стилей. В нашем случае мы хотим проверить, распознает ли браузер амперсанд.

@supports selector(&) {
.post-content {
& h2 {
/* styles here. */
}
}
}

Другие варианты определения поддержки можно посмотреть в этом примере на Codepen от Bramus.

Сегодня я воспользуюсь плагином PostCSS nesting, который компилирует вложенный CSS в обычный CSS. Я удалю этот плагин, когда его использование станет безопасным.

Инструменты разработчика для UX-вложенности CSS

Мне не очень нравится текущий пользовательский интерфейс для вложенных CSS-кодов в инструментах разработчика браузера.

Я работал над отдельной статьей, в которой рассмотрел несколько предложений о том, как бы я хотел видеть вложенность CSS в инструментах разработчика.

Результат

Вложенность CSS — это важная функция, улучшающая способ написания CSS-кода. В настоящее время использование вложенности возможно, но следует быть осторожным с аудиторией, поскольку поддержка этого функционала пока относительно новая.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *


Вам также может понравиться

Создавайте и развертывайте приложения на платформе приложений DigitalOcean с использованием собственного домена.

Введение Как разработчики, мы часто создаем проекты вместе, будь то для развлечения или для обучения...
Настройка выделенных серверов для популярных игр Minecraft ARK Survival

Настройка выделенных серверов для популярных игр

Введение Мир онлайн-игр расширяется с каждым днем, и геймеры ищут более плавный игровой процесс, больше настроек и полный контроль...

Обмен сообщениями «точка-точка» с Amazon SQS

Введение. Шаблон обмена сообщениями «точка-точка» — это широко используемая модель коммуникации в современных веб-архитектуре и облачных архитектурах…