Using CSS only, I would like to select the last 4 elements, but only when any of them has the "selected" class.
In the snippet you can see in the second row how i’d like it to work.
let sel=0;
setTimeout(setSelected, 1000);
function setSelected() {
document.getElementById("d"+sel).classList.remove("selected");
document.getElementById("j"+sel).classList.remove("selected");
if (++sel>5) sel = 0;
document.getElementById("d"+sel).classList.add("selected");
// This is only to show what i would like to get with CSS selectors
document.getElementById("j"+sel).classList.add("selected");
if (sel>=3) {
document.getElementById("j3").classList.add("active");
document.getElementById("j4").classList.add("active");
document.getElementById("j5").classList.add("active");
}else{
document.getElementById("j3").classList.remove("active");
document.getElementById("j4").classList.remove("active");
document.getElementById("j5").classList.remove("active");
}
setTimeout(setSelected, 1000);
}
.container {text-align: center;}
.normal, .example {
display: inline-block;
width: 3rem;
color: white;
background-color: #004;
text-align: center;
border: 2px solid transparent;
}
.normal:last-of-type,
.normal:nth-last-of-type(2),
.normal:nth-last-of-type(3)
{
background-color: #A00;
}
.selected{
background-color: #0A0;
border: 2px solid #0A0;
}
.active{background-color: #A00;}
<p>CSS Only</p>
<div class="container">
<div id="d0" class="normal selected">0</div>
<div id="d1" class="normal">1</div>
<div id="d2" class="normal">2</div>
<div id="d3" class="normal">3</div>
<div id="d4" class="normal">4</div>
<div id="d5" class="normal">5</div>
</div>
<p>example with Javascript</p>
<div class="container">
<div id="j0" class="example selected">0</div>
<div id="j1" class="example">1</div>
<div id="j2" class="example">2</div>
<div id="j3" class="example">3</div>
<div id="j4" class="example">4</div>
<div id="j5" class="example">5</div>
</div>
I started by selection the last of them:
.normal:last-of-type,
.normal:nth-last-of-type(2),
.normal:nth-last-of-type(3)
{
background-color: #A00;
}
but then i wasn’t able to go further; by reading the description of CSS :has() i have the impression that a clever combination of it and nth-last-of-type()
could get me there, but i can’t figure out how should that "stack" of selectors be built.
Is it possible, using only CSS, to conditionally select the last 3 items only if one of them has the "selected" class?
If yes, how?
-EDIT-
Since the question was close ’cause seems to be a duplicate of Can I combine :nth-child() or :nth-of-type() with an arbitrary selector? :
My problem is that i need to select ALL of the last three divs when only one of them match an arbitrary selector, while in the linked question all of the selected elements matches the selector.
Trying to say it in another way, i need to select the elements 3, 4 and 5 when either 3 or 4 or 5 has the "selected" class.
2
Answers
You can try
.container:has(.selected:nth-last-of-type(-n + 3)) > :nth-last-of-type(-n + 3)
. When the container has an element with.selected
and that element is one of the last 3, select the last 3It can be done with a combination of
nth-last-of-type()
and:has
.