73

Is there some kind of "not" CSS selector?

For example when I write the following line in my CSS, all input fields inside an tag with class classname will have a red background.

.classname input {
  background: red;
}

How do I select all input fields that are OUTSIDE of a tag with class classname?

saulotoledo
  • 1,737
  • 3
  • 19
  • 36
BlaM
  • 28,465
  • 32
  • 91
  • 105

8 Answers8

53


With current browser CSS support, you can't.

Newer browsers now support it- see Sam's answer for more info.

(See other answers for the alternatives in CSS.)


If doing it in JavaScript/jQuery is acceptable, you can do:

$j(':not(.classname)>input').css({background:'red'});
Community
  • 1
  • 1
Peter Boughton
  • 110,170
  • 32
  • 120
  • 176
32

Mozilla supports negation pseudo-class:

:not(.classname) input {background: red;}

See also: http://developer.mozilla.org/en/Mozilla_CSS_support_chart

Sotiris
  • 38,986
  • 11
  • 53
  • 85
ultracrepidarian
  • 1,080
  • 11
  • 18
  • 1
    ie9+ support this too. – chovy Nov 13 '13 at 23:27
  • also chrome, safari, and opera, scroll down and read more answers if you dont believe me ;P – Rooster Jul 17 '15 at 16:18
  • Oh, I believe you. I just never bothered to come back and expand on my answer that I provided exactly 6 years and 1 week ago. :D – ultracrepidarian Jul 17 '15 at 19:31
  • Thanks for this. Just to add to your answer.... I wanted to add styles to all a tags which were descendants of my header, except for an a tag with class (.no_in_cart) so with your solution I tried: #headernav li :not(.no_in_cart) a{background: red;} which did not work so I tried this #headernav li a:not(.no_in_cart){background: red;} which did work. – Sarah Jul 30 '15 at 09:26
31

Note that the negation pseudo class is in the Selectors Level 3 Recommendation and works in recent versions of Firefox, Chrome and Safari (at least). Sample code below.

<html>
<head>
<title>Negation pseudo class</title>
<style type="text/css">
    div {
    border: 1px solid green;
    height: 10px;
    }
    div:not(#foo) {
    border: 1px solid red;
    }
</style>
</head>
<body>
    <div id="foo"></div>
    <div id="bar"></div>
    <div id="foobar"></div>
</body>
</html>
Sam Dutton
  • 14,775
  • 6
  • 54
  • 64
  • 5
    [Now supported](http://caniuse.com/#feat=css-sel3) in released versions of all major browsers. ([Automated test](http://www.css3.info/selectors-test/) available if you want to double-check that `:not()` is supported.) – Dan Cecile May 08 '12 at 13:27
  • 2
    Perhaps also worth adding that you can chain them together: `div:not(#foo):not(#bar)` – Daz Aug 21 '13 at 13:35
  • FWIW I've put a simple negative selector demo at http://simpl.info/cssnegativeselector. – Sam Dutton Sep 03 '13 at 10:50
24

Wouldn't you do that by setting the 'global' background to red, then using the classname to alter the others?

input { background: red; }
.classname input { background: white; }
Harper Shelby
  • 16,475
  • 2
  • 44
  • 51
10

I would do this

input { /* styles outside of .classname */ }
.classname input { /* styles inside of .classname, overriding above */ }
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
1

There is no way to select the parent of matched elements with CSS. You would have to use JavaScript to select them.

From your question I assume you have markup that looks more or less like this:

<form class="formclassname">
    <div class="classname">
        <input />  <!-- Your rule matches this -->
        <input />  <!-- Your rule matches this -->
    </div>
    <input />  <!-- You want to select this? -->
    <input />  <!-- You want to select this? -->
</form>

One option is to add a class to a higher element, say the <form>, and write a rule to style all of the inputs of the form. I.E:

.formclassname input {
  /* Some properties here... */
}

Or

.formclassname > input {
  /* Some properties here... */
}

If you want to select them based on the fact that they are not inside of an element with a specific class, you're out of luck without the use of JavaScript.

Zack The Human
  • 8,373
  • 7
  • 39
  • 60
0

I think the closest you can get is to only affect direct descendants with a declaration

This code for example will only affect input fields directly under divs with class "maincontent"

div.maincontent > input {
  // do something
}
Dan Roberts
  • 4,664
  • 3
  • 34
  • 43
0

Inputs are a bit annoying because, unlike most other html elements, there isn't necessarily a way of resetting all the css properties back to their default value.

If the styling is non-critical (ie a nice to have but doesn't affect functionality) I would use jQuery to get an array of all the inputs, check their parents, and then only carry out the styling on those outside that div. Something like:

$('input').each(function() {
     if($(this).closest('.classname') == false)
     {
           // apply css styles
     }
});

(By the way, I'm no jQuery expert, so there might be some errors in the above, but in principle something like this should work)

wheresrhys
  • 22,558
  • 19
  • 94
  • 162