views:

1566

answers:

7

Is there some kind of "negative" 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?

+1  A: 

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 Mulgrew
+15  A: 

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
That's exactly what I try to find a workaround for because it's not just the background that is changed...
BlaM
Override each of the options in the `.classname input` rule.
Daniel A. White
+7  A: 

I would do this

input { /* styles outside of .classname */ }
.classname input { /* styles inside of .classname, overriding above */ }
Daniel A. White
+7  A: 


With current browser CSS support, you can't.

(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'});
Peter Boughton
Wouldn't the selector be "*:not(.classname) input"?
Zack Mulgrew
Ah, misread the question. Yes, it should - although the * is optional.
Peter Boughton
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).
Peter Boughton
A: 

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
A: 

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
+1  A: 

Mozilla supports negation pseudo-class:

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

See also (sorry, I'm limited to one hyperlink max)

developer.mozilla.org/en/Mozilla_CSS_support_chart

nameanyone