Spec-Zone.ru › CSS

:has()

Baseline 2023

Новое

С декабря 2023 года эта функция работает на последних версиях устройств и браузеров. Возможно, эта функция не будет работать на более старых устройствах или браузерах.

  • Узнать больше
  • Полная совместимость
  • Отправить отзыв

Функциональный псевдокласс :has() CSS представляет элемент, если какой-либо из относительных селекторов, переданных в качестве аргумента, совпадает хотя бы с одним элементом при закреплении относительно этого элемента. Этот псевдокласс предоставляет способ выбора родительского элемента или предыдущего соседнего элемента по отношению к элементу-ссылке, приняв в качестве аргумента список относительных селекторов.

/* Selects an h1 heading with a
paragraph element that immediately follows
the h1 and applies the style to h1 */
h1:has(+ p) {
  margin-bottom: 0;
}

Псевдокласс :has() принимает специфичность самого специфичного селектора в своих аргументах, так же, как и псевдоклассы :is() и :not().

Синтаксис

:has(<relative-selector-list>) {
  /* ... */
}

Если сам псевдокласс :has() не поддерживается браузером, весь блок селектора завершится неудачей, если :has() находится в гибком списке селекторов, например, в :is() и :where().

Псевдокласс :has() не может быть вложен в другой псевдоэлемент :has(). Это происходит потому, что многие псевдоэлементы существуют условно на основе стилизации своих предков, и разрешение запроса этих элементов с помощью :has() может привести к циклическим запросам.

Псевдоэлементы также не являются допустимыми селекторами внутри :has() и псевдоэлементы не являются допустимыми якорями для :has().

Примеры

С использованием комбинатора соседних элементов

Объявление стиля :has() в следующем примере настраивает интервалы после заголовков <h1> если за ними сразу следует заголовок типа <h2>.

HTML

<section>
  <article>
    <h1>Morning Times</h1>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
      tempor incididunt ut labore et dolore magna aliqua.
    </p>
  </article>
  <article>
    <h1>Morning Times</h1>
    <h2>Delivering you news every morning</h2>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
      tempor incididunt ut labore et dolore magna aliqua.
    </p>
  </article>
</section>

CSS

h1,
h2 {
  margin: 0 0 1rem 0;
}

h1:has(+ h2) {
  margin: 0 0 0.25rem 0;
}

Результат

Этот пример показывает два похожих текста рядом для сравнения — слева заголовок H1 с последующим абзацем, а справа заголовок H1 с последующим заголовком H2 и затем абзацем. В примере справа :has() помогает выбрать элемент H1 который сразу следует за элементом H2 (указано комбинатором соседних элементов +) и правило CSS уменьшает интервал после такого элемента H1. Без псевдокласса :has() вы не можете использовать селекторы CSS для выбора предшествующего соседнего элемента другого типа или родительского элемента.

С псевдоклассом :is()

Этот пример продолжает предыдущий, чтобы продемонстрировать, как выбрать несколько элементов с помощью :has().

HTML

<section>
  <article>
    <h1>Morning Times</h1>
    <h2>Delivering you news every morning</h2>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
      tempor incididunt ut labore et dolore magna aliqua.
    </p>
  </article>
  <article>
    <h1>Morning Times</h1>
    <h2>Delivering you news every morning</h2>
    <h3>8:00 am</h3>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
      tempor incididunt ut labore et dolore magna aliqua.
    </p>
  </article>
</section>

CSS

h1,
h2,
h3 {
  margin: 0 0 1rem 0;
}

:is(h1, h2, h3):has(+ :is(h2, h3, h4)) {
  margin: 0 0 0.25rem 0;
}

Результат

Здесь первый псевдокласс :is() используется для выбора любого из заголовков в списке. Второй псевдокласс :is() используется для передачи списка селекторов соседних элементов в качестве аргумента к :has(). Псевдокласс :has() помогает выбрать любой элемент H1, H2, или H3 который сразу следует за (указано +) элементом H2, H3, или H4 и правило CSS уменьшает интервал после таких элементов H1, H2, или H3.

Этот селектор также можно было бы записать как:

:is(h1, h2, h3):has(+ h2, + h3, + h4) {
  margin: 0 0 0.25rem 0;
}

Логические операции

Относительный селектор :has() может использоваться для проверки того, истинно ли одно из нескольких свойств или истинны ли все свойства.

Используя значения, разделенные запятыми, внутри относительного селектора :has(), вы проверяете, существуют ли какие-либо из параметров. x:has(a, b) будет стилизовать x если дочерний элемент a ИЛИ b существует.

Объединяя несколько относительных селекторов :has() вместе, вы проверяете, существуют ли все параметры. x:has(a):has(b) будет стилизовать x если дочерний элемент a И b существуют.

body:has(video, audio) {
  /* styles to apply if the content contains audio OR video */
}
body:has(video):has(audio) {
  /* styles to apply if the content contains both audio AND video */
}

Аналогия между :has() и регулярными выражениями

Интересно, что некоторые конструкции CSS :has() можно сопоставить с утверждением о просмотре вперед в регулярных выражениях, так как оба позволяют выбирать элементы (или строки в регулярных выражениях) на основе условия, не фактически выбирая соответствующий элемент (или строку) само условие.

Позитивное утверждение о просмотре вперед (?=шаблон)

В регулярном выражении abc(?=xyz), строка abc совпадает только в том случае, если за ней сразу следует строка xyz. Поскольку это операция предварительного просмотра, xyz не включается в совпадение.

Аналогичная конструкция в CSS будет .abc:has(+ .xyz): она выбирает элемент .abc только в том случае, если у него есть следующий соседний элемент .xyz. Часть :has(+ .xyz) действует как операция предварительного просмотра, так как выбирается элемент .abc и не выбирается элемент .xyz.

Отрицательное утверждение о просмотре вперед (?!шаблон)

Аналогично, в случае с отрицательным утверждением о просмотре вперед, в регулярном выражении abc(?!xyz), строка abc совпадает только в том случае, если за ней не следует xyz. Аналогичная конструкция CSS .abc:has(+ :not(.xyz)) не выбирает элемент .abc если следующим элементом является .xyz.

Спецификации

Спецификация
Селекторы уровня 4
# relational

Совместимость с браузерами

Рабочие столы Мобильные устройства
Chrome Edge Firefox Opera Safari Chrome Android Firefox для Android Opera Android Safari на iOS Samsung Internet WebView Android
:has 105 105 121 91 15.4 105 121 72 15.4 20.0 105

См. также

  • :is(), :where(), :not()
  • Селекторы CSS и комбинаторы
  • Структура CSS селектора
  • Список селекторов
  • Модуль селекторов CSS
  • Поиск элементов DOM с помощью селекторов

© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/:has

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API