Difference Between a Pseudo-Class and a Pseudo-Element in Css

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.

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.

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.

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.

define pseudo class and pseudo element in same element

Interesting question. If you're able to show us a working example we could probably be of more help.

However, in theory there's nothing wrong with what you're attempting to do (although not all browsers will like it: particularly IE8 and below).

The important thing to understand here is that :hover is a pseudo-class, whereas :before is a pseudo-element.

Here's a quick excerpt from the standard (with thanks to this answer previously on Stack Overflow):

Pseudo-classes are allowed anywhere in selectors while pseudo-elements
may only be appended after the last simple selector of the selector.

The mistake you're making is in your syntax: the order that you're appending them.

Try this instead:

#sidebar .widget li a:hover:before,
#sidebar .widget li a.active:before {
background-position: 65% 65.7%;
}

That should do as you wish. However this isn't going to give you great cross-browser coverage, it's not something that all browsers support of have implemented.

A better approach would be to:

  • reset the :before element to nothing (overwrite the styles you can't access);
  • use a non-repeated background image on the anchor instead (to display the image), and padding-left to give the indentation;
  • You can then switch the background-image in whatever fashion you see fit using :hover on the anchor in your CSS.

This will give you far better cross-browser compatibility.

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>

Whats the difference between pseudo element markers : and ::?

From the CSS3 selector specification section on pseudo-elements:

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.



Related Topics



Leave a reply



Submit