Погружаемся в CSS: как использовать :where ()

—

от автора

Функция :where() помогает писать меньше кода, применять стили ко всему списку и снимает головную боль при использовании CSS reset. В статье разберёмся, как это работает, и посмотрим на примеры использования.

Что это за функция CSS :where()

Как пишут на  MDN, :where() — это псевдокласс, который в качестве аргумента принимает список селекторов и применяет заданные стили к любому элементу из этого списка. Полезен, когда надо укоротить длинный список селекторов.

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

Вот что бывает, когда один и тот же стиль применим ко всем тегам  <a> внутри header, main  и  footer.

header a:hover, main a:hover, footer a:hover {   color: green;   text-decoratíon: underline; }

Выше у нас только три элемента. Но когда их больше, код становится трудно читать и понимать. А ещё он визуально становится некрасивым. Вот тут-то и требуется :where().

:where(header, main, footer) a:hover {   color: red;   text-decoratíon: underline; }

Браузер доходит до такого фрагмента кода. Код отправляет его к селекторам header, main, и footer и ко всем якорям в этих селекторах. Когда пользователь наведет курсор на якорь, браузер применит заданный стиль. В этом случае — red и underline. То есть список селекторов можно записать коротко и ясно.

Что можно сделать с :where() 

С помощью :where() можно группироваться элементы разными способами. Можно разместить :where() в начале, середине или в конце селектора. Допустим, у нас есть списки.

/* first list */ header a:hover, main a:hover, footer a:hover {   color: green;   text-decoratíon: underline; } /* second list */ article header > p, article footer > p{   color: gray; } /* third list */ .dark-theme button, .dark-theme a, .dim-theme button, .dim-theme a{   color: purple; }

А вот то же самое, сделанное с :where().

/* first list */ /* at the beginning */ :where(header, main, footer) a:hover {   color: red;   text-decoratíon: underline; } /* second list */ /* in the middle */ article :where(header, footer) > p {   color: gray; } /* third list */ /* at the end */ .dark-theme :where(button, a) {   color: purple; }

В первом списке мы указываем, что red и underline должны применяться к header, main, и footer при наведении курсора. 

Во втором списке указываем, что содержание, заголовок и футер окрашены в серый.

В третьем списке мы указываем, что для button и a задали стили .dark-theme, .dim-theme, и purple.

Упростим ещё.

/* at the end */ .dim-theme :where(button, a) {   color: purple; }

И ещё. 

/* stacked */ :where(.dark-theme, .dim-theme) :where(button, a) {   color: purple; }

Такой подход к сокращению сложного списка селекторов называется наложением.

Специфичность и :where()

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

Специфичность :where() всегда равна нулю. Следовательно, любой элемент, на который нацелена функция, автоматически получает равную нулю специфичность. Поэтому можно легко аннулировать стиль любого элемента, сводя специфичность к нулю. Пример с упорядоченными списками HTML.

<div>   <h2>First list no class</h2>   <ol>     <li>List Item 1</li>     <li>List Item 2</li>   </ol> </div> <div>   <h2>Second list with class</h2>   <ol class="second-list">     <li>List Item 1</li>     <li>List Item 2</li>   </ol> </div> <div>   <h2>Third list with class</h2>   <ol class="third-list">     <li>List Item 1</li>     <li>List Item 2</li>   </ol> </div>

Во фрагменте кода есть три упорядоченных списка с двумя элементами в каждом. У второго и третьего списка есть заданный класс, у первого — нет. Без применения стилей каждый список упорядочен по номерам. 

Добавляем стили. Для этого используем :where(), чтобы выбрать все теги <ol>, к которым применен class.

:where(ol[class]) {   list-style-type: none; }

Ниже видим, что :where() применяется ко второму и третьему списку (с классами), поэтому стиль списков удалён.

Добавляем ещё стили.

:where(ol[class]) {   list-style-type: none; } .second-list {   list-style-type: disc; }

Если применять :where() только ко второму списку, используя наименование класса, то список отобразится с маркерами. А у третьего списка по-прежнему нет стиля. 

Вопрос: разве так и не должно быть, раз новый стиль записан ниже :where()? Нет, и сейчас разберёмся, почему.

Посмотрим, что произойдёт, если переместить добавленный код в верхнюю часть блока кода и передвинуть :where() вниз.

.second-list {   list-style-type: disc; } :where(ol[class]) {   list-style-type: none; }

Стиль всё ещё не изменился.

Запомним, что у :where() нулевая специфичность. Вне зависимости от того, где размещён новый код относительно :where(), специфичность элемента, к которому применяется :where(), равна нулю, а стили аннулированы. Для наглядности давайте добавим стили второго списка в третий список после :where()в коде.

.second-list {   list-style-type: disc; } :where(ol[class]) {   list-style-type: none; } .third-list{   list-style-type: disc; }

Теперь и второй, и третий список отображаются с маркерами, независимо от размещения кода. 

Теперь посмотрим, как :where() будет работать, если один из элементов выбран с помощью недопустимого селектора.

Forgiving и :where() 

Если браузер в CSS не распознает только один селектор в списке, весь список окажется недопустимым. Стиль не будет применяться. Но только если не использовать :where().

Если элемент в :where() содержит недопустимый селектор, никакой стиль к этому элементу применен не будет. Но для остальных элементов стили сработают. Функция :where() пропустит недопустимый селектор. Поэтому :where() называют forgiving-селектором, дословно — «прощающим».

Ниже видим селектор :unsupported — недопустимый для многих браузеров. Но весь код ниже будет успешно распарсен и будет соответствовать селектору :valid, даже в браузерах, которые не поддерживают :unsupported.

:where(:valid, :unsupported) {   ... }

А вот пример кода, который будет проигнорирован в браузерах, которые не поддерживают:unsupported, но при этом поддерживают селектор :valid.

:valid, :unsupported {   ... }

Где можно и нельзя использовать :where()

Инструмент полезный, но со своими ограничениями. В основном ошибаются из-за нулевой специфичности. Если существует элемент или набор элементов, у которых ни в коем случае не должен поменяться стиль, :where() лучше не использовать. Посмотрим, в каких случаях :where() нужна и хорошо работает.

Улучшить CSS reset

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

Например, представьте, что мы захотели оформить все якоря на странице зелёным. А потом решили, что в футере все якоря должны быть серыми. 

Новый стиль (серый цвет) не применяется из-за особенностей CSS reset. У селектора в CSS reset более высокий порядок специфичности, чем у селектора в коде, который применяет стили только для футера. Но если добавить :where() в CSS reset, все элементы в CSS reset автоматически приобретут нулевую специфичность. Позже, когда будем менять стили, не надо будет беспокоиться о конфликтах специфичности.

Удалить стили

Функция :where() помогает удалить или обнулить стили или изменить специфичность элементов. Когда поместим функцию в код, она сработает как reset на минималках.

Минимизировать код

Короткий код легко читать и исправлять. Хороший тон — проверять, можно ли сократить любой код, в котором есть больше двух запятых или больше трёх элементов списка. Эта же стратегия помогает комбинировать два и более селектора: section > header > p > a.


Функция :where() помогает работать с CSS resets, удалять стили в любом месте кода и просто делать код красивым и понятным. Пользуетесь?


ссылка на оригинал статьи https://habr.com/ru/company/netologyru/blog/657651/


Комментарии

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

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