Многие годы веб-разработчики мечтали о возможности стилизовать родительский элемент в зависимости от его дочерних элементов. Долгие годы это было возможно выполнить только с помощью JavaScript. Однако спецификация Selectors Level 4 подарила нам псевдокласс :has() — настоящий «родительский селектор», который кардинально меняет логику написания CSS.
- Что такое CSS :has()?
- Примеры использования :has() в реальных задачах
- 1. Стилизация карточки товара при наличии скидки
- 2. Изменение стилей формы при ошибке валидации
- 3. «Исключающая» логика с :not()
- Часто задаваемые вопросы (FAQ) о селекторе :has()
- Можно ли использовать :has() для выбора предыдущего сестринского элемента?
- Сильно ли :has() влияет на производительность рендеринга?
- Заменяет ли :has() функциональность JavaScript?
Что такое CSS :has()?
Псевдокласс :has() предоставляет способ применить стили к элементу, если он содержит (или «имеет») внутри себя определенный элемент, соответствующий заданному селектору. Это позволяет создавать сложную логику интерфейсов исключительно средствами CSS, делая код чище и быстрее.
Примеры использования :has() в реальных задачах
1. Стилизация карточки товара при наличии скидки
Ранее, если внутри карточки добавлялся бейдж «Скидка», нам приходилось вешать отдельный класс на саму карточку, например .card--discount. Теперь это работает автоматически:
|
1 2 3 4 5 |
/* Если внутри .product-card есть элемент с классом .badge-discount */ .product-card:has(.badge-discount) { border: 2px solid var(--accent-red); box-shadow: 0 4px 15px rgba(255, 0, 0, 0.2); } |
2. Изменение стилей формы при ошибке валидации
Вы можете подсветить всю группу полей формы, если хотя бы один из внутренних инпутов не прошел валидацию (состояние :invalid):
|
1 2 3 4 5 6 7 8 9 10 |
/* Стилизуем весь блок form-group, если внутри есть ошибка */ .form-group:has(input:invalid) { background-color: var(--error-bg); border-left: 4px solid red; } /* Изменяем цвет лейбла, если поле с ошибкой находится внутри */ .form-group:has(input:invalid) label { color: red; } |
3. «Исключающая» логика с :not()
Вы можете комбинировать :has() с другими псевдоклассами. Например, выбрать все статьи, в которых нет изображений:
|
1 2 3 4 5 |
/* Применяем стили к статьям без картинок */ article:not(:has(img)) { max-width: 600px; font-size: 1.1rem; } |
Поддержка браузерами: Псевдокласс
:has()полностью поддерживается во всех актуальных версиях браузеров (Chrome, Safari, Firefox). Его можно безопасно использовать в production-проектах в 2026 году без фоллбеков на JS.
Часто задаваемые вопросы (FAQ) о селекторе :has()
Можно ли использовать :has() для выбора предыдущего сестринского элемента?
Да! Это еще одна суперсила этого селектора. Конструкция вида h2:has(+ p) выберет именно тот заголовок h2, сразу за которым идет абзац p. Это открывает невероятные возможности для типографики.
Сильно ли :has() влияет на производительность рендеринга?
Исторически разработчики браузеров боялись внедрять родительский селектор именно из-за проблем с производительностью. Однако современные механизмы инвалидации стилей (в движках Blink, WebKit и Gecko) стали настолько умными, что использование :has() практически не сказывается на FPS страницы, даже на мобильных устройствах.
Заменяет ли :has() функциональность JavaScript?
Во многих визуальных аспектах — да. Задачи по переключению состояний, подсветке активных элементов, раскрытию меню и реакциям на чекбоксы (checkbox hack) теперь решаются с помощью :has() гораздо элегантнее, экономя мегабайты JS-кода.





