В обычном CSS дочерний элемент легко стилизовать в зависимости от состояния родительского: например, изменить кнопку при наведении на карточку. Обратная задача — изменить саму карточку, когда курсор наведен на ее кнопку, — долгое время требовала JavaScript или дополнительных классов.
Псевдокласс :has() решает эту проблему. Он позволяет выбрать элемент, если внутри него есть дочерний элемент, соответствующий заданному условию. В Elementor это удобно использовать для карточек услуг, товаров, записей и элементов Loop Grid.
Что делает псевдокласс :has()
Селектор `.card:has(.elementor-button:hover)` означает: выбрать элемент с классом `card`, если внутри него находится кнопка Elementor, на которую в данный момент наведен курсор.
В отличие от обычного селектора потомка, :has() позволяет стилизовать именно родительский контейнер. Это полезно, когда нужно выделить всю карточку, а не только отдельную кнопку или ссылку.
Псевдокласс работает без JavaScript и не изменяет HTML-структуру страницы. Состояние карточки автоматически обновляется вместе с состоянием дочернего элемента.
- `:has(.elementor-button:hover)` — карточка реагирует на наведение на кнопку.
- `:has(a:focus-visible)` — карточка реагирует на фокус ссылки при навигации с клавиатуры.
- `:has(.sale-badge)` — можно изменить внешний вид карточки, если в ней есть бейдж со скидкой.
- `:has(input:checked)` — можно стилизовать блок в зависимости от состояния переключателя или чекбокса.
Как подготовить карточку в Elementor
Сначала нужно добавить контейнеру карточки собственный CSS-класс. Откройте нужный контейнер в Elementor и перейдите на вкладку «Дополнительно». В поле CSS-классов укажите `card` без точки.
Класс должен быть добавлен именно к родительскому контейнеру, стиль которого вы хотите изменить. Если добавить его к кнопке, селектор :has() не даст нужного результата.
Проверьте структуру карточки: кнопка или ссылка должны находиться внутри контейнера с классом `card`. Если кнопка фактически расположена за пределами контейнера из-за особенностей шаблона, селектор не сработает.
- Контейнер карточки: класс `card`.
- Внутри контейнера: заголовок, описание, изображение и кнопка или ссылка.
- Класс добавляется без символа `.`.
- Названия классов должны совпадать с написанием в CSS, включая дефисы и регистр.
Базовый пример: выделение карточки при наведении на кнопку
Сначала задайте карточке базовое состояние. Это важно: пользователь должен видеть корректный дизайн даже в браузере, который не поддерживает :has(). Для плавности перехода добавьте transition к свойствам, которые будут изменяться.
Затем используйте :has() для состояния наведения на кнопку и фокуса на ссылке. Такой подход одновременно учитывает взаимодействие мышью и клавиатурой.
- Базовые стили работают независимо от поддержки :has().
- Трансформация должна быть умеренной, чтобы карточка не смещала соседние элементы.
- Тень, рамка или изменение фона обычно создают понятный визуальный сигнал.
.card {
transition: box-shadow .25s ease, transform .25s ease;
}
.card:has(.elementor-button:hover),
.card:has(a:focus-visible) {
transform: translateY(-4px);
box-shadow: 0 12px 30px rgba(0, 0, 0, .12);
}
Как добавить CSS
Код можно разместить там, где в вашей конфигурации доступны пользовательские стили: в настройках CSS сайта, темы или Elementor. Главное, чтобы стили загружались на странице с этой карточкой.
Если CSS добавляется непосредственно к конкретному элементу, проверьте, поддерживает ли это поле обычные CSS-правила, а не только объявления для текущего селектора. При необходимости разместите код в глобальном CSS сайта.
Поддержка клавиатуры и доступность
Стилизация только через `:hover` не учитывает пользователей, которые перемещаются по странице с клавиатуры. Поэтому целесообразно добавлять условие `a:focus-visible`. Когда ссылка получает видимый фокус клавиатуры, изменяется вся карточка.
Не убирайте стандартный индикатор фокуса без замены. Пользователь должен понимать, какой элемент сейчас активен. Если дизайн сайта предусматривает собственный стиль фокуса, сделайте его достаточно контрастным.
Если в карточке используется кнопка, а не ссылка, при необходимости можно отдельно учесть оба типа элементов.
- Для ссылок: `.card:has(a:focus-visible)`.
- Для кнопок: `.card:has(button:focus-visible)` или селектор класса кнопки Elementor.
- Не полагайтесь только на изменение тени: фокус желательно обозначать также рамкой, контуром или другим заметным эффектом.
- Проверяйте состояние карточки клавишей Tab, а не только курсором.
.card:has(a:focus-visible),
.card:has(button:focus-visible) {
outline: 3px solid rgba(30, 100, 220, .45);
outline-offset: 4px;
}
Практические варианты использования в Elementor
В карточках услуг :has() помогает связать кнопку «Узнать больше» со всем блоком. В карточках товаров можно выделять контейнер во время взаимодействия с кнопкой покупки или ссылкой на товар.
В Loop Grid класс должен присутствовать в шаблоне элемента, чтобы каждая сгенерированная карточка получила одинаковые правила. Если класс назначен контейнеру шаблона, селектор применяется к каждому его экземпляру.
- Изменить фон карточки, когда активна ссылка внутри.
- Добавить рамку товара, если в нем есть бейдж со скидкой.
- Показать дополнительную иконку или изменить цвет заголовка при фокусе на кнопке.
- Стилизовать блок формы, если внутри отмечен чекбокс.
- Выделить родительский элемент меню, когда один из его пунктов получает фокус.
.card:has(.sale-badge) {
border-color: #e53935;
}
.card:has(.elementor-button:hover) .card-title,
.card:has(a:focus-visible) .card-title {
color: #1e64dc;
}
Совместимость, fallback и типичные ошибки
Псевдокласс :has() поддерживается современными браузерами, но в старых версиях или отдельных устаревших средах правило может быть проигнорировано. Поэтому базовый вид карточки нужно задавать без :has(), а эффект через этот псевдокласс использовать как дополнительное улучшение.
Если браузер не распознает селектор :has(), группа правил с ним не применяется. При этом базовые свойства `.card` остаются действующими, если они вынесены в отдельное правило.
Не добавляйте без необходимости чрезмерно сложные селекторы. Они усложняют поддержку стилей и могут уступать правилам Elementor или темы по специфичности.
- Не пишите `.card:has(.elementor-button:hover)` на кнопке — класс `card` должен находиться на родительском контейнере.
- Не добавляйте точку в поле CSS-классов Elementor: там нужно указать `card`, а не `.card`.
- Убедитесь, что кнопка действительно находится внутри карточки в DOM-структуре.
- Очистите кэш плагина, CDN и браузера после изменения CSS.
- Проверьте, не перекрывает ли правило Elementor или тема.
- Не используйте `overflow: hidden`, если поднятая карточка или ее тень должны выходить за пределы контейнера.
.card {
transform: none;
box-shadow: 0 2px 10px rgba(0, 0, 0, .06);
transition: box-shadow .25s ease, transform .25s ease;
}
@supports selector(.card:has(a)) {
.card:has(.elementor-button:hover),
.card:has(a:focus-visible) {
transform: translateY(-4px);
box-shadow: 0 12px 30px rgba(0, 0, 0, .12);
}
}
Как проверить, почему стиль не работает
Откройте инструменты разработчика браузера и выберите контейнер карточки. Убедитесь, что на нем есть класс `card`, а кнопка или ссылка вложены в этот же элемент.
Затем проверьте правило на панели стилей. Если оно перечеркнуто, проблема обычно заключается в специфичности или порядке загрузки CSS. Если правило вообще не отображается, проверьте синтаксис селектора и место вставки кода.
- Проверить класс на правильном контейнере.
- Проверить вложенность кнопки или ссылки.
- Проверить состояние `:hover` и `:focus-visible` в DevTools.
- Временно добавить заметный `background`, чтобы быстро увидеть, срабатывает ли селектор.
Как протестировать готовый эффект
После добавления стилей проверьте карточку на реальной странице, а не только в редакторе Elementor. Наведите курсор на кнопку, переместите его за пределы карточки и убедитесь, что состояние возвращается к базовому.
Отдельно протестируйте навигацию с клавиатуры. Нажимайте Tab, наблюдайте за видимым фокусом и проверяйте, подсвечивается ли правильная карточка. Также просмотрите страницу на узком экране: эффект не должен создавать горизонтальную прокрутку или накладываться на соседние блоки.
- Наведение на кнопку мышью.
- Фокус на ссылке или кнопке клавишей Tab.
- Проверка нескольких карточек одновременно.
- Проверка мобильной и планшетной ширины.
- Тестирование в нескольких современных браузерах.
- Проверка после очистки кэша.
Частые вопросы
Нужен ли JavaScript для стилизации родительского контейнера?
Нет. Псевдокласс :has() позволяет изменять стиль родительского контейнера только с помощью CSS, когда дочерний элемент соответствует заданному условию.
Куда добавлять класс card в Elementor?
Класс `card` нужно добавить родительскому контейнеру карточки на вкладке «Дополнительно» в поле CSS-классов. В поле вводится `card` без точки.
Будет ли :has() работать в Loop Grid?
Да, если класс добавлен контейнеру шаблона элемента, а нужная кнопка или ссылка находится внутри этого контейнера. Проверьте готовую HTML-структуру с помощью инструментов разработчика.
Что произойдет в браузере без поддержки :has()?
Правила с :has() не применятся, но базовые стили карточки сохранятся, если они заданы отдельно. Поэтому не стоит делать корректный вид карточки зависимым только от этого псевдокласса.
Почему карточка не реагирует на наведение на кнопку?
Наиболее частые причины — класс добавлен не тому контейнеру, кнопка не вложена в карточку, CSS перекрывается другим правилом или изменения скрывает кэш. Проверьте DOM-структуру, панель стилей и кэш сайта.
Вывод
Псевдокласс :has() дает разработчикам Elementor простой способ связать состояние дочернего элемента с оформлением всей карточки. Для этого достаточно добавить собственный класс контейнеру и описать нужное условие в CSS.
Лучший практический подход — объединить базовые стили без :has(), реакцию на `:hover` и `:focus-visible`, а также проверку навигации с клавиатуры и мобильной версии. Так карточки останутся понятными, доступными и предсказуемыми в разных средах.