The difference between pseudo-classes and pseudo-elements

Posted by on

Today I stumbled upon an article by ImpressiveWebs about  the difference between :before and ::before in CSS3. I had wondered about this before, so the article was actually an interesting read.

In summary, the difference is that in CSS 2.1 pseudo-elements and pseudo-classes are both targeted using the single colon (:before). In CSS3 however, a distinction is made between the both, pseudo-elements now being prefixed with two colons (::before).

Why? Not sure, but as Louis points out the rule may have come a little too late anyway. Because a lot of pseudo-elements were already introduced in CSS 2.1, backwards compatibility will have to be ensured by supporting the single-colon version as well. Anyway, more about that in the original post: What’s the Difference Between “:before” and “::before”?

Not surprisingly, one of the comments implied (unless I misunderstood the speaker) not being able to actually tell the difference between a pseudo-class and a pseudo-element. This too is something I’ve been wondering about, but which I found the answer to a couple of weeks back. Here’s my reply to said comment:

I don’t think it’s so strange at all that :first-child is a pseudo-class yet ::first-line and ::first-letter are pseudo-elements.

Think of it this way: a :first-child, :last-of-type or :nth-child() is an entire element, like the first li in an ol, the last p in a div or whatever. Because the entire element is selected by this rule, all that has to be used to style it is a pseudo-class.

::selection, ::before and ::first-line however are not already existing elements by themselves, but rather parts of an element. To give that particular part of the document another style, a pseudo-element is wrapped around it with the proper style. In the case of ::select, think of it as surrounding the selected part with a span and then styling that. It’s a pseudo-element, because there wasn’t a real element available to add the style to.

I hope that makes it a little easier to understand/memorize the difference?

Also interesting, multiple pseudo-classes can be used on the same element. For instance, when using the following rules:

a:hover { color: green }
a:visited { color: red }
a:visited:hover { color: blue }

Visited links will show up red, hovered links will show up green, but when hovering a link that has been visited it actually shows up blue.

This doesn’t (or at least shouldn’t, according to the CSS3 spec) work for pseudo-elements. It’d be cool if the following code:

::selection::first-letter { color: red }

Would make only the first letter of a selected text show up red, but it doesn’t. Luckily, we can still combine pseudo-classes and pseudo-elements, as long as there’s still only one of the latter. Take a look at this example, and see if you can figure out what it will do:

li:nth-child(even){
  color: grey
}
li::selection {
  background: #eee;
}
li:nth-child(even)::selection {
  color: white;
  background: black;
}

That’s right! It alternates the background color if you select the list items, as long as you use a browser that supports :nth-child.

See the working version right here, including the other examples I used in this article. If you use IE, just marvel at the screenshot.

Anyway, that’s all for today. Hope you learned something, and be sure to add a comment or tweet me (@Litso_) if you’ve got anything to add!

3 Responses to “The difference between pseudo-classes and pseudo-elements”

  1. Bart van Heukelom said on

    CSS is getting better and more flexible, but it’ll always be flawed as long as you can’t script in it, and add completely new purely graphical objects in the page. I believe that until that happens, we’ll see things such as extra empty divs and non-optimal ordering of the HTML content.

  2. Stephan said on

    There is currentlly talk about browser support of CSS variables, mixins and nesting. Certainly worth a read: http://net.tutsplus.com/articles/news/native-css-variables-welcomed-addition-or-huge-mistake/

    I’m going to give LESS or SASS a try soon and see how I like it, but I think it’ll make coding CSS a lot more dynamic.

    You might be right about the adding purely graphical objects though. Using :before / :after with background images helps, but not enough to prevent developers from adding non-semantical elements. I wonder though, if that day will ever come :P

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>