Содержание
Недавно появившийся селектор :has() позволяет применять стили к родителям и другим предкам, и в этой статье мы расскажем вам, как использовать его при разработке веб-приложений.
(self.Astro=self.Astro||{}).load=a=>{(async()=>await(await a())())()},window.dispatchEvent(new Event(“astro:load”));
В мире CSS селекторы - это рабочая лошадка, обеспечивающая красивые и отзывчивые дизайны, которые мы видим в Интернете. Они позволяют разработчикам выбирать и стилизовать HTML-элементы на основе их свойств, положения и взаимосвязей.
Более современный CSS-селектор/псевдокласс, известный как :has, позволяет выбрать каждый элемент, у которого есть дочерние элементы, соответствующие селектору, который вы предоставляете функции :has(). Это важное решение в CSS, не ограничивающееся простым селектором ”родитель”.
Используя селектор :has(), вы можете применять стили к родительскому или предковому HTML-элементу. Это позволяет расширить область действия селектора, включив в нее одного или нескольких братьев и сестер или детей.
В этой статье мы рассмотрим селекторы CSS :has и несколько примеров их использования в вашем коде.
Когда использовать селектор :has
Селектор :has() - это псевдокласс CSS, который позволяет выбрать элемент, если он содержит определенные дочерние элементы. Это мощный инструмент CSS, который можно использовать для следующих целей:
- Стилизация родителя дочернего элемента: Вы можете использовать селектор
:has()для стилизации элемента<div>, если он содержит элемент “. - Условное добавление или удаление стилей: Вы можете использовать селектор
:has()для добавления границы к элементу<div>, если он содержит определенное количество дочерних элементов. - Выбор элементов на основе их содержимого: Вы можете использовать селектор
:has()для выбора всех элементов<div>, которые содержат дочерний элемент с классом"important".
Селектор :has() можно использовать с любым допустимым CSS-селектором, включая другие псевдоклассы. Это делает его очень универсальным инструментом, который можно использовать различными способами.
Вот небольшой фрагмент того, как можно использовать селектор :has():
/* Выбираем все элементы <div>, содержащие элемент . */
div:has(p) {
background-color: blue;
}
/* Выберите все элементы <div>, которые содержат дочерний элемент с классом "important". */
div:has(.important) {
border: 1px solid black;
}
/* Выберите все элементы <div>, которые содержат не менее двух дочерних элементов. */
div:has(> * + *) {
padding: 10px;
}
В приведенном выше коде показаны практические примеры использования селектора :has. Но прежде чем мы углубимся в использование селектора :has, давайте разберемся, почему этот селектор важен.
Настройка проекта
Чтобы начать этот проект, вы можете клонировать стартовый код из этого GitHub repo. В репо также находится готовый проект, но для того, чтобы следовать этому руководству, вам нужно использовать стартовый код.

Примечание: Проект представляет собой простое демо для блога, чтобы показать, как обычно используется псевдокласс :has.
Прямое и обратное выделение
Раньше разработчики могли выбирать только вперед, но с селектором :has теперь можно выбирать и назад.
Сейчас мы собираемся выбрать родителя элемента. В прошлом это обычно делалось следующим образом:
article + article {
background-color: pink;
}
Здесь мы выбрали article и еще одну article с помощью селектора adjacent sibling, а затем изменили background-color на розовый. Вот результат, представленный ниже:

Как вы можете заметить, цвет второй и третьей статьи изменился. Это связано с тем, что они находятся рядом друг с другом. Таким образом, он выбирается вперед, а не назад. Теперь давайте сделаем это в обратном порядке с помощью селектора :has.
article:has(+ article) {
background-color: coral;
}
В приведенном выше коде мы просто говорим, что если у статьи есть соседняя статья, выберите первые две статьи.

Обратите внимание, что на этот раз выбраны первая и вторая статьи.
Выборы на основе дочерних элементов
С помощью :has мы можем выбирать не только родителя, но и дочерние элементы.
article:has(span) .bold {
background-color: lightyellow;
}
article:has(span) .italic {
text-decoration: underline;
}
В файле index.html мы использовали span, чтобы применить класс жирного и курсивного начертания к статьям 2 и 3. В нашем CSS-файле мы выбрали span, используя синтаксис article:has(span). Вот результат, представленный ниже:

Здесь вы можете увидеть изменения, примененные к жирному и курсивному начертанию во второй и третьей статьях. Мы выбрали не только статьи, но и то, к чему был применен класс span.
Использование :has с выбором :not
В этом разделе мы рассмотрим, как использовать псевдокласс :has с :not.
article:not(:has(span)) {
background-color: yellowgreen;
}
Ниже приведен результат:

Изменяется только та статья, внутри которой нет класса span.
Селектор :has также поддерживает логические условия 0R.
article:has(p, .button) {
background-color: royalblue;
}
Ниже приведен результат:

Здесь мы могли бы выбрать статью с абзацем OR или любую статью с классом button. Эти три статьи выбраны, потому что все они содержат HTML-тег p. Но если мы удалим тег p, то цветной останется только последняя статья с классом button ”Купить сейчас”.
Примеры использования CSS :has
В этом разделе мы рассмотрим более практические случаи и примеры использования селектора :has.
Пример навигационного меню
Это подводит нас к следующей части нашего проекта, которая выглядит следующим образом:

Здесь мы навели курсор на местоположения, и при наведении курсора на местоположения вы можете увидеть различные местоположения.
Когда мы не наводим курсор на местоположения и сотрудников, вы заметите, что нет никаких признаков того, что здесь вообще есть выпадающее меню. Если бы мы использовали для этого классы-модификаторы, нам пришлось бы вручную заходить в HTML-файл и писать код. Однако мы можем сделать это с помощью псевдокласса :has.
.nav__item:has(.nav__submenu)::after {
font-family: 'Font Awesome 5 Free';
font-weight: 400;
content: '\f150';
margin-left: 1rem;
}
В приведенном выше коде мы говорим, что если .nav__item имеет внутри себя .nav__submenu, то примените дизайн только к первым двум панелям навигации. Это и есть результат, представленный ниже:

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

Когда флажок установлен, ничего не происходит. Но мы можем легко заставить что-то произойти с помощью псевдокласса :has.
.awesome:has(.awesome__terms:checked) {
display: none;
}
Класс .awesome - это наш модал. Затем мы сказали, что если у нас есть .awesome__terms: checked, то при повторном нажатии на чекбокс будет отображаться следующая страница:

Отлично!
Пример светлого и темного режима
Это еще один быстрый пример того, как мы можем применить что-то, если оно отмечено галочкой.
.three:has(.lightswitch:checked) {
background-color: var(--COLOR);
color: var(---BGCOLOR);
}
После того как мы применим приведенный выше код и нажмем на кнопку “Toggle Dark Mode”, мы получим следующий результат:

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

На изображении выше показана label, содержащая текст “Name”, и текстовый ввод. Теперь мы хотим выбрать что-то в обратном направлении. Раньше мы могли выбирать только вперед, поэтому label должна была идти после текста input. Теперь мы можем изменять метку в зависимости от того, что находится в вводе.
<div>
<label for="name">Имя:</label>
<br />
<input class="name" type="text" name="name" id="name" обязательный pattern="^\[A-Z\][A-z]{2,}" />
</div>
В нашем коде index.html выше мы применили шаблон к input. Здесь у нас есть требуемый шаблон с Regex, который говорит, что текст должен начинаться с заглавной буквы и состоять не менее чем из 3 символов. В наш style.css мы включили следующий код:
label:has(~ .name:valid)::after {
content: '✔️';
цвет: limegreen;
margin-left: 1rem;
font-size: 3rem;
}
Ниже приведен результат:

Имя ”Джойс” соответствует требованию: оно начинается с заглавной буквы и состоит из трех слов, поэтому появляется зеленая галочка.
Теперь, когда мы подошли к концу этого урока, я надеюсь, что вы узнали кое-что о CSS-селекторе/псевдоклассе :has.
Заключение
Селектор CSS :has представляет собой инновационный подход к решению сложных задач стилизации в веб-разработке. В этой статье мы рассмотрели возможности и потенциальные сценарии использования этого мощного селектора, который позволяет нам выбирать элементы на основе их потомков.
Используя селектор :has, веб-разработчики могут повысить эффективность и гибкость своего CSS-кода, упростив процесс выбора и сократив необходимость в ненужных классах и вложенных структурах.
Этот селектор позволяет разработчикам создавать более чистый и удобный код, сохраняя при этом целостность структуры HTML.