Not two classes css

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'])

:not(.class1):not(.class2) doesn’t work. It selects element missing at least one class, not both. Meaning in the first example the 2nd tab is not red. Why the downvotes?

I don’t know, I didn’t downvote, but now I’m a little confused. That li.active.last isn’t missing both classes — since it does have the «last» class. As stated, :not(.first):not(.last) will match elements that don’t have either class. But that’s simply not what you’re looking for.

3 Answers 3

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)

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)

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

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 .tabs li:first-of-type.active

How to use a CSS selector to select html elements with either one of two classes, but not both of the classes

Or how to do XOR in a CSS selector

Exclusive or is a logical operation that is true if and only if its arguments differ (one is true, the other is false).

XOR

Unfortunately there’s not an XOR operator in CSS which makes this a bit tricky. But we have both AND ant NOT, and those two together gets us NAND (NOT AND). The cool thing with NAND is that it is possible to combine NAND to express any Boolean expression!

So we need XOR which can be realized with NAND like this

XOR = ( A NAND ( A NAND B ) ) NAND ( B NAND ( A NAND B ) )

So lets say A = the CSS class first, and B = the CSS class last, then we get this:

li.active:not(:not(.first:not(.first.last)):not(.last:not(.first.last)))
  1. In CSS AND is realized by chaining two selectors together, so in order to get CSS version of first NAND last we do :not(.first.last)
  2. Next we need ( first NAND ( first NAND last ) ) which we get with :not(.first:not(.first.last)) , again chaining together first with the expression :not(.first.last) from point 1 above. This gives us the left part of the complete expression.
  3. The second and right part of the expression is almost identical to the left part

Источник

Can the :not() pseudo-class have multiple arguments?

I’m trying to select input elements of all type s except radio and checkbox . Many people have shown that you can put multiple arguments in :not , but using type doesn’t seem to work anyway I try it.

form input:not([type="radio"], [type="checkbox"]) < /* css here */ >

«Many people have shown that you can put multiple arguments in :not» Either those people were quoting a certain article that is popularly referenced but gravely misleading, or they were talking about jQuery, not CSS. Note that the given selector is in fact valid in jQuery, but not in CSS. I wrote a Q&A detailing the differences: stackoverflow.com/questions/10711730/… (the answer also mentions that article on the side)

Congratulations! You have successfully written valid CSS4.0 in your example above 2 years before the official edition came out.

@Jack Giffin: What «official edition» are you referring to? This question only pre-dates the FPWD of selectors-4 by 5 months, and the spec is still nowhere near completion: w3.org/TR/2011/WD-selectors4-20110929/#negation And it pre-dates the first implementation by 4 and a half years: stackoverflow.com/questions/35993727/…

According to MDN, the :not() selector with multiple arguments, is currently supported in FF84 and Safari9: developer.mozilla.org/en-US/docs/Web/CSS/:not#specifications

5 Answers 5

input:not([type="radio"]):not([type="checkbox"]) 

As a side note, if you do something like input:not(‘.c1’), input:not(‘c2’) you end up with an «and» situation where both classes would have to be on the input for it to match.

@Cloudkiller no that would select any input element -> «input without the class c1 OR input without the class c2»

If you’re using SASS in your project, I’ve built this mixin to make it work the way we all want it to:

@mixin not($ignorList. ) < //if only a single value given @if (length($ignorList) == 1)< //it is probably a list variable so set ignore list to the variable $ignorList: nth($ignorList,1); >//set up an empty $notOutput variable $notOutput: ''; //for each item in the list @each $not in $ignorList < //generate a :not([ignored_item]) segment for each item in the ignore list and put them back to back $notOutput: $notOutput + ':not(#)'; > //output the full :not() rule including all ignored items &#  < @content; >> 

Option 1: list the ignored items inline

Option 2: list the ignored items in a variable first

$ignoredItems: '[type="radio"]', '[type="checkbox"]' ; input < /*non-ignored styling goes here*/ @include not($ignoredItems)< /*ignored styling goes here*/ >> 

Outputted CSS for either option

input < /*non-ignored styling goes here*/ >input:not([type="radio"]):not([type="checkbox"]) < /*ignored styling goes here*/ >

What? so you would rather write .selector:not(.one):not(.two):not(.three):not(.four) < . >than .selector < @include not('.one','.two','.three','.four') < . >> ?

:not() = 6 characters per item; », = 3 characters per item. @include should be assigned to a hot key so I’m going to count that as one character (in terms of typing it). Technically I don’t think you even need to use the single quote marks in the list if you hate them that much. They do help prevent editors from freaking out though. Based on that, I still think my way is the more typing efficient way of writing it out.

@DaanHeskes also that writing out all the :not() cases doesn’t allow you to use a variable to list them.

Источник

CSS :not() with Multiple Classes

Say you want to select an element when it doesn’t have a certain class. That’s what the :not() selector is for.

But what if there are multiple classes you want to avoid? There are no logical combinators with :not() , like and or or , but you can chain them, which is effectively like and .

body:not(.home):not(.away):not(.page-50)

The :not() selector doesn’t add any specificy by itself, but what is inside does, so :not(.foo) adds the same weight as .foo does.

Psst! Create a DigitalOcean account and get $200 in free credit for cloud-based hosting and services.

Comments

Since this will be the same behaviour as chaining them, we can probably expect build tools to automatically convert between them in the future. Thanks for the info!

I think it goes without saying but having chained (:not)s just seems logically confusing. If 2 are checked for :not, then every class would be allowed. But there is clearly an additional layer of logic put into this pseudo class to make sure that a :not chain is self aware of the previous classes on the declaration. Oh well, good to know anyway!

You should also mention that with Selectors 4 spec (link) we can pass a selectors list inside the :not() function. Like :not(h1, h2, h3)

On first read, I found the and/or part a bit confusing, but this is basically using logical “and” to represent “or”: not(A or B) <=>not(A) and not(B). This also means that you can replace all “or” (represented in CSS by “,”) with a similar construct using “:not”: foo, bar < color: orange; >is (apart from specificity) equivalent to: :not(:not(foo):not(bar)) < color: orange; >Not sure if that is helpful in any context (where selector lists may not be allowed?).

If the tag is “body” and the class list does not include “home” and the class list does not include “away” and the class list does not include “page-50”, then …

Of course using the not yet widely available level 4 selectors ( body:not(.home, .away, .page-50) would be simpler:

Good grief, I hate to be the na sayer but Can I Use :not() sure kills any bright hopes for this. I fully expected IE11 to not support it (and I’ve got a bunch of those users) but even Edge, Chrome, and Firefox are not on board yet. This seems to be a Safari only selector…

To be clear, you’re ONLY talking about the fancy comma-separated :not(a, b, c) style. Regular :not(a):not(b):not(c) style is supported everywhere.

The CSS3 selector :not() is widely supported (including IE9+).
What is only supported by Saffari is the list argument, like :not(a, b, c).

You gave me a damn heart attack! That’s only for the selector list argument of :not(), which is the :not(.a, .b, .c) thing. Just straight up :not(.a) is fine, as is :not(.a):not(.b):not(.c)

That’s only for a list of multiple selectors, the basic implementation of :not() works across most browsers.

Being able to chain selectors within :not() is not fully supported but :not() itself is https://caniuse.com/#feat=mdn-css_selectors_not

I think you might be looking at selector list argument of :not() , which only works in Safari, yeah. But :not itself is part of the CSS3 selectors listing, which seems to be green across the board. So you can use :not() wherever, but we might have to hold off on using it with a list of selectors for now, like so:

I could see how this could be powerful, but I’m a little hesitant to start using this. Doesn’t this have the same dangers as using !important because you’re overriding the cascade? On the front page of CSS-Tricks I see this done with some a tags successfully (the site looks dayung good.) But I’m not sure I want to override things like this where selectors (and properties) are being overridden with frequency: a:not(.button):not(.commentPreviewButton):not(.comment-reply-link):focus, a:not(.button):not(.commentPreviewButton):not(.comment-reply-link):hover <
background: -webkit-gradient(linear,left top,right top,from(#ff8a00),to(#da1b60));
background: linear-gradient(to right,#ff8a00,#da1b60);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
-webkit-box-decoration-break: clone;
box-decoration-break: clone;
text-shadow: none;
> I guess I’d have to see the code, maybe it’s much simpler in their codebase?

I wasn’t even thinking of that particular code when writing this, but it makes a fairly good point. I don’t control the classes commentPreviewButton and comment-reply-link . They come from WordPress core or plugins. I could probably write filters to control them, but that’s technical debt at a level I’d rather not deal with. I’ll take my technical debt in a CSS selector, because of my personal skillset. That selector helps me to what I want to do, targeting most links, but avoiding a few specifically based on class name.

Yeah, I think I should take back in part what I said about !important- because it’s not an uncontrolled override. At least :not has you specify. The way it’s used here makes sense especially in environments where you don’t have control over some of the environment like WordPress like you said. But this probably is the exception more than the rule.

I encountered someone’s code that did not understand this concept in the wild — worse, in the Production code of a well-known CMS’s admin. The code was like this:

#some-id *, #some-id *:not(div), #some-id *:not(svg *)

…which is just insane. The first rule is not needed if the second rule is present. And the third rule just makes you wonder what this world is coming to. Please please be careful with the power that CSS gives you. Make sure you understand the rules before you apply them.

Источник

Оцените статью