Статьи

Руководство PostCSS по улучшению селекторов и медиазапросов

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

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

Мы не будем вдаваться в подробности настройки и установки PostCSS в этой статье. Это уже было описано в « Введение в PostCSS » и « Повышение качества вашего CSS с помощью PostCSS ». Для быстрого ознакомления вы также можете посетить страницу PostCSS на GitHub.

Вложение правил

Давайте начнем с того, что, вероятно, будет самой основной функцией из всех — и, безусловно, знакомо каждому пользователю препроцессора — вложение. Плагин postcss-nesting реализует вложение правил стилей в соответствии с предложением модуля вложения W3C .

Предложение вводит новый селектор вложенности, который ссылается на родительский селектор. В отличие от Less или Sass, согласно спецификации, этот селектор является обязательным и должен быть первым основным селектором в цепочке селекторов, чтобы включить вложение. Любые селекторы, которые не содержат вложенный селектор, будут игнорироваться. Например:

 &

Будет переведено на:

 .article {
  color: #333;

  &.popular {
    background: #DDD;
  }

  & .title {
    font-weight: bold;
  }
}

Обратите внимание, что следующий код недействителен, так как он не использует .article {
color: #333
}
.article.popular {
background: #DDD
}
.article .title {
font-weight: bold
}

 &

Чтобы разрешить вставку родительского селектора в любое место селектора (а не только в начало), в предложении определяется альтернативный синтаксис с использованием nesting at-rule .article {
color: #333;

/* no nested-selector */
.popular {
background: #DDD;
}

/* the nested selector is not the fist selector in the chain */
.latest & {
border: 1px solid red;
}
}
Мы можем исправить @nest

 .latest &

Который будет компилироваться в:

 .article {
  color: #333;

  @nest .latest & {
    border: 1px solid red;
  }
}

Синтаксис .article {
color: #333
}
.latest .article {
border: 1px solid red
}
@nest

Пользовательские селекторы

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

PostCSS имеет плагин postcss-custom-selectors, который реализует эту функцию. Вот простой пример, который определяет селектор для всех элементов заголовка:

 &

Он будет скомпилирован в:

 @custom-selector :--heading h1, h2, h3, h4, h5, h6;

:--heading {
  font-weight: bold;
}

Пользовательские селекторы реализованы в виде псевдоклассов, поэтому выглядит странно h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: bold;
}

Пользовательские селекторы могут эффективно использоваться вместе с базовыми селекторами. Например:

 :--

Собирается в:

 .article :--heading .author {
  color: blue;
}

Вы даже можете объединить несколько пользовательских селекторов в один селектор для достижения более сложных перестановок.

 .article h1 .author,
.article h2 .author,
.article h3 .author,
.article h4 .author,
.article h5 .author,
.article h6 .author {
  color: blue;
}

Приведет к:

 @custom-selector :--links a, a:focus, a:visited, a:hover, a:active;
article :--heading :--links {
  color: #333;
}

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

Новые псевдоклассы

Спецификация Selectors Level 4 представила целую кучу новых псевдоклассов, но из-за динамической природы большинства из них только несколько доступны в виде плагинов PostCSS.

Псевдокласс article h1 a,
article h2 a,
article h3 a,
article h4 a,
article h5 a,
article h6 a,
article h1 a:focus,
article h2 a:focus,
article h3 a:focus,
article h4 a:focus,
article h5 a:focus,
article h6 a:focus,
article h1 a:visited,
article h2 a:visited,
article h3 a:visited,
article h4 a:visited,
article h5 a:visited,
article h6 a:visited,
article h1 a:hover,
article h2 a:hover,
article h3 a:hover,
article h4 a:hover,
article h5 a:hover,
article h6 a:hover,
article h1 a:active,
article h2 a:active,
article h3 a:active,
article h4 a:active,
article h5 a:active,
article h6 a:active {
color: #333;
}

Плагин postcss-selector-match реализует новый псевдокласс :matches()match :matches() Это функциональный класс, который фильтрует только те элементы, которые соответствуют селекторам в аргументе. Если вы передаете несколько селекторов, то элемент должен соответствовать хотя бы одному из них. Короче говоря:

 button:matches(:hover, :focus) {
  color: red;
}

Составляется в:

 button:hover, button:focus {
  color: red;
}

The :not()

Псевдокласс :not() Это реализовано в плагине postcss-selector-not .

 section:not(:first-child, :last-child) {
  background: white;
}

Результаты в:

 section:not(:first-child):not(:last-child) {
  background: white;
}

Плагин postcss-pseudo-class-any-link реализует псевдокласс :any-link Он был введен для устранения путаницы вокруг псевдокласса :link В отличие от последнего, он соответствует всем ссылкам, включая посещенные.

 a:any-link {
  color: blueviolet;
}

Составляется в:

 a:link,a:visited {
  color: blueviolet;
}

Улучшения медиазапросов

В арсенале PostCSS есть пара плагинов, разработанных для облегчения использования медиазапросов. Это postcss-custom-media и postcss-media-minmax .

Custom Media

Написание медиазапросов приводит к той же проблеме, что и обычные селекторы — они часто повторяются в таблицах стилей. Вероятно, даже чаще, чем простые селекторы. К счастью, есть решение, похожее на пользовательские селекторы. Плагин postcss-custom-media реализует спецификацию пользовательских медиа-запросов, которая добавляет возможность сохранять медиа-запросы в переменные.

Синтаксис очень похож на пользовательские селекторы. Вот простой пример:

 @custom-media --medium-viewport (min-width: 768px) and (max-width: 992px);

@media (--medium-viewport) {
  /* your styles here */
}

Составляется в:

 @media (min-width: 768px) and (max-width: 992px) {
  /* your styles here */
}

Конечно, вы можете использовать несколько пользовательских медиа-запросов одновременно:

 @custom-media --landscape (orientation: landscape);
@media (--medium-viewport) and (--landscape) {
  /* your styles here */
}

Приведет к:

 @media (min-width: 768px) and (max-width: 992px) and (orientation: landscape) {
  /* your styles here */
}

Как вы можете видеть, теперь намного проще изменить определение «среднего окна просмотра», а также искать любой связанный код CSS.

Мин. И Макс. Синтаксис

Хотя медиа-запросы — отличная вещь, синтаксис min-max- W3C ответил введением более интуитивного синтаксиса с использованием операторов сравнения. Плагин postcss-media-minmax добавляет поддержку операторов >>=<<= Это также позволяет нам использовать синтаксис значения в середине, то есть min-value < property < max-value

Мы можем упростить предыдущие примеры, используя новый синтаксис, который даст тот же результат.

 @custom-media --medium-viewport (768px <= width <= 992px);

@media (--medium-viewport) {
  /* your styles here */
}

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

Не останавливайтесь здесь

К сожалению, не многие из новых функций CSS могут быть реализованы как плагин PostCSS из-за их динамической природы и зависимости от DOM. Нам нужно будет ждать нативной поддержки для большинства из них. Но есть еще много плагинов для изучения и тестирования в вашем рабочем процессе. Эта статья была посвящена плагинам, связанным с селекторами и медиа-запросами, но мы также надеемся представить вам обзоры других новинок. Если вы любопытны и нетерпеливы, вы можете найти больше их на postcss.parts . Продолжайте изучать!