Css element that has child

Css element that has child

Уникальный селектор, позволяющий стилизовать родителя при наличии конкретного ребёнка.

Время чтения: меньше 5 мин

Кратко

Скопировать ссылку «Кратко» Скопировано

Псевдокласс :has ( ) позволяет выбрать элемент, уточнив основной селектор дополнительным, и при этом не увеличив его «вес». В отличие от привычных селекторов, правило применится только к тому селектору, который был описан до :has ( ) .

Этот псевдокласс только в 2022 году начал получать поддержку современных браузеров. Пока он поддерживается не всеми браузерами. Следим за обновлениями.

Пример

Скопировать ссылку «Пример» Скопировано

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

 dt:has(+ dd)  /* Стили */> dt:has(+ dd)  /* Стили */ >      

В отличие от соседнего селектора + ( dt + dd ), будет выбран не второй элемент, а первый, т. е. :has ( ) позволяет буквально инвертировать селектор — правило применится не к последнему селектору, а к тому, который указан перед :has ( ) .

Как, например, найти такие ссылки, внутри которых есть изображения:

 a:has(img)  /* Стили */> a:has(img)  /* Стили */ >      

Как пишется

Скопировать ссылку «Как пишется» Скопировано

 selector1:has(selector2)  /* … */> selector1:has(selector2)  /* … */ >      

selector1 — необязательный селектор (если не указан — правило применится ко всем подходящим элементам). Аргумент selector2 в :has ( ) описывает селектор относительно своей точки отсчёта — selector1 .

Как понять

Скопировать ссылку «Как понять» Скопировано

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

Подсказки

Скопировать ссылку «Подсказки» Скопировано

💡 Использование :has ( ) не влияет на специфичность, т. е. при расчёте веса селектора учитывается только целевой селектор, к которому применяется этот псевдокласс.

На практике

Скопировать ссылку «На практике» Скопировано

Саша Патлух советует

Скопировать ссылку «Саша Патлух советует» Скопировано

🛠 Бывает, что контент какого-то блока вашей HTML-страницы генерируется из Markdown-разметки. Это особенно часто встречается на сайтах, созданных при помощи генераторов сайтов вроде 11ty. Вы не можете добавить в сгенерированный HTML-код классы, идентификаторы или дата-атрибуты. Псевдокласс :has ( ) может решить достаточно сложную ситуацию с непредвиденным появлением обёрток вокруг элементов.

Вот типовой кусок разметки Markdown:

 ## Цитаты Далай Ламы Люди были созданы для того, чтобы их любили,а вещи были созданы для того, чтобы ими пользовались.Мир в хаосе, потому что все наоборот. ![Фото Далай Ламы](https://yoursite.com/dalai-lama.jpg) Принимая решение, спрашивайте себя: «А сделает ли это меня счастливым?»Задавая этот вопрос всякий раз перед принятием решения,мы перемещаем свое внимание с того, в чем мы себе отказываем,на то, к чему мы стремимся. Далай Лама ## Цитаты Далай Ламы Люди были созданы для того, чтобы их любили, а вещи были созданы для того, чтобы ими пользовались. Мир в хаосе, потому что все наоборот. ![Фото Далай Ламы](https://yoursite.com/dalai-lama.jpg) Принимая решение, спрашивайте себя: «А сделает ли это меня счастливым?» Задавая этот вопрос всякий раз перед принятием решения, мы перемещаем свое внимание с того, в чем мы себе отказываем, на то, к чему мы стремимся. Далай Лама     

Эта разметка превратится в такой HTML (я поместил его внутрь секции — это похоже на реальное использование):

   

Цитаты Далай Ламы

Люди были созданы для того, чтобы их любили, а вещи были созданы для того, чтобы ими пользовались. Мир в хаосе, потому что все наоборот. src="https://yoursite.com/dalai-lama.jpg" alt="Фото Далай Ламы" > Принимая решение, спрашивайте себя: «А сделает ли это меня счастливым?» Задавая этот вопрос всякий раз перед принятием решения, мы перемещаем свое внимание с того, в чем мы себе отказываем, на то, к чему мы стремимся.

Далай Лама

section class="content"> h2>Цитаты Далай Ламыh2> p> Люди были созданы для того, чтобы их любили, а вещи были созданы для того, чтобы ими пользовались. Мир в хаосе, потому что все наоборот. p> p> img src="https://yoursite.com/dalai-lama.jpg" alt="Фото Далай Ламы" > p> p> Принимая решение, спрашивайте себя: «А сделает ли это меня счастливым?» Задавая этот вопрос всякий раз перед принятием решения, мы перемещаем свое внимание с того, в чем мы себе отказываем, на то, к чему мы стремимся. p> p>Далай Ламаp> section>

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

Выбираем абзац, следом за которым сразу идёт другой абзац с вложенным изображением:

 .content p:has(+ p > img)  display: inline-block; vertical-align: top;> .content p:has(+ p > img)  display: inline-block; vertical-align: top; >      

Если знаки + и > в селекторах вызывают недоумение, то почитайте статью о комбинированных селекторах.

Теперь выберем абзац с вложенным изображением:

 .content p:has(img)  display: inline-block; vertical-align: top; width: 300px;> .content p:has(img)  display: inline-block; vertical-align: top; width: 300px; >      

Подгоним изображение под ширину родителя:

 .content img  width: 100%;> .content img  width: 100%; >      

Realetive советует

Скопировать ссылку «Realetive советует» Скопировано

🛠 До появления псевдокласса :has ( ) единственной возможностью управлять проверкой вложенного селектора был JavaScript.

Источник

The CSS :has Selector (and 4+ Examples)

The CSS :has selector helps you select elements that contain elements that match the selector you pass into the :has() function. It’s essentially a “parent” selector, although far more useful than just that. For example, imagine being able to select all

s but only when they contain a

. That’s what we can do:

Although it’s not supported in any browser as I write, it has now dropped in Safari Technical Preview 137, so it’s starting to happen! Pretty darn handy right! Here’s another example. Say you want space after your headers. Of course! A bit of margin-block-end on your h2 should do it. But… what if there is a subtitle? Now we can select a parent on the condition a subtitle is present and adjust the spacing.

h2, .subtitle < margin: 0 0 1.5rem 0; >.header-group:has(h2):has(.subtitle) h2 < margin: 0 0 0.2rem 0; /* reduce spacing on header, because subtitle will handle it */ >/* 

Blog Post Title

Blog Post Title

This is a subtitle
*/

The CSS :has selector being helpful in spacing headers with subtitles (or not).

The way I think about :has is this: it’s a parent selector pseudo-class. That is CSS-speak for “it lets you change the parent element if it has a child or another element that follows it.” This might feel weird! It might break your mental model of how CSS works. This is how I’m used to thinking about CSS:

You can only style down, from parent to child, but never back up the tree. :has completely changes this because up until now there have been no parent selectors in CSS and there are some good reasons why. Because of the way in which browsers parse HTML and CSS, selecting the parent if certain conditions are met could lead to all sorts of performance concerns. If I sit down and think about all the ways I might use :has today, I sort of get a headache. It would open up this pandora’s box of opportunities that have never been possible with CSS alone. Another example: let’s say we want to only apply styles to links that have images in them:

This would be helpful from time to time. I can also see :has being used for conditionally adding margin and padding to elements depending on their content. That would be neat. The :has selector is part of the CSS Selectors Level 4 specification which is the same spec that has the extremely useful :not pseudo-class. You could argue that the CSS :has selector is more powerful than just a “parent” selector, which is exactly what Bramus has done! Like in the subheadings example above, you aren’t necessarily ultimately selecting the parent, you might select the parent in a has-condition, but then ultimately select a child element from there.

/* Matches elements that have a as a child element */ figure:has(figcaption) < … >/* Matches elements that is a child of a that contains a child element */ figure:has(figcaption) img

There you can quickly see that the second selector is selecting a child , not just the parent of the .

And the list is forgiving: The list is no longer “forgiving” after the W3C adopted a resolution in December 2020 in response to a reported issue. So, if the selector list contains even one invalid argument, the entire list is ignored:

/* 👎 */ article:has(h2, ul, ::-blahdeath) < /* ::blahdeath is invalid, making the entire selector invalid. */ >
/* 👍 */ article:has(:where(h2, ul, ::-blahdeath)) < /* :where is a forgiving selector, making this valid. */ >

The :not() selector is part of the same spec…

Unlike :has , :not does have pretty decent browser support and I used it for the first time the other day:

That’s great I also love how gosh darn readable it is; you don’t ever have to have seen this line of code to understand what it does. Another way you can use :not is for margins:

So every element that is not the last item gets a margin. This is useful if you have a bunch of elements in a card, like this:

CSS Selectors Level 4 is also the same spec that has the :is selector that can be used like this today in a lot of browsers:

:is(section, article, aside, nav) :is(h1, h2, h3, h4, h5, h6) < color: #BADA55; >/* . which would be the equivalent of: */ section h1, section h2, section h3, section h4, section h5, section h6, article h1, article h2, article h3, article h4, article h5, article h6, aside h1, aside h2, aside h3, aside h4, aside h5, aside h6, nav h1, nav h2, nav h3, nav h4, nav h5, nav h6

Источник

Использование CSS-селектора :has() на примерах

Обложка: Использование CSS-селектора :has() на примерах

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

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

Всё ещё не очень понятно, правда? Давайте обратимся к практическим примерам.

Как использовать CSS-селектор :has()?

Рассмотрим следующий HTML-код с двумя родственными элементами с классом everybody . Как бы вы выбрали тот, у которого есть потомок с классом a-good-time ?

С CSS-селектором :has() это можно реализовать следующим образом:

Это выбирает первый экземпляр .everybody и применяет к нему animation . В этом примере целью является элемент с классом everybody . Условием является наличие потомка с классом a-good-time .

Но :has() гораздо больше возможностей. Вот некоторые из них.

Выбрать anchor , которые не имеют прямого потомка SVG:

Выбрать label , у которых есть родственный input :

Выбрать documentElement , в котором некое состояние присутствует в DOM:

:root:has(.menu-toggle[aria-pressed=”true”])

Совместимость :has() с браузерами

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

Совместимость CSS-селектора :has() с браузерами

CSS-селектор :has() на практике

Это реализация без единой строчки на JavaScript. Для начала можете посмотреть и самостоятельно протестировать пример, который реализован в CodePen:

Теперь рассмотрим его подробнее. Итак, CSS-псевдокласс :hover срабатывает, когда пользователь наводит на элемент мышью, но при этом активировать его необязательно.

Senior/ Middle FrontEnd (React) Developer Центр HR TECH (Проект Атомкор) АО «Гринатом» , , можно удалённо , По итогам собеседования

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

Затем, чтобы применить это, нам нужны правила, которые обновляют пользовательское свойство —lerp для :hover или :focus для каждого элемента или блока. Код ниже предназначен для выбора пяти блоков с комбинацией родственных комбинаторов (+) и :has() .

:is(.block:hover, .block:focus-visible) < --lerp: var(--lerp-0); z-index: 5; >.block:has( + :is(.block:hover, .block:focus-visible)), :is(.block:hover, .block:focus-visible) + .block < --lerp: var(--lerp-1); z-index: 4; >.block:has( + .block + :is(.block:hover, .block:focus-visible)), :is(.block:hover, .block:focus-visible) + .block + .block < --lerp: var(--lerp-2); z-index: 3; >.block:has( + .block + .block + :is(.block:hover, .block:focus-visible)), :is(.block:hover, .block:focus-visible) + .block + .block + .block < --lerp: var(--lerp-3); z-index: 2; >.block:has( + .block + .block + .block + :is(.block:hover, .block:focus-visible)), :is(.block:hover, .block:focus-visible) + .block + .block + .block + .block

Последнее, что нужно сделать, это применить всё к самим блокам. Поскольку блоки выложены с помощью flexbox, можно использовать значение —lerp , чтобы изменить flex каждого блока, и translation для каждого элемента:

А вот сами значения —lerp сгенерированы с помощью утилиты GSAP для распределения значений с помощью сглаживающей кривой.

Источник

Читайте также:  Css свойства border radius
Оцените статью