Настанови щодо поліпшення селекторів і медіа запитів в PostCSS

21

Від автора: з останніми змінами в специфікації CSS з’явилося досить багато нових можливостей. Але на жаль, деякі з них знаходяться у формі чернетки, а інші не підтримуються браузерами. І як зазвичай, перш ніж нові пропозиції будуть розглянуті, прийняті і реалізовані, пройде якийсь час. Однак ми можемо не чекати так довго і спробувати деякі з цих властивостей у PostCSS.

У PostCSS є безліч плагінів, призначених для створення полифилов для самих нових властивостей CSS. Плагінів дуже багато, і розповісти про всі в одній статті буде важко. Тому ми зосередимо увагу на плагінах по додаванню нових можливостей селекторам і медіа запитам. Багато з цих плагінів істотно поліпшать структуру стилів, а інші просто додадуть нові функції. У статті ми не будемо показувати, як налаштовувати і встановлювати PostCSS. На PostCSS і GitHub можна швидко ознайомитися з тематикою.

Вкладення правил

Почнемо з самих основ, того, що знайоме всім працюючим з препроцессорами – вкладення. Плагін postcss-nesting реалізує вкладення по специфікації W3C nesting module proposal.

У специфікації описаний новий селектор вкладеності &, що вказує на батьківський селектор. По специфікації цей селектор, на відміну від Less або Sass, обов’язковий і повинен розташовуватися першим в ланцюзі вкладеності селекторів. Селектори без селектора вкладеності будуть ігноруватися. Наприклад:

.article {
color: #333;
&.popular {
background: #DDD;
}
& .title {
font-weight: bold;
}
}

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

.article {
color: #333
}
.article.popular {
background: #DDD
}
.article .title {
font-weight: bold
}

Зверніть увагу: код нижче неправильний, у ньому не використовується селектор &.

.article {
color: #333;
/* невложенный селектор */
.popular {
background: #DDD;
}
/* селектор вкладеності розташований не першим у ланцюжку селекторів */
.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 розширень представлений спосіб зберігання селекторів в змінних, на які можна посилатися з інших частин стилів. Тобто повторюваний селектор можна оголосити один раз і нормально використовувати його в будь-якому місці.

У 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;
}

Результат:

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;
}

Приклад злегка роздутий, зате він дає чітке уявлення того, на що здатна дана функція.

Нові псевдокласи

У специфікації Selectors Level 4 була представлена ціла купа нових псевдокласів, але з-за динамічності тільки деякі з них були реалізовані у вигляді PostCSS плагінів.

Псевдоклас :matches()

В плагіні postcss-selector-matches реалізована робота нового псевдокласу :matches(). Це функціональний клас, який фільтрує елементи за вказаною аргументу. Якщо аргумент передати кілька селекторів, то елемент співпаде хоча б з одним з них. Якщо коротко:

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

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

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

Псевдоклас :not()

Псевдоклас :not() фільтрує елементи, що не збігаються з заданим аргументом. Його робота реалізована в плагіні postcss-selector-not.

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

Результат:

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

Псевдоклас :any-link

В плагіні postcss-pseudo-class-any-link реалізована робота псевдокласу :any-link. Даний псевдоклас був створений для вирішення проблем з псевдоклассом :link. На відміну від останнього, псевдоклас :any-link використовується для вибору всіх посилань – в тому числі відвіданих.

a:any-link {
color: blueviolet;
}

Переводиться в:

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

Поліпшення медіа запитів

В арсеналі PostCSS є парочка плагінів, що полегшують роботу з медіа запитами — postcss-custom-media та postcss-media-minmax.

Користувальницькі запити медіа

У медіа запитів ті ж проблеми, що і у звичайних селекторів – вони часто повторюються. Може бути, навіть частіше звичайних селекторів. На щастя для нас, є рішення, схоже на користувальницькі селектори. В плагіні postcss-custom-media реалізована специфікація custom media query, в якій описаний спосіб збереження медіа запитів в змінні. Синтаксис сильно нагадує синтаксис користувальницьких селекторів. Приклад:

@custom-media —medium-viewport (min-width: 768px) and (max-width: 992px);
@media (—medium-viewport) {
/* стилі */
}

Компілюється в:

@media (min-width: 768px) and (max-width: 992px) {
/* стилі */
}

Можна також використовувати кілька користувальницьких медіа запитів за раз:

@custom-media —landscape (orientation: landscape);
@media (—medium-viewport) and (—landscape) {
/* стилі */
}

Результат:

@media (min-width: 768px) and (max-width: 992px) and (orientation: landscape) {
/* стилі */
}

Тепер набагато простіше змінити розмір для «середнього розміру екрана», а також шукати інший CSS код.

Синтаксис min і max

Медіа запити це чудово, але ось синтаксис min і max — отримав масу нарікань з боку співтовариства. W3C випустили більш інтуїтивний синтаксис на основі операторів порівняння. Плагін postcss-media-minmax додає підтримку операторів >, >=, < і <=. Плагін також дозволяє використовувати синтаксис «значення посередині», тобто min-value < property < max-value. За допомогою нового синтаксису можна спростити приклади вище і отримати той же результат.

@custom-media —medium-viewport (768px <= width <= 992px);
@media (—medium-viewport) {
/* стилі */
}

Плагін буде працювати і без власних медіа запитів.

Не зупиняйтеся на досягнутому

На жаль, з-за динамічності нових властивостей і їх залежності з DOM більшу частину властивостей не можна реалізувати у вигляді плагінів PostCSS. Доведеться почекати, поки з’явиться рідна підтримка у більшості властивостей. Але все ж у мережі є досить багато плагінів, на яких можна вивчати і тестувати роботу нових властивостей. У цій статті був зроблений наголос на плагіни для селекторів і медіа запитів, але ми хочемо вам показати і інший новий функціонал. Особливо нетерплячі можуть подивитися інші плагіни на postcss.parts. Вивчайте нові можливості!