Reputation: 9801
I have a list of elements under the same container. some of them has class A, other has class B. I'm looking for a CSS selector to select the first A element in a group of A and the first B element in a group of B.
Example:
<style>
.A { background: red; }
.B { background: blue; }
</style>
<ul class="list">
<li class="item A">AAA</li><!-- I want to select this -->
<li class="item A">aaa</li>
<li class="item A">aaa</li>
<li class="item B">BBB</li><!-- I want to select this -->
<li class="item B">bbb</li>
<li class="item B">bbb</li>
<li class="item A">AAA</li><!-- I want to select this -->
<li class="item A">aaa</li>
<li class="item A">aaa</li>
</ul>
Notice that using the pseudo selector :first-of-type
will not work, becuase it will select the first element of type without group relation.
Also trying to use :first-child
will not work ether, since it will select only the first A element, and will not select the first B element, also it will not select the first A element in the 2nd group.
I don't believe this is a duplicate of "CSS selector for first element with class".
Upvotes: 3
Views: 15826
Reputation: 431
The most elegant solution:
:nth-child(1 of div.item.A)
Doc: https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child#the_of_selector_syntax
Upvotes: 0
Reputation: 17481
In case you didn't know what's each class name (for example, when scraping) you could use JS to find groups that match your criteria:
let list = document.querySelector('.list');
let filtered = [...list.children].filter((item) => {
let previous = item.previousElementSibling;
return !previous || [...previous.classList].join('.') !== [...item.classList].join('.');
});
console.log(filtered);
.A {
background: red;
}
.B {
background: blue;
}
<ul class="list">
<li class="item A">First AAA</li>
<!-- I want to select this -->
<li class="item A">AAA</li>
<li class="item A">AAA</li>
<li class="item B">First BBB</li>
<!-- I want to select this -->
<li class="item B">BBB</li>
<li class="item B">BBB</li>
<li class="item A">Second AAA</li>
<!-- I want to select this -->
<li class="item A">AAA</li>
<li class="item A">AAA</li>
</ul>
You could also restrict your criteria to groups of elements that share their tagName.
Upvotes: 0
Reputation: 29282
To select first child of the ul
element, you can use :first-child
pseudo-class.
To select the first element in each group, you can use adjacent sibling selector.
.A + .B
will select any element with class B
that immediately follows an element with class A
. Similarly .B + .A
will select any element with class A
that immediately follows an element with class B
.A { background: red; }
.B { background: blue; }
.A:first-child,
.B + .A,
.A + .B {
background: yellow;
}
<ul class="list">
<li class="item A">AAA</li><!-- I want to select this -->
<li class="item A">AAA</li>
<li class="item A">AAA</li>
<li class="item B">BBB</li><!-- I want to select this -->
<li class="item B">BBB</li>
<li class="item B">BBB</li>
<li class="item A">AAA</li><!-- I want to select this -->
<li class="item A">AAA</li>
<li class="item A">AAA</li>
</ul>
Upvotes: 11