Dev
Dev

Reputation: 385

Select list items with a certain class but only if they are the last in the group

Let's say there is a list that looks like this:

<ul class="list">
  <li class="item">Text</li>
  <li class="item unique">Text</li>
  <li class="item unique">Text</li> // <-- Should be selected
  <li class="item">Text</li>
  <li class="item unique">Text</li>
  <li class="item unique">Text</li>
  <li class="item unique">Text</li> // <-- Should be selected
  <li class="item">Text</li>
  <li class="item unique">Text</li> // <-- Should be selected
  <li class="item">Text</li> 
<ul>

I'm trying to find a way to select all the list items with the class unique, but only if this item is the last one in the group, meaning that all list items with the class unique that come before this item should not be selected.

Is there any way to achieve the desired behavior if the HTML structure cannot be changed?

Upvotes: 1

Views: 50

Answers (1)

John Li
John Li

Reputation: 7447

If :has can be used (not currently supported by Firefox), it could be:

.unique:has(+ :not(.unique)) {
  color: crimson;
}

More about :has()

Example: (not compatible with Firefox, IE, and older browsers)

@supports (selector(html:has(body))) {
  .unique:has(+ :not(.unique)) {
    color: crimson;
  }
}
<ul class="list">
  <li class="item">Text</li>
  <li class="item unique">Text</li>
  <li class="item unique">Text</li> // <-- Should be selected
  <li class="item">Text</li>
  <li class="item unique">Text</li>
  <li class="item unique">Text</li>
  <li class="item unique">Text</li> // <-- Should be selected
  <li class="item">Text</li>
  <li class="item unique">Text</li> // <-- Should be selected
  <li class="item">Text</li> 
<ul>

If :has is not an option, perhaps use some Javascript code for this as a fallback solution.

Example: (fallback solution with Javascript)

const items = document.querySelectorAll("li");

items.forEach((item, index, arr) => {
  if (!item.classList.contains("unique")) return;
  if (index < arr.length - 1 && arr[index + 1].classList.contains("unique"))
    return;
  item.classList.add("last");
});
.last {
  color: crimson;
}
<ul class="list">
  <li class="item">Text</li>
  <li class="item unique">Text</li>
  <li class="item unique">Text</li> // <-- Should be selected
  <li class="item">Text</li>
  <li class="item unique">Text</li>
  <li class="item unique">Text</li>
  <li class="item unique">Text</li> // <-- Should be selected
  <li class="item">Text</li>
  <li class="item unique">Text</li> // <-- Should be selected
  <li class="item">Text</li>
<ul>

Upvotes: 3

Related Questions