941

I would like to write a CSS selector rule that selects all elements that don't have a certain class. For example, given the following HTML:

<html class="printable">
    <body class="printable">
        <h1 class="printable">Example</h1>
        <nav>
            <!-- Some menu links... -->
        </nav>
        <a href="javascript:void(0)" onclick="javascript:self.print()">Print me!</a>
        <p class="printable">
            This page is super interresting and you should print it!
        </p>
    </body>
</html>

I would like to write a selector that selects all elements that don't have the "printable" class which, in this case, are the nav and a elements.

Is this possible?

NOTE: in the actual HTML where I would like to use this, there are going to be a lot more elements that don't have the "printable" class than do (I realize it's the other way around in the above example).

0

10 Answers 10

1278

Typically you add a class selector to the :not() pseudo-class like so:

:not(.printable) {
    /* Styles */
}

:not([attribute]) {
    /* Styles */
}

But if you need better browser support (IE8 and older don't support :not()), you're probably better off creating style rules for elements that do have the "printable" class. If even that isn't feasible despite what you say about your actual markup, you may have to work your markup around that limitation.

Keep in mind that, depending on the properties you're setting in this rule, some of them may either be inherited by descendants that are .printable, or otherwise affect them one way or another. For example, although display is not inherited, setting display: none on a :not(.printable) will prevent it and all of its descendants from displaying, since it removes the element and its subtree from layout completely. You can often get around this by using visibility: hidden instead which will allow visible descendants to show, but the hidden elements will still affect layout as they originally did. In short, just be careful.

9
  • 4
    As a little nugget of info, browser support for media-agnostic aspects of CSS is often the same across media types — if a browser doesn't support :not() on the screen, it won't support it in print either.
    – BoltClock
    Commented Feb 2, 2012 at 10:10
  • 44
    Note that :not() only takes a simple selector which means it can not contain nested selectors like :not(div .printable) - see W3C Selector syntax Commented Jul 8, 2016 at 10:04
  • 1
    I just tried it for .active a :not(.active a) did not work for me. But, a:not(.active) did! Commented Jun 7, 2018 at 22:39
  • When you say it did not work for you, you probably mean it did not work for you, right? It does not mean it does not work, it probably is a case of specificity -- the properties in your :not(.active) rule may have simply been overriden by properties in rule(s) with higher priority. Commented Jun 16, 2018 at 10:56
  • 2
    @Kilves: Are you sure about that? The specificity of :not() is that of its argument, which means :not(div) is equally specific to div, :not(.cls) to .cls and :not(#id) to #id.
    – BoltClock
    Commented Jan 10, 2019 at 11:24
242
:not([class])

Actually, this will select anything that does not have a css class (class="css-selector") applied to it.

I made a jsfiddle demo

    h2 {color:#fff}
    :not([class]) {color:red;background-color:blue}
    .fake-class {color:green}
    <h2 class="fake-class">fake-class will be green</h2>
    <h2 class="">empty class SHOULD be white</h2>
    <h2>no class should be red</h2>
    <h2 class="fake-clas2s">fake-class2 SHOULD be white</h2>
    <h2 class="">empty class2 SHOULD be white</h2>
    <h2>no class2 SHOULD be red</h2>

Is this supported? Yes : Caniuse.com (accessed 02 Jan 2020):

  • Support: 98.74%
  • Partial support: 0.1%
  • Total:98.84%

Funny edit, I was Googling for the opposite of :not. CSS negation?

selector[class]  /* the oposite of :not[]*/
0
138

The :not negation pseudo class

The negation CSS pseudo-class, :not(X), is a functional notation taking a simple selector X as an argument. It matches an element that is not represented by the argument. X must not contain another negation selector.

You can use :not to exclude any subset of matched elements, ordered as you would normal CSS selectors.


Simple example: excluding by class

div:not(.class)

Would select all div elements without the class .class

div:not(.class) {
  color: red;
}
<div>Make me red!</div>
<div class="class">...but not me...</div>


Complex example: excluding by type / hierarchy

:not(div) > div

Would select all div elements which arent children of another div

div {
  color: black
}
:not(div) > div {
  color: red;
}
<div>Make me red!</div>
<div>
  <div>...but not me...</div>
</div>


Complex example: chaining pseudo selectors

With the notable exception of not being able to chain/nest :not selectors and pseudo elements, you can use in conjunction with other pseudo selectors.

div {
  color: black
}
:not(:nth-child(2)){
  color: red;
}
<div>
  <div>Make me red!</div>
  <div>...but not me...</div>
</div>


Browser Support, etc.

:not is a CSS3 level selector, the main exception in terms of support is that it is IE9+

The spec also makes an interesting point:

the :not() pseudo allows useless selectors to be written. For instance :not(*|*), which represents no element at all, or foo:not(bar), which is equivalent to foo but with a higher specificity.

1
  • 1
    Ok, your example :not(div) > div would work with only direct parents. What about other grandfathers? Commented Dec 16, 2016 at 6:30
32

I think this should work:

:not(.printable)

From "negative css selector" answer.

12

Just like to contribute that the above answers of :not() can be very effective in angular forms, rather than creating effects or adjusting the view/DOM,

input.ng-invalid:not(.ng-pristine) { ... your css here i.e. border-color: red; ...}

Ensures that on loading your page, the input fields will only show the invalid (red borders or backgrounds, etc) if they have data added (i.e. no longer pristine) but are invalid.

10

Example

  [class*='section-']:not(.section-name) {
    @include opacity(0.6);
    // Write your css code here
  }

// Opacity 0.6 all "section-" but not "section-name"

8

If you want a specific class menu to have a specific CSS if missing class logged-in:

body:not(.logged-in) .menu  {
    display: none
}
5

Using the :not() pseudo class:

For selecting everything but a certain element (or elements). We can use the :not() CSS pseudo class. The :not() pseudo class requires a CSS selector as its argument. The selector will apply the styles to all the elements except for the elements which are specified as an argument.

Examples:

/* This query selects All div elements except for   */
div:not(.foo) {
  background-color: red;
}


/* Selects all hovered nav elements inside section element except
   for the nav elements which have the ID foo*/
section nav:hover:not(#foo) {
  background-color: red;
}


/* selects all li elements inside an ul which are not odd */
ul li:not(:nth-child(odd)) { 
  color: red;
}
<div>test</div>
<div class="foo">test</div>

<br>

<section>
  <nav id="foo">test</nav>
  <nav>Hover me!!!</nav>
</section>
<nav></nav>

<br>

<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ul>

We can already see the power of this pseudo class, it allows us to conveniently fine tune our selectors by excluding certain elements. Furthermore, this pseudo class increases the specificity of the selector. For example:

/* This selector has a higher specificity than the #foo below */
#foo:not(#bar) {
  color: red;
}

/* This selector is lower in the cascade but is overruled by the style above */
#foo {
  color: green;
}
<div id="foo">"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
  in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</div>

2

You can use :not(.class) selector as mentioned before.

If you care about Internet explorer compatibility I recommend you to use http://selectivizr.com/.

But remember to run it under apache otherwise you won't see the effect.

2
  • 3
    What do you mean run it under apache? Selectivizr is a front end lib, it has nothing to do with the server software
    – Kloar
    Commented Apr 11, 2014 at 10:30
  • It performs ajax request - that doesn't work without a http server. Commented Apr 15, 2014 at 21:25
1

As others said, you simply put :not(.class). For CSS selectors, I recommend visiting this link, it's been very helpful throughout my journey: https://code.tutsplus.com/tutorials/the-30-css-selectors-you-must-memorize--net-16048

div:not(.success) {
  color: red;
}

The negation pseudo class is particularly helpful. Let's say I want to select all divs, except for the one which has an id of container. The snippet above will handle that task perfectly.

Or, if I wanted to select every single element (not advised) except for paragraph tags, we could do:

*:not(p) {
  color: green;
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.