Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'If not' CSS Selectors

So this may be ambitious, but I'm trying to solve the following problem with CSS only:

.this-class[if-is-not-a-table], .this-class .something-else {      border: 1px solid red; } 

Basically, I'm trying to find a way to use advanced CSS selectors to only apply a style dependent on whether or not it is NOT something else. Like apply this but only if it's not on a table element. Is this possible?

NOTE: Also, this is for IE 8, so if this can be backwards compatible at all that'd be amazing!

like image 307
streetlight Avatar asked Jun 02 '14 15:06

streetlight


People also ask

Which is not CSS selector?

The :not(selector) selector is used to style every element that is not the specified by selector. Since it prevents specific items from being selected, it is also known as the negation pseudo-class. Example-1: html.

Is not a valid CSS selector?

The :invalid selector allows you to select <input> elements that do not contain valid content, as determined by its type attribute. :invalid is defined in the CSS Selectors Level 3 spec as a “validity pseudo-selector”, meaning it is used to style interactive elements based on an evaluation of user input.

Can I use not selector?

Selectors Level 3 only allowed :not() pseudo-class to accept a single simple selector, which the element must not match any of. Thus, :not(a, . b, [c]) or :not(a.b[c]) did not work. Selectors Level 4 allows :not() to accept a list of selectors.

Can you chain not CSS?

There are no logical combinators with :not() , like and or or , but you can chain them, which is effectively like and . The :not() selector doesn't add any specificy by itself, but what is inside does, so :not(.


2 Answers

You can use the :not() pseudo-class, but IE8 does not support it:

.this-class:not(table), .this-class .something-else {      border: 1px solid red; } 

Thankfully, getting it to work for IE8 is trivial — simply apply the style to any elements with .this-class, and override it for the ones that are tables instead:

.this-class, .this-class .something-else {      border: 1px solid red; }  table.this-class {     border: none; } 

Notice that the .this-class .something-else part of your first rule remains completely separate, matching descendants of .this-class regardless of what type of element it is. If that is intended, you can leave that portion unchanged. Otherwise, if you want the styles to apply to descendants of .this-class with the same condition, you will need to repeat the condition accordingly.

Using :not():

.this-class:not(table), .this-class:not(table) .something-else {      border: 1px solid red; } 

And using an override (for IE8):

.this-class, .this-class .something-else {      border: 1px solid red; }  table.this-class, table.this-class .something-else {     border: none; } 
like image 85
BoltClock Avatar answered Oct 04 '22 09:10

BoltClock


:not() is what you're looking for:

In your case it's:

.this-class:not(table), .this-class .something-else { 

As @ajp15243 noted, :not() isn't supported in IE8 and lower.

like image 40
display-name-is-missing Avatar answered Oct 04 '22 11:10

display-name-is-missing