Combining :Not() Selectors in CSS

Combining :not() selectors in CSS

Selectors level 3 does not allow anything more than a single simple selector within a :not() pseudo-class. As a jQuery selector, it works because jQuery extends its :not() functionality to allow any selector (like the .not() method).

However, your second syntax is one of the proposed enhancements to :not() in Selectors 4, and works equivalently to your first. Although the example (shown as of this writing anyway) shows a chain of :not() selectors, the proposal says:

The negation pseudo-class, :not(X), is a functional notation taking a selector list as an argument. It represents an element that is not represented by its argument.

Here a selector list is simply a comma-separated list of selectors.

If you need to negate selectors that contain combinators (>, +, ~, space, etc, for example div p), you can't use :not() in CSS; you'll have to go with the jQuery solution.

How can I combine two :not()s?

Combine the two :not() selectors, just as a selector for .class-a AND .class-b is .class-a.class-b.

:not(h1):not(figure) > a {  color: red;}
<h1><a>Test</a></h1><p><a>Test</a></p><figure>  <a>Test</a></figure>

Why can't I combine pseudo-element selectors?

You are combining multiple vendor-specific selectors into a single CSS rule.

This means that if one of the selectors is not recognised by the browser, the entire CSS block is ignored. In this particular case, Chrome does not recognize ::-moz-range-track, because it is specific to Firefox/Gecko. This is not a quirk, but intended behaviour and part of the CSS standard.

The solution would be to split the declarations. Like so:

.range2::-webkit-slider-runnable-track {
height: 6px;
border-radius: 3px;
border: 1px solid black;
}
.range2::-moz-range-track {
height: 6px;
border-radius: 3px;
border: 1px solid black;
}

Updated CodePen

Combine :not() and :first-child() selectors

This is a tricky question : I don't think there's a simple way to achieve that :)

As far as I understand : you try to select the first .image element, as long as it's not a .mobileOnly element ?

#holder .image:first-child {
border: 5px solid #0a85d4;
}
#holder .image.mobileOnly:first-child {
border: none;
}
#holder .image.mobileOnly:first-child + .image {
border: 5px solid #0a85d4;
}

Live example : http://codepen.io/enguerranws/pen/wMWzBr

Let's explain this : you were trying to select the first child of type .image, which as class .onlyMobile > this couldn't work, because in the case you need, .image wasn't the first child of its type.

LESS CSS selector combining not and :after pseudo element

By generating the following selectors, you are essentially styling all :after pseudo elements regardless of their classes.

.submit-it:not(.excluded):after,
.submit-it:not(.error):after, { ... }

By selecting all elements without class excluded, and all elements without class error, you are indirectly selecting all the elements since these two events are not mutually exclusive.

Therefore you would chain the :not() pseudo classes, and replace:

&:not(.excluded), &:not(.error)

with:

&:not(.excluded):not(.error)
.submit-it, .send-it, .get-results {
&:not(.excluded):not(.error) {
&:after {
content: 'text';
}
}
}

Which will output:

.submit-it:not(.excluded):not(.error):after,
.send-it:not(.excluded):not(.error):after,
.get-results:not(.excluded):not(.error):after {
content: 'text';
}


Related Topics



Leave a reply



Submit