Связанный псевдокласс :has()
Выбирайте родительские элементы на основе их дочерних элементов с помощью мощного связанного псевдокласса :has().
«Связанный псевдокласс :has()» — бесплатный урок CSS Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения CSS Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс CSS Academy содержит 4 уроков всего.
Что такое :has()?
Псевдокласс :has() выбирает элемент, если он содержит потомка, соответствующего аргументу. Его часто называют «селектором родителя»: он позволяет оформлять родительский элемент в зависимости от его дочерних элементов — возможности, которой раньше в CSS не было.
Базовый синтаксис
.card:has(img) выбирает любой элемент .card, содержащий потомка img. Аргумент представляет собой список относительных селекторов — любой допустимый CSS-селектор, описывающий элементы относительно целевого элемента.
Оформление родителей
Оформляйте контейнер формы, если он содержит недопустимый ввод: form:has(:invalid) { border-color: red; }. Оформляйте раздел, содержащий заголовок: section:has(h2) { padding-top: 2rem; }. Внешний вид родителя меняется в зависимости от состояния дочернего элемента.
Выбор соседних элементов
:has() может выбирать предшествующие соседние элементы — то, чего не позволяют сделать + и ~. h2:has(+ p) выбирает элементы h2, сразу за которыми следует p. li:has(~ .active) выбирает элементы li, у которых есть следующий соседний элемент .active.
Оформление состояния формы
Реагируйте на встроенную проверку формы без JavaScript: input:has(~ .error-msg) оформляет поле ввода, у которого есть соседнее сообщение об ошибке. label:has(+ input:required) оформляет подписи, связанные с обязательным полем ввода, — всё это только средствами CSS.
Состояние навигации
Выделяйте контейнеры навигации в зависимости от активного дочернего элемента: nav:has(.active) применяет стили ко всей навигации, если любой дочерний элемент имеет активный класс. Это удобно для обозначения текущего раздела навигации на уровне контейнера.
Сочетание с другими псевдоклассами
.grid:has(.card:focus-within) оформляет всю сетку, когда любая карточка получает фокус с клавиатуры. .dropdown:has(:hover) оставляет раскрывающийся список открытым при наведении на любого потомка — это проще, чем сложные цепочки комбинаторов соседних элементов.
Эквивалент медиазапроса в CSS
.sidebar:has(nav) применяет другой макет, чем .sidebar:not(:has(nav)). Условный макет без JavaScript: наличие или отсутствие определённых дочерних элементов управляет макетом родителя, обеспечивая по-настоящему адаптивный CSS, учитывающий содержимое.
Особенности производительности
:has() с широкими селекторами аргумента, например :has(*), может быть затратным: браузеру приходится проверять каждый элемент. Делайте аргументы :has() конкретными. По возможности предпочитайте :has(> .specific-child) (прямой дочерний элемент) варианту :has(.specific-child) (любой потомок).
Поддержка браузерами
:has() поддерживается в Chrome 105+, Safari 15.4+ и Firefox 121+. Полная базовая поддержка появилась в конце 2023 года. Полифила нет (для его имитации потребовался бы JavaScript), поэтому в старых браузерах используйте этот псевдокласс с постепенным улучшением, если функция не является критически важной.
Замена шаблонов JavaScript
Шаблоны, для которых раньше требовались обработчики событий JS: «добавить класс родителю, когда дочерний элемент получает фокус», «показать наложение, когда существует триггер модального окна», «оформить сетку иначе, если в ней ровно три элемента». :has() декларативно обрабатывает все эти случаи.
Проверка знаний
Чем :has() отличается от существующих CSS-комбинаторов, таких как + и ~?
Итоги
:has() — первый настоящий реляционный псевдокласс CSS, позволяющий выбирать родителей и предшествующие соседние элементы. Он поддерживает оформление, определяемое содержимым, реакцию на состояние формы, выделение навигации и множество шаблонов, для которых раньше требовалось управление DOM с помощью JavaScript, — и всё это декларативно в CSS.
Часто задаваемые вопросы
Урок «Связанный псевдокласс :has()» бесплатный?
Да — полный текст урока «Связанный псевдокласс :has()» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс CSS Academy, подпишись на CoddyKit PRO. Курс CSS Academy содержит 4 уроков всего.
Чему я научусь в уроке «Связанный псевдокласс :has()»?
Выбирайте родительские элементы на основе их дочерних элементов с помощью мощного связанного псевдокласса :has(). Ты практикуешь CSS Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать CSS Academy?
Предыдущий опыт не требуется. CSS Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Связанный псевдокласс :has()»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке CSS Academy?
Да. Каждый урок CSS Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Вложенность в нативном CSS
- Связанный псевдокласс :has()
- @scope для изолированных стилей
- API переходов между представлениями