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?

8 Answers 8

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'});
Sign up to request clarification or add additional context in comments.

5 Comments

Wouldn't the selector be "*:not(.classname) input"?
Ah, misread the question. Yes, it should - although the * is optional.
Ah, also, need to use direct descendant (a>b) rather than any descendant (a b) otherwise all inputs will match since there is likely to be a higher container without the class (like body).
You can do this with CSS in current browsers now -- see answer below.
Down-voted; if you can do it in jQuery you SHOULD do it in pure JavaScript without dumping 70KB worth of extra bandwidth that has to be handled.
32

Mozilla supports negation pseudo-class:

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

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

4 Comments

ie9+ support this too.
also chrome, safari, and opera, scroll down and read more answers if you dont believe me ;P
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
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.
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>

3 Comments

Now supported in released versions of all major browsers. (Automated test available if you want to double-check that :not() is supported.)
Perhaps also worth adding that you can chain them together: div:not(#foo):not(#bar)
FWIW I've put a simple negative selector demo at simpl.info/cssnegativeselector.
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; }

3 Comments

That's exactly what I try to find a workaround for because it's not just the background that is changed...
Override each of the options in the .classname input rule.
you try ".classname input { background-color: white ! important; }" ??
10

I would do this

input { /* styles outside of .classname */ }
.classname input { /* styles inside of .classname, overriding above */ }

Comments

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.

Comments

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
}

Comments

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)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.