Differencebetween Pseudo-Classes and Pseudo-Elements

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

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.

when to use pseudo-classes and when to use pseudo-elements selectors in CSS

The single colon syntax is an older implementation. In general, there are pseudo-elements :: & pseudo-classes :, and they are not identical. In this case though, browsers still support the outdated single-colon syntax.

This means that in your example with :before/::before, it will not make a difference to the outcome, but in general you should use the double colon syntax, because before & after are pseudo-elements, not pseudo-classes.

Read more on MDN.

Difference between pseudo class, pseudo selector, and pseudo element in CSS

Pseudo-classes are used to select elements according to information that you can't otherwise express using attributes, IDs or classes (or any other info available through the DOM). For example, :root, :first-child, :last-child, :lang() and :not().

Pseudo-elements are mock elements that you can apply styles to selectively as part of other actual elements, but aren't themselves members of the DOM. For example, content fragments such as ::first-line and ::first-letter, or generated content such as ::before and ::after.

"Pseudo-selectors" is an umbrella term used to cover both kinds of selectors (or really any selector that begins with at least one :), but it is itself meaningless, because in Selectors, pseudo-classes and pseudo-elements are two fundamentally different things.

CSS :: vs : -- pseudo-element vs pseudo-selector?

Pseudo-classes (:) allow you to style the different states of an element e.g. when you hover over it, when it is disabled, when it is the first child of its parent, etc.

Pseudo-elements (::) allow you to style different parts of an element e.g. the first line, the first letter, inserting content before or after, etc.

Originally they all used a single colon, but CSS3 introduced the double colon to separate the two.

How is ::first-letter different from :first-child (pseudo-class vs pseudo-element)

The document language refers, in the most typical CSS use case, to HTML. The document tree (as referred to throughout Selectors) refers to the DOM tree that is constructed from the markup.

A pseudo-element is something that is generated based on an existing layout. That is, a layout must first be constructed and rendered based on CSS that's applied to elements in a DOM tree. This cannot be accomplished with the document language, the markup, alone.

You'll notice that the ::first-letter pseudo-element only applies to block container boxes, for example. There's no way to know whether an element (or its descendant) will have a ::first-letter pseudo-element until it's determined to be a block container box (the only kind of box that can directly contain a flow of inline content), and that is determined by CSS, not by HTML. As a more concrete example:

<p>Hello world!

By default, a p element is display: block. This results in a block box, which is a kind of block container box. But even so, this default is implemented using CSS. And if you were to override that default with the following CSS rule:

p {
display: inline;
}

this element then becomes an inline box, and p::first-letter will no longer have any effect on it.

Intuitively, it still seems trivial to determine the first letter of an inline box compared to a block box (or any other type of box), but things get pretty complicated once you have several inline boxes in the same inline formatting context all interacting with one another.

::first-line is much more clear-cut: not only is it impossible to know how long the first formatted line of an element's text is until you format the line, but the contents and length of this line can also change as you resize and/or reflow the element and its contents.

In contrast, a tree-structural pseudo-class such as :first-child matches elements in the DOM independently of the layout. Without having to render anything, the browser can tell right off the bat which of the elements is the first child of its parent. All you need is the DOM tree of elements, which means all the information you need can be retrieved from the document language, the markup. For example, the first child of the ol in the following fragment is always the same no matter what CSS you apply to it:

<ol>
<li>First
<li>Second
<li>Third
</ol>

why do some pseudo-elements seem like pseudo-classes?

Pseudo-classes target an existing element when the state of it matches a condition.

You can target a and a:visited and they will match exactly the same "thing" when it is in the visited state.

Pseudo-elements target something that isn't an element in its own right. The :first-line of an element isn't event a complete DOM node.

Difference between the :where() and :is() pseudo-classes?

The difference between :where() and :is() is that :where() always has
0 specificity, whereas :is() takes on the specificity of the most
specific selector in its arguments
.

The pseudo-class :is() doesn't have any weight itself (unlike most pseudo-classes, which are the equivalent of classes in calculating specificity), but the values inside it's parentheses are used to calculate specificity instead. (By the way, it's the same case with another pseudo-class, :not().)

Example:
div:where(.outer) p has a specificity score (ordered from highest to least specificity value: inline styling/style attribute, id, class/pseudo-class/attribute, element) of 0,0,0,2, while div:is(.outer) p is scored 0,0,1,2.

Here's a mnemonic: :is() is influential, :where() is worthless.

Source: MDN



Related Topics



Leave a reply



Submit