Css селектор родительский: Sass: Родительский селектор

Содержание

Ссылка на родителя селектора · Less. Путеводитель для новичков

Благодаря вложенности, мы можем писать бесподобный структурированный код, который будет понятен всем разработчикам и даже тому, кто его написал. Но сейчас у нас на повестке дня стоит вопрос о том, как в этой модели вложенности работать с псевдоклассами, псевдоэлементами и комбинированными селекторами. Для этого в Less есть специальный символ — & (родительский селектор).

Символ & играет особую и важную роль в Less. С помощью этого символа можно обращаться к родителю текущего селектора, а также сшивать, объединять их и создавать внутри них области видимости (подробнее в главе 3).

Прямое объединение селекторов

Родительский селектор может использоваться для объединения любых селекторов, псевдоэлементов и псевдоклассов.

Пример 2.3.1

Наиболее часто, символ & применяется для добавления псевдоклассов к селекторам. Например, с помощью него можно добавить эффект при наведении, используя псевдокласс :hover.

Посмотрите на следующий пример:

a {
  color: #777;
  text-decoration: none;
  &:hover {
    color: #a31515;
  }
}

После компиляции селектор a и псевдокласс :hover будут объединены, а их свойства поделены между ними в соответствии с их объявлениями по вложенности:

a {
  color: #777;
  text-decoration: none;
}
a:hover {
  color: #a31515;
}
Пример 2.3.2

Как я уже говорил раньше, объединять можно и селекторы с другими селекторами. Для примера ниже приводится код объединения .class-1 с .class-2.

.class-1 {
  background-color: #fff;
  &.class-2 {
    color: #000;
  }
}

На выходе компилятора получается сдвоенный селектор:

.class-1 {
  background-color: #fff;
}
.class-1.class-2 {
  color: #000;
}

Обратите внимание, что препроцессор не запрещает использовать стандартный синтаксис .class-1.class-2 {}. Но при таком стиле записи теряется весь смысл и шарм, который нам дарит препроцессор.

Обратное объединение селекторов

У автомобилей есть передний и задний ход, такой же функционал реализован и у символа &. Такие возможности позволяют писать более гибкий код, когда нужно добавить какой-то селектор перед другим селектором. Вместо того, чтобы писать новую структуру, можно просто использовать этот функционал.

Пример 2.3.3

Примером может послужить поддержка IE, когда с помощью JavaScript в тег body или html добавляются классы .ie6, .ie7 и им подобные. Возможность использования обратного объединения позволяет писать более гибкий код, когда нужно изменить контекст применения селектора.

Представим, что нашему проекту требуется поддержка IE7, который не умеет работать со свойством border-image. А по дизайну в любом случае должна быть рамка между двумя элементами, иначе они превратятся в тыкву.

На деле имеем такой код:

.item-card {
  background-color: #f5f5f5;
  border-image: url("images/bg-image. png") 30 round round;
}

Вместо того, чтобы писать новый класс .ie7 .item-card {} и плодить сложно поддерживаемую структуру, можно использовать принцип обратного объединения.

.main {
  .item-card {
    background-color: #f5f5f5;
    border-image: url("images/bg-image.png") 30 round round;
    .ie7 & {
      border: 1px solid #a31515;
    }
  }
}

Во время компиляции, селектор, у которого имеется ссылка на родителя справа от имени, будет опущен ниже по древу вложенности вне зависимости от глубины вложенности. То есть при обратном объединении родительский селектор всегда ссылается на корневой селектор всего объявления.

.main .item-card {
  background-color: #f5f5f5;
  border-image: url("images/bg-image.png") 30 round round;
}
.ie7 .main .item-card {
  border: 1px solid #a31515;
}

Внимание!

Если написать .ie7 & без пробела, то после компиляции селектор будет комбинированным, а не вложенным:

. item-card {
  background-color: #f5f5f5;
  border-image: url("images/bg-image.png") 30 round round;
}
.ie7.item-card {
  border: 1px solid #a31515;
}

Сшивание (склеивание) селекторов

Не редко требуется производить операцию склеивания имён текущего и родительского селектора. Такая практика применяется при создании новых классов на основе старого. Кроме того, такая операция просто необходима тем людям, кто использует методологию БЭМ (и ей подобные) при написании стилей.

Пример 2.3.4

Стоит задача стилизации кнопок для проекта. Кнопки имеют различные цвета, в зависимости от действия и контекста использования. Изначально кнопки имеют серый цвет. Кнопка, предназначенная для добавления новой записи имеет зелёный цвет, а для удаления — красный.

Если опустить основные свойства, рассматривая лишь те, что необходимы для определения цвета кнопок, то получается следующий код:

.button {
  background-color: #ddd;
  color: #000;
}
.button-add {
  background-color: green;
  color: #fff;
}
. button-remove {
  background-color: red;
  color: #fff;
}

С помощью препроцессора этот код можно структуризировать, и тем самым упростить. Для этого используется сшивание селекторов. В этом случае наш код преобразуется таким образом:

.button {
  background-color: #ddd;
  color: #000;
  &-add {
    background-color: green;
    color: #fff;
  }
  &-remove {
    background-color: red;
    color: #fff;
  }
}

А ещё этот код можно оптимизировать, указав сначала общий для двух селекторов цвет текста, а уже потом индивидуальный цвет фона. Но не стоит забывать, что такая оптимизация не имеет никакого эффекта в случае, если после компиляции код будет минифицирован, так как практически любой современный минификатор умеет группировать селекторы с общими свойствами.

.button {
  background-color: #ddd;
  color: #000;
  &-add,
  &-remove {
    color: #fff;
  }
  &-add { background-color: green; }
  &-remove { background-color: red; }
}

Многократное и комбинированное использование

Символ & может использоваться в селекторе больше одного раза. Это даёт возможность несколько раз ссылаться на родительский селектор, но не писать его имя.

Пример 2.3.5

Немного академический пример, который не несёт в себе смысловой нагрузки, но всё таки отображает суть происходящего:

.header {
  .item {
    & + & {
      color: red;
    }
    & & {
      color: green;
    }
    && {
      color: blue;
    }
    &, &-box {
      color: yellow;
    }
  }
}

Важно понимать, что обращение к родительскому селектору происходит по всей его ветви селекторов, а не только к ближайшему селектору от места обращения.

.header .item + .header .item {
  color: red;
}
.header .item .header .item {
  color: green;
}
.header .item.header .item {
  color: blue;
}
.header .item,
.header .item-box {
  color: yellow;
}

Такое использование символа & практически нигде не используется (кроме случая &, &-box). Если вы его встретите где-нибудь, то будьте уверены, что сегодня ваш день.

Пример 2.3.6

Из примера 2.3.5 следует, что с помощью такого вот взаимодействия текущего селектора с родительским, можно творить неведомые ранее чудеса. Это может пригодиться тогда, когда нужно комбинировать селекторы между собой. Наиболее ярко суть происходящего описывает пример из документации.

ul, li {
  border-top: 2px dotted #366;
  & + & {
    border-top: 0;
  }
}

Суть такого метода заключается в том, что компилятор сначала возьмёт весь перечень селекторов, добавит к нему свойства и сохранит полученный результат. В результате чего получится:

ul,
li {
  border-top: 2px dotted #366;
}

Далее компилятор встретит на своём пути два вызова родительского селектора и поймёт, что кроме них у него имеется перечень селекторов. Немного подумав, он начнёт их комбинировать, то есть перебирать все доступные комбинации. На практике это будет выглядеть следующим образом:

ul + ul,
ul + li,
li + ul,
li + li {
  border-top: 0;
}

Но что будет, если указать три вызова родительского селектора (

& + & + &)? Правильно, будет комбинация доступного перечня по трём позициям:

ul + ul + ul,
ul + ul + li,
ul + li + ul,
ul + li + li,
li + ul + ul,
li + ul + li,
li + li + ul,
li + li + li {
  border-top: 0;
}

Мысли и советы

Описанный в этой части функционал на практике имеет довольно спорные моменты. Во-первых, некоторые люди против применения возможности склеивания имён вследствие того, что это затрудняет поиск селектора в редакторах. Во-вторых, нужно осознанно ссылаться на родителя, как в случае прямого , так и в случае обратного объединения.

Также не стоит злоупотреблять возможностью комбинирования селекторов. Да, в некоторых случаях это может сэкономить время написания кода, но в итоге сэкономленное время будет тратиться в будущем на понимание происходящего.

Почему у нас нет селектора по родителю — Веб-стандарты

Относительно регулярно я вижу дискуссии о том, должен ли CSS включать селектор по родителю и, пока я не выяснил, как работает движок браузера, сам строил предположения по этому поводу.

Вкратце: производительность.

Как работает CSSСкопировать ссылку

В связи с моей работой я делаю много тестов производительности. Для определения «узких мест» мы используем массу приложений. Например, Google Page Speed, который дает рекомендации по улучшению производительности JavaScript и рендеринга. Прежде чем я перейду к рассмотрению этих рекомендаций, нам нужно разобраться как браузеры работают с CSS

Стиль элемента применяется в момент его созданияСкопировать ссылку

Мы часто рассматриваем веб-страницы как полноценные документы, наполненные элементами и содержимым. Между тем, браузеры разработаны так, чтобы обрабатывать документ потоково. Они начинают получать документ с сервера и могут начать его отображать до момента полной загрузки. Каждый узел анализируется и отображается в окне по мере получения.

Взгляните на этот документ:

<body>
    <div>
        <div>
            <p>Lorem Ipsum</p>
        </div>
        <div>
            <p>Lorem Ipsum</p>
            <p>Lorem Ipsum</p>
            <p>Lorem Ipsum <span>Test</span></p>
        </div>
    </div>
</body>

Браузер начинает сначала и видит элемент <body>. В этот момент времени считается, что этот узел не имеет дочерних узлов. Ничего более не рассматривается. Браузер определяет соответствующий ему обобщенный набор стилей и применяет его к элементу. Какой шрифт, цвет, интерлиньяж? После того, как это все будет выяснено, элемент отображается на экране.

Далее браузер видит элемент <div> со значением атрибута ID content. И снова в этот момент времени браузер считает его пустым. Он не рассматривает другие элементы. Как только браузер рассчитает стиль, элемент отображается на экране. Затем браузер определяет нужно ли перерисовать <body> — стал ли элемент шире или выше? Я подозреваю, что там есть масса других проверок, но изменение ширины и высоты — самый распространенный способ повлиять на отображение родительского узла.

Процесс продолжается, пока браузер не достигнет корневого узла документа.

Вот как выглядит визуализация процессов перерисовки в Firefox:

CSS-селекторы анализируются справа налевоСкопировать ссылку

Чтобы определить, применяется ли CSS-правило к определенному элементу, браузер рассматривает селектор справа налево.

Если у вас есть селектор body div#content p { color: #003366; }, то, когда каждый элемент появляется на странице, браузер проверяет, является ли он параграфом. Если да, он начинает подниматься вверх по DOM и ищет <div> со значением атрибута ID равным content. Если он его находит, то продолжает подниматься по DOM пока не найдет <body>.

Таким образом, читая селектор справа налево, браузер значительно быстрее может определить применяется ли правило к элементу. Чтобы определить, какой из селекторов обладает большей производительностью, нужно выяснить, как много узлов придется рассмотреть, чтобы определить, можно ли применить правило к элементу.

ПравилаСкопировать ссылку

Возвращаясь к Page Speed, давайте рассмотрим несколько его рекомендаций:

  • Избегайте селектора по потомку: .content .sidebar;
  • Избегайте селектора по дочернему элементу: .content > .sidebar и селектора по следующему элементу: . content + .sidebar.

Конечно, селекторы по ID — самые быстрые. Проверить применимость селектора #content к рассматриваемому элементу можно очень быстро. Есть у него этот ID или нет? Селекторы по классу практически такие же быстрые, так как нет никаких связанных элементов, которые надо проверять.

Селекторы по потомкам, такие как .content .sidebar — более ресурсоемкие, так как, чтобы определить надо ли применять правило к .sidebar, браузер должен найти .content. Cелектор по дочернему элементу, например, .content > .sidebar, лучше селектора по потомку, так как браузер должен проверить только один элемент вместо множества. (К сожалению, селекторы + и > не поддерживаются IE6. Так что если его поддержка актуальна для вас, то про них придется забыть — прим. переводчика).

Селектор по тегу и универсальный селекторСкопировать ссылку

В рамках рекомендации избегать селекторов по потомку, дочернему или следующему элементам, рекомендуется избегать универсального селектора и селектора по тегу.

Рассмотрим следующий пример:

#content * { color: #039; }

Так как в селекторе присутствует ID, то можно подумать, что этот селектор обрабатывается очень быстро. Проблема в том, что браузер обрабатывает селектор справа налево и сперва проверяется универсальный селектор. Для того чтобы браузер мог определить, должен ли цвет текста элемента быть тёмно-синим, надо проверить каждый предок элемента, пока не будет найден предок с атрибутом ID равным content или не будет достигнут корень документа.

И это должно быть сделано для каждого элемента на странице.

Теперь, когда мы понимаем, как элемент обрабатывается, как определяется применимость правил к элементу, давайте рассмотрим пример.

Почему IE долго не поддерживал

:last-childСкопировать ссылку

Все жаловались: у всех браузеров, кроме IE, есть поддержка :last-child (она появилась только в IE9!) Некоторые могли подумать насколько же сложнее сделать :last-child, если уже реализован :first-child?

Давайте представим, что мы — браузер и мы парсим документ-пример, который я приводил ранее.

.module > p:first-child { color: red; } /* Первое правило */
.module > p:last-child { color: blue; } /* Второе правило */

Когда мы рассматриваем внутренности первого <div>, мы видим, что там есть параграф. Браузер видит что-то вроде этого:

<div>
    <p>Lorem Ipsum</p>

Нужно ли применить первое правило к параграфу? Да, это параграф; да, это первый дочерний узел; и, да, это непосредственный потомок элемента с классом module.

Нужно ли применить к этому параграфу второе правило? На данный момент это последний элемент. Но мы могли ещё не загрузить все элементы и не можем быть уверены, что он останется последним.

Вне зависимости от того, как решать эту дилемму, у нас возникает необходимость повторного анализа стилей двух узлов для каждого нового узла, который мы добавляем в DOM. Если я добавлю ещё один параграф следом за первым, мы должны так же повторно перерассчитать стили, которые применяются к предыдущему параграфу.

Как на самом деле это делает браузер?Скопировать ссылку

Я не мог сказать с абсолютной уверенностью, как браузеры парсят :last-child, так что я создал несколько тестов:

  • Статическая HTML-страница;
  • Рендеринг с паузами в одну секунду.

Первый пример весьма скучен. В любом браузере, включая IE9, всё отображается корректно. Внутри <div> первый элемент красный, а последний синий. Но посмотрите на второй пример, и вы увидите интересные отличия в поведении браузеров.

Второй пример приостанавливается перед добавлением каждого параграфа в <div>.

В Firefox первый параграф изначально отображается синим. Когда загружается второй параграф, первый становится красным и второй — синим. Когда загружается третий параграф, второй отображается цветом по умолчанию и третий отображается синим. Firefox рассматривает каждый элемент, который был загружен в качестве последнего элемента, пока не будет загружен ещё один.

В Safari, Chrome и Opera мы увидим другой подход. Первый параграф красный. Второй отображается чёрным. Последний параграф отображается чёрным, пока браузер не получит закрывающий тег </div>. В этот момент последний параграф становится синим. Эти браузеры не рассматривают элемент как последний, пока не будет закрыт родительский.

В Internet Explorer 9 Beta я нашел интересный баг. В то время, как статическая страница отображается корректно, версия с паузами отрабатывает с любопытным побочным эффектом. Первый параграф синий, второй параграф синий и затем — третий. Когда закрывающий тег </div> загружен, предпоследний параграф меняет цвет на чёрный. IE9 пытается обрабатывать селектор как WebKit и Opera, но… м-м… не выходит. Надо бы отправить багрепорт в Microsoft.

Почему у нас нет селектора по родителю?Скопировать ссылку

Уже дано достаточно пояснений, чтобы можно было вернуться к оригинальному вопросу. Проблема не в том, что у нас не может быть селектора по родителю. Проблема в том, что мы столкнемся с проблемами быстродействия, когда дело дойдет до определения того, какие CSS-правила применимы к данному элементу. Если Google Page Speed не рекомендует использование универсальных селекторов, то можно гарантировать, что селектор по родителю будет первым в списке ресурсоемких селекторов, намного опережая все проблемы с производительностью, которые могут быть вызваны использованием универсального селектора.

Давайте посмотрим почему. Первым делом давайте приведём пример синтаксиса для селектора по родителю.

div.module:has(span) { color: green; }

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

Посмотрите на часть нашего документа:

<div>
    <p>Lorem Ipsum</p>
    <p>Lorem Ipsum</p>
    <p>Lorem Ipsum <span>Test</span></p>
</div>

Исходя из того, что мы видим, .module будет отображён без использования правила, применяемого селектором по родителю. Когда будет загружен первый элемент <p>, нужно повторно оценить применимость селектора по родителю к <div>. Нужно сделать это снова для следующего параграфа. И снова, для следующего. Наконец, когда <span> загружен, селектор по родителю будет применен к родительскому <div>, и элемент нужно будет повторно перерисовать.

И что теперь? Теперь, если изменится любое наследуемое CSS-свойство, каждый потомок должен будет повторно анализироваться и перерисовываться. Ох…

Почему проблему можно решить с помощью JavaScript?Скопировать ссылку

Это только кажется, что JavaScript решает проблему. В общем случае JavaScript-заплатки (заплатки — polyfills — части кода, обеспечивающие функциональность, которую должен обеспечивать браузер — прим. переводчика). Или регрессивное усовершенствование (или как там вы, молодежь, это сейчас называете) запускаются только один раз, после полной загрузки DOM.

Для того чтобы действительно имитировать поведение CSS, любой скрипт, решающий эту проблему, должен запускаться после отображения каждого элемента на странице, чтобы определить, нужно ли применить нашу «заплатку». Помните CSS-expressions в Internet Explorer? Именно по этой причине они вызывали такие проблемы с производительностью.

Не невозможноСкопировать ссылку

Появится ли когда-нибудь селектор по родителю? Возможно. То, что я описал, не невозможно. На самом деле — наоборот. Это значит только то, что нам придётся иметь дело с ухудшением производительности из-за использования этого селектора.

как работает селектор CSS

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

В спецификации CSS Selectors 4 CSS представляет новый селектор под названием :has() , который, наконец, позволяет нам выбирать родителей. Это означает, что мы сможем настроить таргетинг на элемент CSS, который имеет конкретных дочерних элементов. Это уже поддерживается в Safari , а также в Chrome 105 . Полная таблица поддержки показана ниже:

Поскольку поддержка расширяется, в этой статье я сосредоточусь на том, как работает выбор родительского элемента CSS, и как это можно сделать сегодня, если поддержка доступна. Тем временем, если вам требуется полная поддержка во всех браузерах, вы также можете реализовать этот полифилл, пока не будет доступна собственная поддержка CSS.

Как работают родительские селекторы в CSS

В CSS, если мы хотим что-то выбрать, мы используем селекторы, которые нисходят на DOM. Например, выбор тега p в теге div выглядит следующим образом:

 div p {
    красный цвет;
}
 

До сих пор мы не могли выбрать тегов div , в которых было тегов p , и это означало, что нам пришлось прибегнуть к Javascript. Основная причина, по которой это не было реализовано в CSS, заключается в том, что это довольно дорогая операция. CSS относительно быстро анализируется, но выбор родительских тегов требует значительно большего объема обработки.

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

 /* Цвет элемента div: красный; */
div: имеет (р) {
    красный цвет;
}
 

Это сделает любой div с потомком p красным.

Объединение родительского выбора с другими селекторами

Как и любой другой селектор CSS, мы можем комбинировать его для определенных обстоятельств. Например, если вы хотите выбрать только теги div , которые имеют прямые span дочерние элементы:

 div:has(> span) {
    красный цвет;
}
 

Как следует из словаря :has , он не ограничивается только родительским выбором. Например, ниже мы можем выбрать диапазон , который :has родственный div :

 span:has(+ div) {
    красный цвет;
}
 

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

 div:not(:has(p)) {
    красный цвет;
}
 

Выбор элементов, содержащих только текст в CSS

Одна очень распространенная проблема в CSS заключается в том, что тег :empty не выбирает элементы, содержащие какой-либо текст, поэтому иногда элемент может содержать один пробел, и :empty будет не применять. Селектор :has дает нам возможность выбирать элементы, которые содержат только текстовые узлы и не содержат других дочерних элементов.

Хотя это не идеальное решение для простых :пустых элементов с пробелами (поскольку это выберет любой элемент только с текстом и без дополнительных элементов DOM HTML) — это дает нам возможность выбирать элементы DOM только с текстовыми узлами. , что раньше было невозможно. Мы можем добиться этого с помощью следующего кода:

 div:not(:has(*)) {
    фон: зеленый;
}
 

Заключение

С добавлением поддержки селектора :has() в Chrome 105 родительский выбор быстро становится реальностью, которую мы скоро сможем использовать в реальных проектах. На данный момент с поддержкой Safari легко протестировать и посмотреть, как он будет работать в будущем. Это дает дополнительное преимущество, позволяя сократить использование решений Javascript для выбора родительских элементов, что довольно часто встречается во многих приложениях и продуктах.

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

Надеюсь, вам понравилась эта статья. Чтобы узнать больше о CSS, нажмите здесь.

Последнее обновление 1656765087561

Стиль родительского элемента на основе количества дочерних элементов с помощью CSS :has() — Bram.us

0009 селектор 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  ) {
…
} 
  • С помощью parent:has() мы можем выбрать родительский элемент , который соответствует определенному условию для своих дочерних элементов.
  • Передавая > в :has() , мы нацеливаемся на родительский элемент .0003 прямых детей.
  • 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 без указания n . Если этот дочерний элемент также является последним дочерним элементом, вы знаете, что в родительском элементе ровно 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
Автор: Брамус! Опубликовано в Исходное содержаниеМетки: CSS, селекторы

Брамус — веб-разработчик из Бельгии, работающий инженером по связям с разработчиками Chrome в Google.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *