Snook.ca

Understanding Pseudo-elements

In CSS, there are certain selectors you can use that act like you've injected new HTML into the page and have the flexibility to style those new imaginary elements. These are known as pseudo-elements.

CSS 2.1 has four of them:

:first-line allows you to style the first line of a block element

:first-letter allows you to style the first letter of a block element

:before allows you to inject and style content before an element, block or inline.

:after allows you to inject and style content after an element, block or inline.

Pseudo-elements can only be applied to the last "simple selector in a chain", as the recommendation says. A simple selector is either the univeral selector (*) or a type selector (I tend to call them element selectors) followed by attribute, ID or pseudo-class selectors.

p:first-line { /* this will work */ }p:first-line span { /* this won't work */ } p.intro:first-line { /* this will work */ }p:first-line.intro { /* this won't work */ }.intro:first-line { /* this will work */ }#main:first-line { /* this will work */ }body#about #content p.intro:first-line { /* this will work */ }

Because the pseudo-element is considered an element unto its own, the style can only be overridden by styling an elements that would be contained within the pseudo-element or by increasing the specificity on the selector. For example, look at the following HTML structure and its corresponding CSS:

<div id="main"><p>Lorem ipsum ... </p></div>

#main p {color:#555;}p:first-line {color:#000;}

The pseudo-element wins out and the first line is black and not gray. If you needed to override the style you'd have to increase the specifity. Like, if we wanted to override the style for an intro paragraph that was different from the rest of them.

p:first-child:first-line {font-size:2em}

This rule has an element selector and a pseudo-class selector (which counts towards the specificity rules just as a regular class selector) which has more specificity than just the element selector used before. I used the pseudo-class :first-child to reiterate something important: the pseudo-element must be last in the declaration.

Caveats

Internet Explorer only supports :first-line and :first-letter. The selectors :before and :after will not work — not even in version 7.

From JavaScript, there's no way that I've found to gain access to these additional elements that have been pseudo-injected into the page. In fact, detecting that these styles are even being applied appears to be impossible in anything but Firefox.

I'm curious however. Do you actually use pseudo elements? I personally don't for precisely the reason you mentioned in your Caveats. They don't work for the biggest browser market: IE.

The only reason I ask is; if you do use them, what sort of situations do you use them in? I for one can't see any advantage to them if I have to re-implement the functionality for IE. I may as well do it the same for all browsers.

@Ian: admittedly, I almost never use pseudo-elements. Some who are particular of their typography may play with the drop cap or first-line to lead into the content. You can do so somewhat consistently across browsers. Although, even then there are some further caveats that I haven't described. Like starting a sentence with quotes and using :first-letter. IE will only modify the quote mark whereas Firefox will include the quote mark with the first letter as the spec indicates you should.

I did use :after on a project to add textual decoration like Â» characters after links. For IE, I just used JavaScript to add them in manually. This meant only a fraction of the site's audience didn't get them but it wasn't a big deal if they didn't.

Thanx for that clarification Jonathan - I have also made a small example page with some of the pseudo selectors, which some of your readers might find useful: http://kimblim.dk/csstest/ - it has browser support and some very basic examples.

Also, as for what to use pseudo-classes for .. :first-child and :last-child are amazing for styling lists where you need different margins, styles, etc, for the beginning and end. no need for special classes in your markup any more.

@Matt Wilcox: Yes, there are a number of pseudo-classes. What I'm talking about here is strictly pseudo-elements.

@Matt Nish-Lapidus: Yes, IE7Scripts can solve the before and after but can be a little heavy handed if you're just trying to fix something small. The :after fix I did for IE, for example, did use Dean's lovely library but it was causing loading issues. Instead, I was able to replicate what I needed in about 4 lines of code.

Probably the only place I ever use pseudo-elements is when i use :after to clear floats, as was first (I think) demonstrated by Matt Brubeck. Adding height: 100% adjusts for IE incompatibilities, which is the only reason I've ever used this pseudo-element.

Now, with increasing browser progression, I look forward to breaking out the rest of the newfangled funkiness. And so Kimblim, I expect to make much use of your excellent list. :)