: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 |
См. также
© 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