Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selector for element having one of two classes, but not both

How can I select elements having one of two classes, but not both?

I tried :not(.class1, .class2) and :not(.class1):not(.class2) but they seem to select elements missing either class. I need to select elements that don't have both classes.

I also tried :not([class='class1 class2']) as this accepted answer states, but it doesn't seem to select anything.

Here is a sample of what I want -

ul.tabs > li.active:not([class='first last']) {
    background-color: #F00;
}
<ul class="tabs">
    <li class="first">1st</li>
    <li class="active last">2nd</li> <!-- Should be red -->
</ul>

<ul class="tabs">
    <li class="active first last">1st</li> <!-- Should NOT be red -->
</ul>

The <li>'s have other classes I'm not responsible over. I'm wondering if there is a way of ignoring other classes for the last selector I tried.

like image 708
Arthur Rey Avatar asked Jan 24 '26 13:01

Arthur Rey


2 Answers

You want :not(.first), :not(.last) which is the Selectors level 3-supported version of :not(.first.last) (from Selectors 4, not yet supported by all browsers, as well as jQuery):

ul.tabs > li.active:not(.first), ul.tabs > li.active:not(.last) {
    background-color: #F00;
}
<ul class="tabs">
    <li class="first">1st</li>
    <li class="active last">2nd</li>
</ul>

<ul class="tabs">
    <li class="active first last">1st</li>
</ul>

As Rounin points out, though, you should be able to just use :first-of-type and :last-of-type, or :first-child and :last-child, instead of bloating the markup with with "first" and "last" classes (if those classes represent the same things as the pseudo-classes).

In fact, if you do switch to those pseudo-classes, you can simplify your CSS to just one selector by condensing :not(:first-of-type), :not(:last-of-type) to :not(:only-of-type):

ul.tabs > li.active:not(:only-of-type) {
    background-color: #F00;
}
<ul class="tabs">
    <li>1st</li>
    <li class="active">2nd</li>
</ul>

<ul class="tabs">
    <li class="active">1st</li>
</ul>
like image 150
BoltClock Avatar answered Jan 27 '26 03:01

BoltClock


In this situation, you can use two CSS pseudo-classes:

  • :first-of-type
  • :last-of-type

and take advantage of the CSS cascade, by declaring the rule for :first-of-type beneath the rule for :last-of-type.

Working Example:

.tabs li:last-of-type.active {background-color: rgb(255, 0, 0);}
.tabs li:first-of-type.active {background-color: transparent;}
<ul class="tabs">
<li>1st</li>
<li class="active">2nd</li> <!-- Should be red -->
</ul>

<ul class="tabs">
<li class="active">1st</li> <!-- Should NOT be red -->
</ul>
like image 24
Rounin - Glory to UKRAINE Avatar answered Jan 27 '26 02:01

Rounin - Glory to UKRAINE