negation pseudoclass on CSS3 does not work on childs - css

I am trying the :not pseudoclass selector, I want everything on the page to have color blue except the childs of a div which class="pag", so I wrote:
:not(.pag > p){
color:blue;
}
<div class="pag">
<p>First</p>
<p>Second</p>
<p>Thirt</p>
<article>Blah blah blah</article>
</div>
but it doesnt seem to work. Can somebody explain me why?
http://jsfiddle.net/Rc9pT/

It works fine if you simplify the selector:
.pag > :not(p){
color:blue;
}
JS Fiddle demo.
Albeit this 'works fine' only with the caveat that you have to specify a selector, with this approach, for every parent-child relationship; which may become burdensome.
I suspect that it's the simplicity that's required:
The negation pseudo-class, :not(X), is a functional notation taking a simple selector (excluding the negation pseudo-class itself) as an argument. It represents an element that is not represented by its argument.
A 'simple selector' is defined as:
either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class.
This seems to imply that any selector incorporating combinators (such as white-space, >, + or ~, among others) is not 'simple', unfortunately.
References:
Negation (:not()) pseudo-class.
Simple selector definition.

Related

In CSS, is 'div:first-of-type[label="hello"]' different from 'div[label="hello"]:first-of-type'?

In CSS, is this selector:
div:first-of-type[label="hello"]
any different from:
div[label="hello"]:first-of-type
?
Unlike pseudo element, pseudo classes can appear in the middle of a selector:
Pseudo-classes are allowed in all sequences of simple selectors contained in a selector. Pseudo-classes are allowed anywhere in sequences of simple selectors, after the leading type selector or universal selector (possibly omitted). ref
So both are the same
div[label="hello"]:first-of-type {
height:50px;
}
div:first-of-type[label="hello"] {
border:5px solid;
}
<div label="hello" class="box"></div>
Considering the new specification:
Like other simple selectors, pseudo-classes are allowed in all compound selectors contained in a selector, and must follow the type selector or universal selector, if present.
Worth to note that :first-of-type will only consider the element and its sibling. So the first selector will not select the first div having label=hello but the first div if it has the label=hello.
In other words, the 2 conditions must be true to select the element that's why the order doesn't matter and both selectors are the same.
You can see both selectors like below:
div[label="hello"]:first-of-type
(div) && (label="hello") && (first of type)
(div) && (first of type) && (label="hello")
div:first-of-type[label="hello"]
Related: Can I combine :nth-child() or :nth-of-type() with an arbitrary selector?

Can pseudo-elements be used alone in CSS?

According to W3C, the definition of a selector does not cover a pseudo-element:
https://www.w3.org/TR/css3-selectors/#selector-syntax
The above link says:
A selector is a chain of one or more sequences of simple selectors
separated by combinators.
and it also says:
A simple selector is either a type selector, universal selector,
attribute selector, class selector, ID selector, or pseudo-class.
Regarding how a pseudo-element should be used, it says:
One pseudo-element may be appended to the last sequence of simple
selectors in a selector.
and
Only one pseudo-element may appear per selector, and if present it
must appear after the sequence of simple selectors that represents the
subjects of the selector.
So does that mean that a pseudo-element can only be a suffix to a "valid" selector and should not be used alone?
does that mean that a pseudo-element can only be a suffix to a "valid"
selector and should not be used alone?
Your conclusion is not true, because the universal selector * can be omitted.
If a universal selector represented by * [...] is immediately
followed by a pseudo-element, then the * may be omitted and the
universal selector's presence implied.
So you can use a pseudo-element alone, e.g. ::before, because under the hood it will be treated like *::before.
::before {
content: 'Hello!';
}

Why is "a:not(b) > c" invalid?

I have the following CSS:
div.section:not(div.cover) > div { ... }
And the validator says:
Parse Error [div.cover) > div]
Why doesn't it validate (not working in browsers either)? Is > not allowed after a pseudo-class, or what could be the issue?
You cannot combine a type selector (div) and a class selector (.cover) in the negation pseudo-class :not(), as pointed out by #DanPrince in the comments.
The negation pseudo-class must contain a simple selector:
A simple selector is either a type selector, universal selector,
attribute selector, class selector, ID selector, or pseudo-class.
Issue is (div.cover). You need to give a simple selector e.g. (.cover)

What does the CSS `not` selector do?

I saw the following snippet in a css file. What does it do?
h3 ~ *:not(h3) {
margin-left: 15px;
}
Obviously it alters h3 headers in some way but I don't understand what ~ *:not(h3) does.
Googling ~ *:not(h3) is unproductive.
The isn't HTML. It is a CSS selector.
Specifically, it is the negation pseudo-class:
The negation pseudo-class, :not(X), is a functional notation taking a simple selector (excluding the negation pseudo-class itself) as an argument. It represents an element that is not represented by its argument.
Obviously it alters h3 headers
No, it does exactly the opposite. It stops the selector from matching h3 elements.
This is CSS, not HTML. See Mozilla's documentation on the CSS negation pseudo class for more details, but not basically selects elements that do not match the specified selector (in this case, h3).

Are parentheses allowed in CSS selectors?

In the below example, I want to create a CSS rule that applies only to the header with the text "Blockhead".
<div class="gumby">
<span class="pokey"></span>
<h3>Blockhead</h3>
<h3>Clay rules</h3>
</div>
Can I use parentheses, such as (.gumby > .pokey) + h3? If not, what is my alternative?
No, parentheses are not valid operators in CSS selectors. They are reserved for functional notations, such as :lang(), :not(), and :nth-child().
You don't need them anyway; .gumby > .pokey + h3 by itself will work just fine.
This is because a sequence of selectors and combinators is always read linearly. Combinators don't have any sort of precedence. The selector can be interpreted as
Select an h3 element
that immediately follows an element with class pokey
that is a child of an element with class gumby.
And because of how node trees work, the use of sibling and child combinators here implies that both .pokey and the h3 are children of .gumby, which in your case they are, because of its statement that both of them are siblings.
As of 2022, we can now use the :is() selector for this purpose:
https://developer.mozilla.org/en-US/docs/Web/CSS/:is
:is(.gumby > .pokey) + h3 {
color: blue;
}
<div class="gumby">
<span class="pokey"></span>
<h3>Blockhead</h3>
<h3>Clay rules</h3>
</div>
If I understand correctly, :is() can simulate both logical AND :is(A):is(B):is(C) and logical OR :is(A, B, C), allowing for powerful combinations. Don't forget to use it in concert with other structural pseudo-classes such as :not() and :nth-child(), CSS Combinators, and DOM Traversal methods such as document.querySelectorAll().
Also, the :where() pseudo-class is identical except that it has 0 specificity, while :is() takes the specificity of its most specific argument.
h3 is not inside .pokey so you must ommit .pokey from the rule
All u'd be able to do is
.gumby h3 {}
or do this
<div class="gumby pokey">
<h3>Blockhead</h3>
<h3>Clay rules</h3>
</div>
.gumby.pokey h3 {}
if a tag has more than one class you can pile them up in css if you don't use a space character

Resources