Стилизовать родительский элемент в зависимости от количества его дочерних элементов с помощью CSS :has() — Bram.us
В CSS можно стилизовать элементы в зависимости от количества их братьев и сестер, используя селектор nth-child
.
Но что, если вы хотите стилизовать родительский элемент в зависимости от количества дочерних элементов? Именно здесь в игру вступает селектор CSS :has()
.
~
# Код
Если вы пришли просто за кодом, вот он. Вы также можете увидеть его в действии в демо ниже.
/* Максимум 3 (3 или менее, исключая 0) детей */ ul: has(> :nth-child( -n+3 ):last-child) { контур: 1px сплошной красный; } /* Максимум 3 (3 или менее, включая 0) дочерних элементов */ ul:not(:has(> :nth-child( 3 ))) { контур: 1px сплошной красный; } /* Ровно 5 детей */ ul: has(> :nth-child( 5 ):last-child) { контур: 1px сплошной синий; } /* Не менее 10 (10 и более) детей */ ul:has(> :nth-child( 10 )) { контур: 1px сплошной зеленый; } /* От 7 до 9 детей (включительно) */ ul:has(> :nth-child( 7 )): has(> :nth-child( -n+9 ):last-child) { контур: 1px сплошной желтый; }
Если хотите узнать, как это работает, продолжайте читать 🙂
~
# Селекторы
Шаблон каждого построенного здесь селектора таков:
parent:has(> count-condition ) { … }
- С помощью
мы можем выбратьродительский элемент
, который соответствует определенному условию для своих дочерних элементов. - Передавая
>
в:has()
, мы нацеливаемся народительских
прямых дочерних элементов. -
count-condition
— это то, что нам нужно придумать для каждого типа выбора, который мы хотим сделать. Как и в случае с количественными запросами, мы будем использовать:nth-child()
для этого.
Максимум
x
дочерних элементов Используя :nth-child
с минусом -n
, можно выбрать первые x
дочерних элементов. Если один из них также является самым последним дочерним элементом, вы можете определить, есть ли у родителя до x
дочерних элементов
/* Не более 3 (3 или менее, исключая 0) дочерних элементов */ ul: has(> :nth-child( -n+3 ):last-child) { контур: 1px сплошной красный; }
Этот селектор исключает родителей, у которых нет детей. В большинстве случаев это нормально, так как любой элемент, содержащий только текст, будет сопоставляться, но если вы действительно хотите включить, используйте этот селектор:
/* Максимум 3 (3 или менее, включая 0) дочерних элементов */ ul:not(:has(> :nth-child( 3 ))) { контур: 1px сплошной красный; }
Точно
x
детей Чтобы выбрать элемент x
из набора, вы можете использовать :nth-child
без каких-либо н
индикация. Если этот дочерний элемент также является последним дочерним элементом, вы знаете, что в родительском элементе ровно x
дочерних элементов
/* Ровно 5 дочерних элементов */ ul: has(> :nth-child( 5 ):last-child) { контур: 1px сплошной синий; }
Не менее
x
дочерних элементов x
дочерними элементами, достаточно иметь возможность выбрать в нем дочерний элемент размером x
, чтобы определить это. Здесь нет необходимости в :last-child
./* Не менее 10 (10 и более) детей */ ul: has (> : nth-child ( 10 )) { контур: 1px сплошной зеленый; }
Между
x
и y
детей Чтобы сделать промежуточный выбор, вы можете объединить два условия :has()
вместе. Первый выбирает все элементы, которые имеют x
или более дочерних элементов, тогда как второй отсекает диапазон, разрешая только элементы, которые имеют не более y
дочерних элементов. Будут рассчитаны только элементы, соответствующие обоим условиям:
/* От 7 до 9 детей (включительно) */ ul:has(> :nth-child( 7 )): has(> :nth-child( -n+9 ):last-child) { контур: 1px сплошной желтый; }
~
# Демонстрация
См. родительские элементы Pen Styling на основе количества дочерних элементов с помощью CSS :has() от Bramus (@bramus) на CodePen.
~
# Поддержка браузера
Эти селекторы поддерживаются всеми браузерами, имеющими :has()
поддержка. На момент написания это не включает Firefox.
Использование экспериментальной поддержки :has()
в Firefox также не помогает. Его реализация все еще является экспериментальной, так как пока поддерживает не все типы выделения. Относительный анализ селекторов (например, a:has(> b)
) — одна из тех функций, которые еще не поддерживаются. Отслеживание ошибки: #1774588
~
# Распространите информацию
Чтобы помочь распространить содержимое этого сообщения, не стесняйтесь ретвитить его объявление:
Стиль родительского элемента в зависимости от количества дочерних элементов с использованием CSS `:has()`
🔗 https://t.co/Kn0JjafCR4
🏷 #css #селекторы pic.twitter.com/ZMtm4IUD0P
— Bram.us (@bramusblog) 17 ноября 2022 г.
~
🔥 Нравится то, что вы видите? Хотите оставаться в курсе? Вот как:
- Подпишитесь на @bramus в Твиттере
- Подпишитесь на @bramus на Mastodon
- Подпишитесь на @bramusblog в Твиттере
- Подпишитесь на bram.us, используя RSS
Если не указано иное, содержимое этого поста лицензировано в соответствии с лицензией Creative Commons Attribution 4.0, а образцы кода лицензированы в соответствии с лицензией MIT
.Селектор CSS :has() — это нечто большее, чем «родительский селектор» — Bram.us
Safari Technology Preview 137 только что вышел, с неотмеченной поддержкой CSS :has()
. Часто называемый «родительским селектором», CSS :has()
— это нечто большее…
~
# CSS
:has()
?В соответствии со спецификацией селекторов-4:
Псевдокласс
:has()
CSS представляет элемент, если любой из селекторов, переданных в качестве параметров, соответствует хотя бы одному элементу.
Этот селектор называется «родительским селектором», так как случаи по умолчанию действительно позволяют вам выбрать родительский элемент, у которого есть определенные дочерние элементы.
/* Соответствует элементам , содержащим дочерний элемент */ а: имеет (изображение) {…} /* Соответствует элементам , которые непосредственно содержат дочерний элемент */ а: имеет (> изображение) { … } /* Соответствует элементам, которые не содержат элементов заголовка: */ раздел: не (: имеет (h2, h3, h4, h5, h5, h6))
Круто!
~
# Больше, чем родительский селектор
Селектор :has()
— это больше, чем просто родительский селектор. Как поделился Адриан Бесе в своем посте на Smashing Magazine:
/* Соответствует элементам
figure:has(figcaption)
соответствует фигуре
, которая имеет figcaption
. Селектор figure:has(figcaption) img
OTOH соответствует img
внутри фигуры
, у которой есть figcaption
Вот перо:
См. перо Селектор CSS :has() намного больше чем «Селектор родителей» Брамуса (@bramus) на CodePen.
В браузерах, поддерживающих :has()
, вы должны увидеть красную пунктирную рамку вокруг верхнего изображения.
Вот еще один пример из спецификации, в котором используется относительный селектор. Он выбирает h2
, за которым следует p
, показывая, что выбор не ограничивается только родителями.
/* Соответствует элементам, только если за ними непосредственно следует элемент
*/ h2:has(+ p) { … }
Это работает, потому что селектор реляционного псевдокласса :has()
принимает
в качестве аргумента. это список из
s, который может содержать любой из уже известных нам комбинаторов: +
, ~
, >
, …
UPDATE: у моего коллеги Jhey есть хорошая статья на developer.chrome.com где он называет это «Семейный селектор» — мне нравится это имя!
~
# Другие особенности
Как и CSS :is()
, CSS :has()
имеет следующие особенности:
-
Список селекторовВ соответствии с резолюцией CSSWG от 2022.12.07 аргументом теперь является (не прощающий) список:has()0006 прощает
- Специфика
:has()
заключается в ее наиболее специфичном аргументе
Нажмите на сообщение на CSS :is()
для получения дополнительной информации об этом.
~
# Поддержка браузера
💡 Хотя этот пост был первоначально опубликован в декабре 2021 года, раздел ниже постоянно обновляется. Последнее обновление: 08 декабря 2022 г. .
Вот актуальный список поддерживаемых браузерами селектора CSS :has()
:
- Chromium (Blink)
✅ Доступен в Chromium 105 и выше.
Экспериментальная поддержка впервые появилась в Chromium 103.
- Firefox (Геккон)
👨🔬 Экспериментальная поддержка доступна в Firefox 103 и выше при включении
layout.css.has-selector.enabled 9Флаг 0006 через
about:config
. Реализация не доработана, так как пока не поддерживает парсинг относительных селекторов.- Сафари (веб-кит)
✅ Доступно в Safari 15.4 и выше.
Экспериментальная поддержка впервые появилась в Safari Technology Preview 137.
Встроенное ниже перо покажет, поддерживает ли браузер, который вы сейчас используете, CSS :has()
или нет:
См. ручку
CSS: имеет тест поддержки селектора от Bramus (@bramus)
на CodePen.
Чтобы быть в курсе последних новостей о поддержке браузера, вы можете отслеживать следующие проблемы с отслеживанием:
- WebKit/Safari: Проблема № 227702 — РЕШЕНО ИСПРАВЛЕНО
- Blink/Chromium: выпуск № 669058 — исправлено (закрыто)
- Gecko/Firefox: выпуск № 418039 — НОВЫЙ
~
# Распространите информацию
Чтобы помочь распространить содержание этого поста, не стесняйтесь ретвитить его анонс:
Селектор CSS `:has()` — это нечто большее, чем «родительский селектор».
🔗 https://t.co/rzAiRG8DQk
🏷 #css #селекторы pic.twitter.com/cwpv7esjwb
— Bram.us (@bramusblog) 21 декабря 2021 г.
~
🔥 Нравится то, что вы видите? Хотите оставаться в курсе? Вот как:
- Подпишитесь на @bramus в Твиттере
- Подпишитесь на @bramus на Mastodon
- Подпишитесь на @bramusblog в Твиттере
- Подпишитесь на bram.