en
Как использовать нативную вложенность селекторов в CSS (обновлено)

Как использовать нативную вложенность селекторов в CSS (обновлено)

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

На синтаксис CSS Nesting существенно повлиял синтаксис вложенных селекторов препроцессора Sass. Многим фронтендерам сложно отказаться от препроцессоров в пользу нативного CSS именно по причине отсутствия в последнем вложенности. Для того чтобы улучшить DX (developer experience) рабочим комитетом CSS было принято решение о внедрении вложенных селекторов.

Несмотря на сильную похожесть синтаксиса, мелкие отличия всё же имеются.

Синтаксис CSS

Медиавыражения внутри вложенных селекторов

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

Классический вариант:

.teaser__image {
  width: 100%;
}

@media (width < 620px) {
  .teaser__image {
    width: 100px;
  }
}

@media (620px <= width <= 768px) {
  .teaser__image {
    width: 180px;
  }
}

С использованием вложенности селекторов:

.teaser__image {
  width: 100%;

  @media (width < 620px) {
    width: 100px;
  }

  @media (620px <= width <= 768px) {
    width: 180px;
  }
}

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

Синтаксис, использующий вложенность, значительно упрощает читабельность и интуитивную понятность кода. К тому же это нативное браузерное поведение, и нам не нужно будет устанавливать дополнительные препроцессоры типа Sass, Less.

Вложенность селекторов

Это поведение знакомо нам по препроцессорам. В последнюю версию спецификации внесли изменение, которое отменяет обязательное написание амперсанда &.

.teaser__image {
  background: lightgray;

  img {
    display: block;
  }
}

figure {
  margin: 0;

  > figcaption {
    background: lightgray;

    > p {
      font-size: 0.9rem;
    }
  }
}

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

button {
  &:hover {
    background-color: red;
  }

  &:focus {
    background-color: blue;
  }
}

Подробнее с синтаксисом можно ознакомиться в спецификации.

Конкатенация строк

.block {
  color: blue;

  &__element {
    color: red;
  }
}

Конкатенация строк в CSS Nesting, работать не будет. Её отказались имплементировать ввиду слишком сложной эвристики для браузеров.

Директива @nest — всё!

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

Подключаем новый синтаксис прямо сейчас

Пока новый синтаксис не достиг полной поддержки всех браузеров новые возможности спецификации CSS Nesting мы подключим с помощью PostCSS.

Устанавливаем плагин PostCSS:

npm i -D postcss postcss-nesting

Создаём файл postcss.config.js для конфигурации PostCSS.

const postcssNesting = require('postcss-nesting');

module.exports = {
  plugins: [postcssNesting],
};

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

Подробнее о том как подключить PostCSS к Gulp, Eleventy, Nuxt я описывал в этой статье.

Обратите также внимание, что существует плагин postcss-nested, но в данный момент я предпочитаю использовать именно плагин postcss-nesting, который корректно реализует последнюю версию CSSWG спецификации.


Ссылки:

Последнее обновление: