Can pseudo-elements be used alone in CSS? - 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!';
}

Related

What is the difference between pseudo-classes and pseudo-elements?

What is the difference between div::after {} and div:after {} ? When do we have to use :: over :?
Double colon and single-colon notation is to distinguish between
pseudo-classes and pseudo-elements.
What is the actual meaning of the above statement?
From https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/Pseudo-classes_and_pseudo-elements
Pseudo-class :
A CSS pseudo-class is a keyword, preceded by a colon (:), added to the end of selectors to specify you want to style the selected elements, and only when they are in certain state. For example, you might want to style an element only when it is being hovered over by the mouse pointer, or a checkbox when it is disabled or checked, or an element that is the first child of its parent in the DOM tree.
Examples:
:active
:checked
:nth-child()
:first
:hover
Pseudo-elements ::
Pseudo-elements are very much like pseudo-classes, but they have differences. They are keywords, this time preceded by two colons (::), that can be added to the end of selectors to select a certain part of an element.
Examples:
::after
::before
::first-letter
::first-line
::selection
::backdrop
As stated by #stephanmg:
In practice ::before is used as :before and ::after is used as :after
because of browser compatibility. Both are pseudo-elements, but may
look like pseudo classes. This might be confusing if you read CSS
code.
Pseudo-classes :
it is applied automatically by the browser
depending on the position of the element or its interactive state.
For Example :
E:hover Matches elements of type E when the cursor is
hovering over it.
Pseudo-elements :
It is applies styles to content
based on its position in the HTML hierarchy.
For Example :
E::first-letter This applies a style to the first letter of the first line inside a block-level
element E.
So ,
The CSS3 Selectors specification prefixes pseudo-elements with two colons instead of one.
So, :first–letter becomes ::first-letter and :first-line becomes ::first-line.
IE 8 and earlier don’t understand the double-colon prefix, so you need use
the single-colon versions to avoid styles breaking in older browsers.

Can the Universal selector * be replaced by :lang?

The universal selector asterisk (*) is unique in that it matches a single element of any type.
So if I have different elements within a div and I want to select them all with one selector, I can either add a class to all the inner elements (something like .parent .class {}) or I can use the universal selector (.parent * {})
Then I saw the spec for the :lang pseudo element (particularly the end):
Note the difference between [lang|=xx] and :lang(xx). In this HTML
example, only the BODY matches [lang|=fr] (because it has a LANG
attribute) but both the BODY and the P match :lang(fr) (because both
are in French).
<body lang=fr>
<p>Je suis Français.</p>
</body>
Which means that all elements within an element targeted by :lang selector are also targeted. (Wow!)
So let's say I wanted to add a border to all the elements within a div - instead of the selector div * {} I could theoretically use :lang
Here's a demo
As far as I can tell, the only difference is that the :lang selector selects the parent as well as all the children (and of course there's the technical difference the :lang has greater specificity)....however
if the :lang selector was applied in a semantic way that it included the whole document - with the lang attribute on the html element - I don't think that the above difference would matter.
So basically my question is:
Assuming that my html element has the attribute lang="en":
Can I replace code which uses the universal selector such like:
* { box-sizing: border-box; }
with:
:lang(en) {
box-sizing: border-box;
}
The code seems to work (DEMO), and it seems to be semantic as well, but I'm wondering if there are certain reasons/cons to the above technique.
Can the Universal selector * be replaced by :lang?
No, because you cannot write a selector using :lang() that is guaranteed to match all elements unless you assume all elements in the document will always be in the same language.1
If you're going to assume that all elements are in the same language, then using the :lang() pseudo is pretty pointless, since the whole point of that pseudo-class is to be able to distinguish parts of the document that differ in their content language.
Also note that the compound selector :lang(en) (consisting of just that one simple selector) is equivalent to *:lang(en). It is essentially the * selector with an additional qualification of a pseudo-class. You are not avoiding the use * by replacing it with :lang().
1 Selectors 4 allows a selector like :lang('*') to be written that matches elements in any language (which, again, is pointless if you don't care what language an element is in!), but this assumes the document even has content language semantics built into it. It is not clear if :lang() will work at all in a document lacking such semantics.

CSS difference bwteen Pseudo-classes and Pseudo-elements in specificity calculation ?

I learned how to calculate css specificity based on http://reference.sitepoint.com/css/specificity
However, based on this reference, I don't understand what is the difference between Pseudo-classes (from c) and Pseudo-elements (from d)?
For example,
input[type="text"]:hover
hover is Pseudo-classes (from c) or Pseudo-elements (from d)?
compared with input[type="text"].error, which one has a higher specificity?
Pseudo classes (c) have a specificity of 10
Pseudo elements (d) has a specificity of 1
Both
input[type="text"]:hover and
input[type="text"].error
have a specificity of 21
input (element - 'd') = 1
[type="text"] (attribute - 'c') = 10
:hover (pseudo class - 'c') = 10
.error (class - 'c') = 10
There are also online specificity calculators available, such as this one.
The page cited says the same as CSS specifications such as CSS3 Selectors, section 9. Calculating a selector's specificity, though in less detail and non-authoritatively. The key point is that in specificity, pseudo-class selectors are treated like class selectors and pseudo-element selectors like type selectors (tag names). This means that a pseudo-class selector is more specific than a pseudo-element selector. The idea behind this is that classes (and pseudo-classes) refer to elements in a more specific way, like “Cadillac” (a class of cars, so to say) is more specific than “car” (a type of things, so to say).
Regarding :hover, whar matters is how it is specified in CSS specs. It so happens that it is a pseudo-class selector. This is natural, since it refers to an element that is in a specific state, so it can be characterized as a “dynamic class”.
Thus, input[type="text"]:hover and input[type="text"].error have equal specificity.

Using CSS pseudo and attribute selectors together

Because of a bug in webkit browsers, you can't use attribute and :before/:after classes by default.
The fix doesn't seem to have any effect when using nth-last-of-type selector.
Here's what I'm doing:
.left[class^='col']:nth-last-of-type{
margin-right: 0 !important;
}
Just wanted to check and see if I'm not overlooking something simple.
Your :nth-last-of-type syntax is a bit off — it's either :last-of-type or functional :nth-last-of-type() with a formula an+b as an argument.
The pseudo-classes pertaining to "type" refer to the element type, represented by its tag name. It does not mean "the last element matching the rest of this selector".
If, for example, the last element matching .left[class^='col'] is not the last span element, then :last-of-type will not match. You'll have to modify your HTML to either segregate those span elements from others, or add a class to the last such element, before you can target it with a selector.
WebKit does not have any issues with pseudo-classes and attribute selectors that I'm aware of (or if it did, those issues have long been fixed). It does have issues with pseudo-elements, which I address here, where the fiddle link originates.

negation pseudoclass on CSS3 does not work on childs

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.

Resources