Day 91: a previous sibling selector with :has()
source link: https://www.matuzo.at/blog/2023/100daysof-day91/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Day 91: a previous sibling selector with :has()
posted on January 30., 2023
It’s time to get me up to speed with modern CSS. There’s so much new in CSS that I know too little about. To change that I’ve started #100DaysOfMoreOrLessModernCSS. Why more or less modern CSS? Because some topics will be about cutting-edge features, while other stuff has been around for quite a while already, but I just have little to no experience with it.
I’ve already shown much appreciation for the :has()
pseudo-class in this series, but that we can use it as a previous sibling selector tops it all of.
Since this is not an official selector, but more something like a hack, it can be hard to read and interpret. So, let’s start nice and easy.
We have three buttons. If we hover/focus one button and we want to highlight it and the next adjacent button in the DOM at the same time, we can use the adjacent sibling selector.
button {
outline-width: 8px;
outline-offset: 4px;
outline-color: hotpink;
}
button:is(:hover, :focus-visible) {
outline-style: solid;
}
button:is(:hover, :focus-visible) + button {
outline-style: dashed;
}
There's no previous item selector, but using :has()
we can select an item that comes before another item. I've written about next-sibling combinators and :has()
on day 26. Here’s an example from that post: The following code sets the block-end margin of all <h2>
to 0 if they're followed by a <time>
element.
h2 {
margin-block-end: 0.7em;
}
h2:has(+ time) {
margin-block-end: 0;
}
<h2>Heading</h2>
<p>Teaser text</p>
<h2>Heading</h2>
<time>31.10.2022</time>
<p>Teaser text</p>
Heading
Teaser text
Heading
31.10.2022Teaser text
If we want to use this in our button example, we have to select a <button>
followed by a <button>
in the :hover
or :focus-visible
state.
button:is(:hover, :focus-visible) {
outline-style: solid;
}
button:is(:hover, :focus-visible) + button {
outline-style: dashed;
}
button:has(+ button:is(:hover, :focus-visible)) {
outline-style: dotted;
}
If we have more buttons and we want to select the button that comes before the previous button, we can extend our selector.
button:has(+ button + button:is(:hover, :focus-visible)) {
/* styles */
}
What a beauty!
Here are a couple of other demos:
Further reading
Want more?
Overview: 100 Days Of More Or Less Modern CSS
My blog doesn't support comments yet, but you can reply via e-mail.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK