Источник: WebForMyself.com
CSS селекторы позволяют выбирать элементы по типу, атрибутам и положению внутри HTML-документа. В этом уроке разберем три новые опции — :is(), :where() и :has().
Селекторы в стилях применяются повсеместно. Пример ниже находит все параграфы и меняет жирность шрифта на bold:
Для поиска DOM узлов селекторы можно использовать и в JavaScript:
- document.querySelector() возвращает первый найденный HTML элемент
- document.querySelectorAll() возвращает все найденные HTML элементы в структуре похожей на массив NodeList
Псевдоклассы находят HTML элементы по их текущему состоянию. Наверное, самый известный псевдокласс — :hover. Он применяет стили к элементу, когда курсор наводится на него. Его используют для подсветки кликабельных ссылок и кнопок. Есть и другие популярные опции:
- :visited: находит посещенные ссылки
- :target: находит элементы, помеченные ссылкой
- :first-child: находит первый дочерний элемент
- :nth-child: выбирает заданный дочерний элемент
- :empty: находит элемент без контента или без дочерних элементов
- :checked: находит включенные чекбоксы и радиокнопки
- :blank: стилизует пустые поля ввода
- :enabled: находит активные input поля
- :disabled: находит неактивные input поля
- :required: находит input поля обязательные для заполнения
- :valid: находит input поля с валидным введенным значением
- :invalid: находит input поля с невалидным введенным значением
- :playing: находит элементы, проигрывающие аудио или видео
CSS псевдокласс :is
Обратите внимание: в ранних версиях селектор писался по-другому — :matches() и :any(), но позже стандартом стал :is().
Очень часто нужно применять одинаковые стили ко множеству элементов. Например, текст внутри <p> должен быть черный, но внутри <article>, <section> или <aside> текст будет серый:
Это простой пример, однако более сложные страницы усложнят и селекторы. Синтаксическая ошибка в одном селекторе поломает стили для всех элементов. CSS препроцессоры типа Sass разрешают использовать вложенность (что также появится в нативном CSS):
Этот CSS идентичен коду выше. Однако такой код писать легче, и он снижает вероятность ошибок. Но есть нюансы:
- Пока эта функция не появилась в нативном CSS, придется использовать CSS билд инструменты. Можно использовать Sass, но это может усложнить работу в некоторых командах разработки.
- Вложенность может привести к другим проблемам. Очень легко скатиться в глубокую вложенность селекторов, которую неудобно читать, а после преобразования в обычные стили такой код превращается в очень длинные строки.
:is() дает нам нативное CSS решение с поддержкой во всех современных браузерах (без IE):
Один селектор может содержать любое количество псевдоклассов :is(). Например, сложный селектор ниже применяет зеленый текст ко всем <h1>, <h2> и <p> элементам, которые расположены внутри <section> с классом .primary или .secondary. А также эти элементы должны быть не первым дочерним элементом <article>:
Аналогичный код без :is() требует 6 CSS селекторов:
Обратите внимание, :is() не может использоваться с псевдоэлементами ::before и ::after. Код ниже упадет с ошибкой:
CSS псевдокласс :where
Синтаксис :where() аналогичен :is() и также поддерживается во всех современных браузерах (без IE). Очень часто результат его работы будет таким же, как у предыдущего псевдокласса. Например:
Разница в специфичности. Специфичность – алгоритм, определяющий приоритет перезаписи CSS селекторов. В примере ниже «article p» более специфичен чем просто «p». Поэтому все параграфы внутри article будут серыми:
Для :is() специфичность равна самому специфичному селектору внутри. Для :where() специфичность равно нулю. Разберем CSS код ниже:
Применим этот код к HTML:
Текст будет красным, как показано в демо.
:is() имеет одинаковую специфичность как и article p, но в коде псевдокласс расположен ниже, поэтому текст будет красным. Чтобы применить синий цвет, нужно удалить article p и :is(), ведь :where() наименее специфичный.
Большая часть людей будет использовать :is(). Однако нулевая специфичность :where() может помочь при сбросе стилей. Тем самым при отсутствии других стилей будут применяться базовые.
Пример CSS сброса ниже применяет top margin в 1em к заголовкам h2 за исключением ситуаций, когда заголовки являются первым дочерними элементами от article:
Если ниже попробовать применить свое значение для top margin у h2, у нас не получится, так как article :first-child имеет специфичность выше:
Это можно исправить с помощью более специфичного селектора, но это раздувает код и не совсем очевидно для других разработчиков. Вы просто забудете, зачем добавляли такой стиль:
Также проблему решит !important для всех необходимых стилей, но не делайте так! Дальнейшее написание стилей и разработка станут только сложнее:
Лучше воспользоваться нулевой специфичностью :where() при сбросе:
Теперь можно переписывать любые стили из сброса, не обращая внимания на их специфичность. Больше не нужно писать !important:
CSS псевдокласс :has
Синтаксис :has() похож на :is() и :where(), но этот псевдокласс находит элемент, который содержит набор других элементов. Например, ниже стили, применяющие синюю рамку в 2 пикселя ко всем <a>, внутри которых есть один или более <img> или <section>:
Это самая классная доработка CSS за десятилетия! Разработчики, наконец, могут находить родительские элементы!
Неуловимый «родительский селектор» был одной из самых желанных фич в CSS, но он поставил перед вендорами браузеров вопрос производительности. Поэтому он долго откладывался. Проще говоря:
- Браузеры применяют CSS стили к элементу, когда он отрисован на странице. При добавлении дочерних элементов весь родительский блок должен быть перерисован.
- Добавление, удаление или изменение элементов в JS затрагивает стили всей страницы вплоть до закрывающего body.
Предполагается, что вендоры решили проблемы производительности, и :has() позволяет делать то, для чего раньше нужно было использовать JS. Например, можно указать стили внешнего тега формы fieldset и кнопки отправки, когда любое из обязательных полей заполнено неправильно:
Этот пример добавляет индикатор в подменю ссылок, которое содержит список дочерних элементов меню:
Возможно, вы хотели бы добавить стили для дебага. Например, подсветить все элементы figure без вложенного img:
Пока вы не открыли свой CSS в редакторе, добавлю, что :has() это новый псевдокласс и его поддержка хуже чем :is() и :where(). Он работает в Safari 15.4+ и Chrome 101+ под экспериментальным флагом. В 2023 ожидается широкая поддержка.
Заключение
Псевдоклассы :is() и :where() урощают синтаксис CSS. Они позволяют избавиться от лишней вложенности и использования CSS препроцессоров (хотя эти инструменты дают свои преимущества такие как части, циклы и минификация).
:has() – более революционный селектор. Поиск родительского элемента быстро станет популярен, и мы забудем о темных временах! Мы опубликуем полный урок по :has(), когда он станет доступен во всех современных браузерах.
Источник: www.sitepoint.com
#css #css3