Cookie Consent by Free Privacy Policy Generator ๐Ÿ“Œ :has(): the family selector

๐Ÿ  Team IT Security News

TSecurity.de ist eine Online-Plattform, die sich auf die Bereitstellung von Informationen,alle 15 Minuten neuste Nachrichten, Bildungsressourcen und Dienstleistungen rund um das Thema IT-Sicherheit spezialisiert hat.
Ob es sich um aktuelle Nachrichten, Fachartikel, Blogbeitrรคge, Webinare, Tutorials, oder Tipps & Tricks handelt, TSecurity.de bietet seinen Nutzern einen umfassenden รœberblick รผber die wichtigsten Aspekte der IT-Sicherheit in einer sich stรคndig verรคndernden digitalen Welt.

16.12.2023 - TIP: Wer den Cookie Consent Banner akzeptiert, kann z.B. von Englisch nach Deutsch รผbersetzen, erst Englisch auswรคhlen dann wieder Deutsch!

Google Android Playstore Download Button fรผr Team IT Security



๐Ÿ“š :has(): the family selector


๐Ÿ’ก Newskategorie: Programmierung
๐Ÿ”— Quelle: developer.chrome.com

Since time began (In CSS terms), we've worked with a cascade in various senses. Our styles compose a "Cascading Style Sheet". And our selectors cascade too. They can go sideways. In most cases they go downwards. But never upwards. For years, we've fantasized about a "Parent selector". And now it's finally coming! In the shape of a :has() pseudo selector.

The :has() CSS pseudo-class represents an element if any of the selectors passed as parameters match at least one element.

But, it's more than a "parent" selector. That's a nice way to market it. The not so appealing way might be the "conditional environment" selector. But that doesn't have quite the same ring to it. How about the "family" selector?

Browser Support

Before we go any further, it's worth mentioning browser support. It's not quite there yet. But, it's getting closer. No Firefox support yet, itโ€™s on the roadmap. But it's already in Safari and due for release in Chromium 105. All the demos in this article will tell you if they aren't supported in the browser used.

How to use :has

So what does it look like? Consider the following HTML with two sibling elements with the class everybody. How would you select the one that has a descendant with the class a-good-time?

<div class="everybody">
<div>
<div class="a-good-time"></div>
</div>
</div>

<div class="everybody"></div>

With :has(), you can do that with the following CSS.

.everybody:has(.a-good-time) {
animation: party 21600s forwards;
}

This selects the first instance of .everybody and applies an animation.

In this example, the element with the class everybody is the target. The condition is having a descendant with the class a-good-time.

<target>:has(<condition>) { <styles> }

But, you can take it much further than that because :has() opens up a lot of opportunities. Even ones likely not discovered yet. Consider some of these.

Select figure elements that have a direct figcaption.

figure:has(> figcaption) { ... }

Select anchors that donโ€™t have a direct SVG descendant

a:not(:has(> svg)) { ... }

Select labels that have a direct input sibling. Going sideways!

label:has(+ input) { โ€ฆ }

Select articles where a descendant img doesnโ€™t have alt text

article:has(img:not([alt])) { โ€ฆ }

Select the documentElement where some state is present in the DOM

:root:has(.menu-toggle[aria-pressed=โ€trueโ€]) { โ€ฆ }

Select the layout container with an odd number of children

.container:has(> .container__item:last-of-type:nth-of-type(odd)) { ... }

Select all items in a grid that are not hovered

.grid:has(.grid__item:hover) .grid__item:not(:hover) { ... }

Select every solo a within a paragraph that has a direct sibling hr element

p:has(+ hr) a:only-child { โ€ฆ }

Select an article where multiple conditions are met

article:has(>h1):has(>h2) { โ€ฆ }

Mix that up. Select an article where a title is followed by a subtitle

article:has(> h1 + h2) { โ€ฆ }

Select the :root when interactive states are triggered

:root:has(a:hover) { โ€ฆ }

Select the paragraph that follows a figure that doesnโ€™t have a figcaption

figure:not(:has(figcaption)) + p { โ€ฆ }

What interesting use cases can you think of for :has()? The fascinating thing here is that has encourages you to break your mental model. It makes you think "Could I approach these styles in a different way?".

Examples

Let's go through some examples of how we could use it.

Cards

Take a classic card demo. We could display any information in our card, for example: a title, subtitle, or some media. Here's the basic card.

<li class="card">
<h2 class="card__title">
<a href="#">Some Awesome Article</a>
</h2>
<p class="card__blurb">Here's a description for this awesome article.</p>
<small class="card__author">Chrome DevRel</small>
</li>

What happens when you want to introduce some media? For this design the card could split into two columns. Before, you might create a new class to represent this behavior, for example card--with-media or card--two-columns. These class names not only become hard to conjure up, but also become hard to maintain and remember.

With :has(), you can detect that the card has some media and do the appropriate thing. No need for modifier class names.

<li class="card">
<h2 class="card__title">
<a href="/article.html">Some Awesome Article</a>
</h2>
<p class="card__blurb">Here's a description for this awesome article.</p>
<small class="card__author">Chrome DevRel</small>
<img
class="card__media"
alt=""
width="400"
height="400"
src="./team-awesome.png"
/>

</li>

And you don't need to leave it there. You could get creative with it. How might a card showing โ€œfeaturedโ€ content adapt within a layout? This CSS would make a featured card the full width of the layout and place it at the start of a grid.

.card:has(.card__banner) {
grid-row: 1;
grid-column: 1 / -1;
max-inline-size: 100%;
grid-template-columns: 1fr 1fr;
border-left-width: var(--size-4);
}

What if a featured card with a banner wiggles for attention?

<li class="card">
<h2 class="card__title">
<a href="#">Some Awesome Article</a>
</h2>
<p class="card__blurb">Here's a description for this awesome article.</p>
<small class="card__author">Chrome DevRel</small>
<img
class="card__media"
alt=""
width="400"
height="400"
src="./team-awesome.png"
/>

<div class="card__banner"></div>
</li>
.card:has(.card__banner) {
--color: var(--green-3-hsl);
animation: wiggle 6s infinite;
}

So many possibilities.

Forms

How about forms? They're known for being tricky to style. One such example of this is styling inputs and their labels. How do we signal that a field is valid for example? With :has(), this gets much easier. We can hook into the relevant form pseudo-classes, for example :valid and :invalid.

<div class="form-group">
<label for="email" class="form-label">Email</label>
<input
required
type="email"
id="email"
class="form-input"
pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$"
title="Enter valid email address"
placeholder="Enter valid email address"
/>

</div
label {
color: var(--color);
}
input {
border: 4px solid var(--color);
}

.form-group:has(:invalid) {
--color: var(--invalid);
}

.form-group:has(:focus) {
--color: var(--focus);
}

.form-group:has(:valid) {
--color: var(--valid);
}

.form-group:has(:placeholder-shown) {
--color: var(--blur);
}

Try it out in this example: Try entering valid and invalid values and taking the focus on and off.

You could also use :has() to show and hide the error message for a field. Take our โ€œemailโ€ field group and add an error message to it.

<div class="form-group">
<label for="email" class="form-label">
Email
</label>
<div class="form-group__input">
<input
required
type="email"
id="email"
class="form-input"
pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$"
title="Enter valid email address"
placeholder="Enter valid email address"
/>

<div class="form-group__error">Enter a valid email address</div>
</div>
</div>

By default, you hide the error message.

.form-group__error {
display: none;
}

But when the field becomes :invalid and isnโ€™t focussed, you can show the message without the need for extra class names.

.form-group:has(:invalid:not(:focus)) .form-group__error {
display: block;
}

No reason you couldn't add a tasteful dash of whimsy for when your users interact with your form. Consider this example. Watch when you enter a valid value for the micro-interaction. An :invalid value will cause the form group to shake. But, only if the user has no motion preferences.

Content

We touched upon this in the code examples. But, how could you use :has() in your document flow? It throws up ideas about how we could style typography around media for example.

figure:not(:has(figcaption)) {
float: left;
margin: var(--size-fluid-2) var(--size-fluid-2) var(--size-fluid-2) 0;
}

figure:has(figcaption) {
width: 100%;
margin: var(--size-fluid-4) 0;
}

figure:has(figcaption) img {
width: 100%;
}

This example contains figures. When they have no figcaption, they float within the content. When a figcaption is present, they occupy full width and get extra margin.

Reacting to State

How about making your styles reactive to some state in our markup. Consider an example with the "classic" sliding nav bar. If you have a button that toggles opening the nav, it may use the aria-expanded attribute. JavaScript could be used to update the appropriate attributes. When aria-expanded is true, use :has() to detect this and update the styles for the sliding nav. JavaScript does its part and CSS can do what it wants with that information. No need to shuffle the markup around or add extra class names, etc. (Note: This isnโ€™t a production ready example).

:root:has([aria-expanded="true"]) {
--open: 1;
}
body {
transform: translateX(calc(var(--open, 0) * -200px));
}

We aren't adding a "Light dismiss" for the menu here. This would need implementing. But, with popup, we will get features like this for free. Check this demo out in Chrome Canary to see how the new "popup" attribute could help simplify things.

Can :has help to avoid user error?

What do all these examples have in common? Aside from the fact they show ways to use :has(), none of them required modifying class names. They each inserted new content and updated an attribute. This is a great benefit of :has(), in that it can help mitigate user error. With :has() CSS is able to take on the responsibility of adjusting to modifications in the DOM. You don't need to juggle class names in JavaScript, creating less potential for developer error. We've all been there when we typo a class name and have to resort to keeping them in Object lookups.

It's an interesting thought and does it lead us towards cleaner markup and less code? Less JavaScript as we aren't doing as many JavaScript adjustments. Less HTML as you no longer need classes like card card--has-media, etc.

Thinking outside the box

As mentioned above, :has() encourages you to break the mental model. It's an opportunity to try different things. One such way to try and push the boundaries is by making game mechanics with CSS alone. You could create a step based mechanic with forms and CSS for example.

<div class="step">
<label for="step--1">1</label>
<input id="step--1" type="checkbox" />
</div>
<div class="step">
<label for="step--2">2</label>
<input id="step--2" type="checkbox" />
</div>
.step:has(:checked), .step:first-of-type:has(:checked) {
--hue: 10;
opacity: 0.2;
}


.step:has(:checked) + .step:not(.step:has(:checked)) {
--hue: 210;
opacity: 1;
}

And that opens up interesting possibilities. You could use that to traverse a form with transforms. Note, this demo is best viewed in a separate browser tab.

And for fun, how about the classic buzz wire game? The mechanic is easier to create with :has(). If the wire gets hovered over, the game is over. Yes, we can create some of these game mechanics with things like the sibling combinators (+ and ~). But, :has() is a way to achieve those same results without having to use interesting markup "tricks". Note, this demo is best viewed in a separate browser tab.

Although you wonโ€™t be dropping these into production any time soon, they highlight ways in which you can use the primitive. Such as being able to chain a :has().

:root:has(#start:checked):has(.game__success:hover, .screen--win:hover)
.screen--win
{
--display-win: 1;
}

These examples show some interesting things enabled by :has(). However, any new feature of the platform needs careful assessment in terms of potential accessibility issues, especially where interaction is concerned.

Performance and limitations

Before we go, what can't you do with :has()? There are some restrictions with :has(). The main ones arise due to the performance hits.

  • You can't :has() a :has(). But you can chain a :has().
:has(.a:has(.b)) { โ€ฆ }
  • No pseudo element usage within :has()
:has(::after) { โ€ฆ }
:has(::first-letter) { โ€ฆ }
  • Restrict use of :has() inside pseudos accepting only compound selectors
::slotted(:has(.a)) { โ€ฆ }
:host(:has(.a)) { โ€ฆ }
:host-context(:has(.a)) { โ€ฆ }
::cue(:has(.a)) { โ€ฆ }
  • Restrict use of :has() after pseudo element
 ::part(foo):has(:focus) { โ€ฆ }
  • Use of :visited will always be false
:has(:visited) { โ€ฆ }

For actual performance metrics related to :has(), check out this Glitch. Credit to Byungwoo for sharing these insights and details around the implementation.

Thatโ€™s it!

Get ready for :has(). Tell your friends about it and share this post, itโ€™s going to be a game changer for how we approach CSS.

All the demos are available in this CodePen colllection.

...



๐Ÿ“Œ How to Increase CSS Class Selector Specificity to Beat the ID Selector Without Using Important


๐Ÿ“ˆ 45 Punkte

๐Ÿ“Œ :has(): the family selector


๐Ÿ“ˆ 39.21 Punkte

๐Ÿ“Œ :has(): the family selector


๐Ÿ“ˆ 39.21 Punkte

๐Ÿ“Œ Level Up Your CSS Skills With The :has() Selector


๐Ÿ“ˆ 28.66 Punkte

๐Ÿ“Œ Has() selector #shorts


๐Ÿ“ˆ 28.66 Punkte

๐Ÿ“Œ How to Use the :has() Selector in CSS


๐Ÿ“ˆ 28.66 Punkte

๐Ÿ“Œ Unleash the Power of CSS :has() Selector: A Game-Changer for Styling Your Web Content


๐Ÿ“ˆ 28.66 Punkte

๐Ÿ“Œ My X session selector has learned new tricks with version 0.3, including starting of Wayland sessions.


๐Ÿ“ˆ 28.66 Punkte

๐Ÿ“Œ An Introduction to the :has() Selector in CSS


๐Ÿ“ˆ 28.66 Punkte

๐Ÿ“Œ Using :has as a previous sibling selector


๐Ÿ“ˆ 28.66 Punkte

๐Ÿ“Œ Time Travel Is Easy With A Time Zone Selector Button


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ Use the :lang pseudo-class over the lang attribute selector for language-specific styles


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ Apache Allura up to 1.10.x Dropdown Selector Stored cross site scripting


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ CVE-2022-21802 | grapesjs up to 0.19.4 Selector Manager cross site scripting (ID 4411)


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ We're fixing issues related to alt-php82 and PHP Selector


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ How to get full CSS selector path?


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ Cisco Gss 4492r Global Site Selector up to 3.0 Crash denial of service


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ Cisco Gss 4492r Global Site Selector up to 3.0 Crash denial of service


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ Ethereal up to 0.10.2 Presentation Protocol Selector Crash denial of service


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ I've slightly improved my X session selector (0.2), and I require more feedback.


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ Help with Gnome Workspaces in Wayland - where did my workspace selector go?


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ Explain advance selector used in Jquery?


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ Complete CSS Selector Cheat Sheet: A Hands-On Guide with images๐Ÿ˜


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ Nextcloud: Authentication bypass in Global Site Selector allows an attacker to log in as any user


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ Adminer With Custom Login Servers Selector Plugin Run In Docker


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ How Tesla's Bizarre Swipe-To-Drive Gear Selector Works


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ wallpaper selector in rofi


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ VoicePicker 1.4.0 - System-voice selector.


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ CVE-2024-22212 | NextCloud Global Site Selector up to 1.4.0/2.1.1/2.3.3/2.4.4 authentication bypass (GHSA-vj5q-f63m-wp77)


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ CVE-2015-2793 | Ikiwiki prior 3.20150329 openid-selector.tmpl openid_identifier cross site scripting (Nessus ID 83209 / ID 867773)


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ Mastering Adaptive Flutter Themes: Crafting a Responsive Theme Selector Page


๐Ÿ“ˆ 22.5 Punkte

๐Ÿ“Œ Spotify Premium,Family Member,Family Owner,Free x300


๐Ÿ“ˆ 21.1 Punkte

๐Ÿ“Œ Your Family Entertainment AG: Die Your Family Entertainment AG stellt innovative Partner-Plattform im neuen Internet ...


๐Ÿ“ˆ 21.1 Punkte

๐Ÿ“Œ Apple's credit card gets a family plan with new Apple Card Family program


๐Ÿ“ˆ 21.1 Punkte

๐Ÿ“Œ The Libertinus font family. What do you think about the Libertinus font family?


๐Ÿ“ˆ 21.1 Punkte











matomo