Skip to main content

SITIST - сборник статей про веб разработку

Псевдокласс :has

О псевдоклассе :has мы мечтали уже очень давно и даже могли попробовать в некоторых браузерах. И вот, в декабре 2023 года, наконец-то вышел Firefox 121 версии, которая поддерживает :has. Теперь его понимают все современные браузеры.

Посмотреть актуальную поддержку можно на caniuse

Что делает :has

Позволяет выбрать элемент на основе дочернего или соседнего


selector1:has(selector2) {
  /* Стили */
}

В этом примере стили применятся к селектору selector1, только тогда, когда внутри есть selector2.

Также есть возможность узнать не только о наличии дочерних селекторов, но и о соседних, идущих после первого


selector1:has(+ selector2) {
  /* Стили */
}

Теоретическая часть закончилась, перейдем к полезным примерам использования

Примеры

В формах

Одна из популярных задач верстки - подсветить label, когда что-то произошло с его input. Вариации разные: произошла ошибка в инпуте или при выбранном чекбоксе :checked или инпут неактивен, находится в состоянии :disabled. Раньше для решения такой задачи, мы должны были ставить label после input либо использовать дополнительный span

В простеньком примере я буду обращаться к элементам по тегам, но вы помните, что лучше всё таки задавать классы


<label>
  <input type="checkbox" disabled>
  <span>Lorem, ipsum.</span>
</label>
  
  
label:has(input[type]:disabled) {
  opacity: 0.3;
  cursor: initial;
}

span в этом примере нужен лишь для безопасного универсального использования flex для label, на случай, если внутри подписи окажутся какие-то ещё теги. Так бывает в подписи к чекбоксу о соглашении с правилами сайта и наличии ссылки внутри label

See the pen (@Websitio) on CodePen.

Блокировка скролла при открытии модального окна

Раньше для решения этой задачи нам приходилось использовать JavaScript и с его помощью вешать класс на body. А потом нужно было отслеживать закрытие модального окна, чтобы убрать этот класс.

А теперь можно построить селектор на основе класса открывающего окно


body:has(.modal-is-opened) {
  overflow: hidden;
}

Аналогично можно поступить, если модальное окно сделано с помощью тега dialog

  
body:has(dialog[open]) {
  /* стили */
}
  

Нюансы использования псевдокласса :has

  • В качестве аргументов нельзя использовать псевдоэлементы. Не сработает.
  • Нельзя вкладывать один :has в другой :has
Вверх