×
На протяжении большей части истории CSS при помощи селекторов можно было нацеливаться на элементы, базируясь на их родителях в дереве DOM. Рассмотрим эту структуру HTML:
<div>
<p>Paragraph 1</p>
<div>
<main>
<div>
<p>Paragraph 2</p>
</div>
<main>
Применить стили ко второму абзацу (Paragraph 2) в CSS очень просто, так как можно привязаться к родительскому узлу <main>.
main p {
color: blue;
}
Это изменит стиль Paragraph 2, но не Paragraph 1, поскольку именно второй параграф содержится внутри элемента <main>.
Однако исторически сложилось так, что стилизация узла <main> в зависимости от наличия тега <p> под ним не была простой.
<main>
Это не надо стилизовать
</main>
<main>
<p>А это — надо</p>
</main>
Если смотреть вверх по дереву DOM, то не было способа применить стили только ко второму элементу <main>, не задев первый (без использования классов или идентификаторов, конечно).
Представляем селектор :has()
По своей сути селектор :has() является реляционным псевдоклассом. Это означает, что он позволяет выбрать элемент на основе его отношений с другими элементами. В частности, он выбирает элемент, если тот содержит другой элемент, соответствующий заданному селектору.
В приведенном выше примере мы можем сделать следующее:
main:has(p) {
color: blue;
}
Это открывает много возможностей для более эффективного оформления веб-страниц с использованием меньшего количества кода.
Пример 1. Выделение статей с помощью изображений
Рассмотрим веб-страницу, на которой отображается список статей, каждая из которых заключена в тег <article>. Если мы хотим выделить статьи, содержащие изображения, селектор :has() предлагает простое решение:
article:has(img) {
border: 2px solid blue;
}
See the Pen
Has Selector in CSS — Example 1 by James Charlesworth (@jcharlesworthuk)
on CodePen.
Это CSS-правило применяет синюю рамку вокруг любого тега <article>, содержащего элемент <img>, визуально отличая статьи с изображениями от статей без них.
Пример 2. Стилизация меню навигации с подменю
Вот еще один пример. В этом примере селектор :has() используется для добавления псевдоэлемента :before() к любому пункту меню, имеющему подменю — то есть к любому элементу <li>, содержащему дочерний элемент с классом .sub-menu.
.main-menu > li:has(.sub-menu):before {
content: «▼»;
margin-left: 5px;
font-size: 0.75em;
}
See the Pen
Has Selector in CSS — Example 2 by James Charlesworth (@jcharlesworthuk)
on CodePen.
От редакции Techrocks: также рекомендуем обратить внимание на статью «Руководство по продвинутым CSS-селекторам».
Поддержка браузеров
По состоянию на март 2024 года селектор :has() поддерживается примерно 92 % браузеров по всему миру, включая все наиболее распространенные современные браузеры, такие как последние версии Chrome, Firefox, Safari и Edge. Для неподдерживаемых браузеров используйте библиотеки обнаружения фич, такие как Modernizr, чтобы применять альтернативные стили.
Также стоит разработать изящный дизайн CSS, чтобы ваши веб-страницы оставались как минимум функциональными и визуально приемлемыми в браузерах, не поддерживающих селектор :has().
:has() готов к использованию уже сегодня
Селектор :has() предлагает новый уровень гибкости и возможностей в CSS, позволяя писать более чистые и эффективные таблицы стилей. Выбирая элементы на основе их содержимого, селектор :has() упрощает многие распространенные задачи стилизации, от выделения статей с изображениями до стилизации отзывчивых макетов.
Поскольку поддержка браузеров продолжает расти, 2024 год — идеальное время, чтобы начать внедрять селектор :has() в свой CSS.
Перевод статьи «How to Use the :has() Selector in CSS».
Запись Как использовать селектор :has() в CSS впервые появилась Techrocks.