Why ::first-letter is a pseudo element and not a pseudo class? - html

I was going through the pseudo classes and elements in CSS.
Till now i read that pseudo classes are used to select elements that are in specific state.
And pseudo elements are used to add virtual elements like ::before and ::after.
I am confused that how come ::first-letter and ::first-line are pseudo elements and not pseudo classes ? Because they are also selecting elements in specific state.

Because they are also selecting elements in specific state.
They are not. They are selecting contents.
Pseudo-elements create abstractions about the document tree beyond those specified by the document language. For instance, document languages do not offer mechanisms to access the first letter or first line of an element’s content. Pseudo-elements allow authors to refer to this otherwise inaccessible information. Pseudo-elements may also provide authors a way to refer to content that does not exist in the source document (e.g., the ::before and ::after pseudo-elements give access to generated content).ref
and
The pseudo-class concept is introduced to permit selection based on information that lies outside of the document tree or that cannot be expressed using the other simple selectors.ref
They cannot be pseudo classes because their selection lies inside the document tree.

Related

CSS: :after vs. ::after ? - Best way to override css classes? [duplicate]

Is there any functional difference between the CSS 2.1 :after and the CSS 3 ::after pseudo-selectors (other than ::after not being supported in older browsers)? Is there any practical reason to use the newer specification?
It's pseudo-class vs pseudo-element distinction.
Except for ::first-line, ::first-letter, ::before and ::after (which have been around a little while and can be used with single colons if you require IE8 support), pseudo-elements require double colons.
Pseudo-classes select actual elements themselves, you can use :first-child or :nth-of-type(n) for selecting the first or specific <p>'s in a div, for example.
(And also states of actual elements like :hover and :focus.)
Pseudo-elements target a sub-part of an element like ::first-line or ::first-letter, things that aren't elements in their own right.
Actually, better description here: http://bricss.net/post/10768584657/know-your-lingo-pseudo-class-vs-pseudo-element
Also here: http://www.evotech.net/blog/2007/05/after-v-after-what-is-double-colon-notation/
CSS Selectors like ::after are some virtual elements not available as a explicit element in DOM tree. They are called "Pseudo-Elements" and are used to insert some content before/after an element (eg: ::before, ::after) or, select some part of an element (eg: ::first-letter). Currently there is only 5 standard pseudo elements: after, before, first-letter, first-line, selection.
On the other hand, there are other types of selectors called "Pseudo-Classes" which are used to define a special state of an element (like as :hover, :focus, :nth-child(n)). These will select whole of an existing element in DOM. Pseudo classes are a long list with more than 30 items.
Initially (in CSS2 and CSS1), The single-colon syntax was used for both pseudo-classes and pseudo-elements. But, in CSS3 the :: syntax replaced the : notation for pseudo-elements to better distinguish of them.
For backward compatibility, the old single-colon syntax is acceptable for pseudo-elements like as :after (browsers still all support the old syntax with one semicolon). Only IE-8 doesn’t support the new syntax (use single-colon if you want to support IE8).

In HTML, do ::after and ::before pseudoelements only work with renderable "non-replaced" elements?

I recently noticed on a project that the ::after pseudoelement did not add any content after an input element:
input::after { content: "xxxxxxxxxx"; } // no "virtual last child" inserted into DOM "after" the input
(reference to "virtual last child" is from MDN page here)
Of course, an element such as a div will have content "after" it, and the last child "::after" will be inserted into the DOM:
div:empty::after { content: "xxxxxxxxxx"; }
//In DOM
<div>::after</div>
but nothing is inserted in these cases:
head, script { content: "qaqaqa"; }
My initial assumption was that any HTML elements that are rendered by the browser with tags that should be closed (.e.g, p, body, html, div,....etc) will have ::after inserted as a last child (and ::before inserted as a first-child), whereas elements that do NOT fit this (e.g., script, head, img, br, input,...etc) will not exhibit this behavior. My CodePen attempts suggested this was correct.
I read through documentation which finally led me to this resource, in which a note reads:
Note. This specification does not fully define the interaction
of :before and :after with replaced elements (such as IMG in HTML).
This will be defined in more detail in a future specification.
(for definition of "replaced elements" see here)
So now my refined assumption regarding ::after and ::before is that these pseudoelements are only applicable to "renderable" elements which cannot be classified as "replaced elements" (Note this refined assumption now excludes textarea from use with ::after / ::before, whereas my initial assumption would have included it - textarea::after was tested with CodePen and no ::after last child is inserted into the DOM).
Would the refined assumption be correct?
HTML does not define which elements are replaced elements or which elements can contain ::before and ::after pseudo-elements. Neither do CSS2.1 or selectors-3. The latest rewrite of css-content-3, however, states pretty unambiguously:
Replaced elements do not have '::before' and '::after' pseudo-elements
although implementations of course are not consistent with the draft (famously or otherwise, WebKit/Blink) since this wasn't hitherto defined.
Whether an element can have ::before and ::after pseudo-elements is not defined by its content model (i.e. if it's void or otherwise), or whether it has an end tag, in HTML. And again, a lot of this is implementation-dependent. For example, some implementations allow br of all things to have ::before and ::after pseudo-elements, because nobody knows exactly how br is supposed to be implemented in terms of CSS and each browser does it its own way (because neither HTML nor CSS actually defines this).
A head element and any of its descendants can have ::before and ::after pseudo-elements — all you have to do is change their display to something other than none. Obviously, they're not supposed to be displayed, but that doesn't stop anyone trying to be clever.
As far as CSS is concerned, input and textarea are both considered replaced elements, even though textarea has a start tag, end tag, and content. Whether these elements should or must be replaced elements is not stated (not even in section 14.5 of WHATWG HTML), but most browsers render them as replaced elements by default, and this behavior usually can't be changed. And for the purposes of the ::before and ::after pseudo-elements not being supported, that's all that matters.
Don't guess, read: https://drafts.csswg.org/selectors-3/#gen-content
The ::before and ::after pseudo-elements can be used to describe generated content before or after an element's content.
input has no content, so no after element is shown. Same applies for every HTML element with no content (br, menuitem, link...). All auto-closing tags have no content, and some others (like script) have none too.

How to use multiple css contents in a same class

One content (:after for box and :before for arrow) property for data-tooltip and I want another content property for the field icon using custom icon fonts like fontello or fontawesome. How can I achieve this.??
If you're asking whether it's possible for an element to have more than one :before or :after pseudo-element at a time, that's not possible in CSS2.1. The reason is twofold:
Any element can only have exactly one :before or :after pseudo-element at a time due to cascading rules. See this answer for details.
Even if an element could have more than one of each kind of pseudo-element, the browser wouldn't know how exactly it should lay all of them out in the formatting structure. This can be worked around by having CSS offer a way to specify multiple pseudo-elements or nest pseudo-elements within other pseudo-elements, but neither of these ideas have been implemented.
If you need a complex structure that cannot be achieved with a single element with one :before and one :after pseudo-element, you will need to modify your HTML to accommodate this structure.

can I define in CSS look of DIV being empty? (no children elements)

Is it somehow possible to define certain look for DIV being empty, i.e having no accessors inside (no nested elements) without need of using JS, just using pure CSS?
Yes that's what the :empty pseudo-class is for.
From the MDN docs:
The :empty pseudo-class represents any element that has no children at
all. Only element nodes and text (including whitespace) are
considered. Comments or processing instructions do not affect whether
an element is considered empty or not.

What does this operator (::) in CSS mean? [duplicate]

This question already has answers here:
What does the double colon (::) mean in CSS?
(3 answers)
Closed 8 years ago.
I have seen CSS like Custom Scrollbars in WebKit
body::-webkit-scrollbar {
width: 10px;
height: 13px;
background-color: white;
color: #EBEBEB;
border:none;
}
This specifies CSS for WebKit browsers. But what does this operator (::) mean in CSS?
Where can I find other such operators in CSS?
It indicates that what follows is a "pseudo-element". From the CSS Selectors level 3 spec:
A pseudo-element is made of two colons (::) followed by the name of
the pseudo-element.
And a pseudo-element creates an "abstraction about the document tree":
Pseudo-elements create abstractions about the document tree beyond
those specified by the document language. For instance, document
languages do not offer mechanisms to access the first letter or first
line of an element's content. Pseudo-elements allow authors to refer
to this otherwise inaccessible information. Pseudo-elements may also
provide authors a way to refer to content that does not exist in the
source document (e.g., the ::before and ::after pseudo-elements give
access to generated content).
For example, the ::webkit-scrollbar pseudo-element provides a mechanism to refer to the webkit scrollbar, which would be otherwise inaccessible. Another example: the ::first-letter pseudo-element provides a way to refer to the first letter of an element (if it is not preceded by any other content).
In css3 we use double colon(::) for pseudo-element & single colon(:) for pseudo-class
The single colon syntax (e.g. “:before” or “:first-child”) is the
syntax used for both pseudo-classes and pseudo-selectors in all
versions of CSS prior to CSS3. With the introduction of CSS3, in order
to make a differentiation between pseudo-classes and pseudo-elements
(yes, they’re different), in CSS3 all pseudo-elements must use the
double-colon syntax, and all pseudo-classes must use the single-colon
syntax.
Read this article http://www.impressivewebs.com/before-after-css3/
It is used to define a pseudo-element. As an example from the documentation:
p::first-line { text-transform: uppercase }
This modifies the first line of p elements. There's no real DOM element that is selected, that is why it is a pseudo-element.
In your case, it modifies scrollbars in WebKit within the body element:
body::-webkit-scrollbar
There is no scrollbar element within your document but this still allows you to style scrollbars within your HTML page.
this operator is new add in CSS3.it's meaning Pseudo element.
Thought I'd add this since people are having difficulty understanding what it actually means:
Basically it's a way to get a document to format in a way that wouldn't be possible using the markup that is present. A good example exists in the W3 spec:
Here is the example for a ::first-letter pseudo element
The original HTML fragment
<div>
<p>The first text.
The fictional markup after the pseudo element is applied
<div>
<p><div::first-letter><p::first-letter>T</...></...>he first text.
As you can see - the original HTML specified a div and a p, but there is no way to format the first letter using standard CSS, so the pseudo elements were added, enabling the first letter to be modified
Psuedo elements allow you to do stuff like that..
Google is your friend here.
Pseudo-elements
Pseudo-elements create abstractions about the document tree beyond those specified by the document language. For instance, document languages do not offer mechanisms to access the first letter or first line of an element's content. Pseudo-elements allow authors to refer to this otherwise inaccessible information. Pseudo-elements may also provide authors a way to refer to content that does not exist in the source document (e.g., the ::before and ::after pseudo-elements give access to generated content).
A pseudo-element is made of two colons (::) followed by the name of the pseudo-element.
This :: notation is introduced by the current document in order to establish a discrimination between pseudo-classes and pseudo-elements. For compatibility with existing style sheets, user agents must also accept the previous one-colon notation for pseudo-elements introduced in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and :after). This compatibility is not allowed for the new pseudo-elements introduced in this specification.
Found at http://www.w3.org/TR/css3-selectors