Gil Epshtain
Gil Epshtain

Reputation: 9801

CSS Selector - first element with Class in a group of same class

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.

Note

I don't believe this is a duplicate of "CSS selector for first element with class".

Upvotes: 3

Views: 15826

Answers (3)

Dotista
Dotista

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

ffflabs
ffflabs

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

Yousaf
Yousaf

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

Related Questions