CSS Pseudo-Classes and Pseudo-Elements

CSS 2 and CSS 3 Pseudo-Properties

CSS 2.1 introduced a new way for web designers to style items in their document tree: pseudo-elements and pseudo-classes. Styles are normally attached to an element based on its location in the document tree, but this doesn't allow enough flexibility. For example, no element refers to the first line of a paragraph, so using simple CSS selectors you wouldn't be able to style it. But with CSS pseudo-classes and pseudo-elements you can style the first line and many other scenarios.

CSS 2.1 Pseudo-Classes

Pseudo-classes are allowed anywhere in selectors. They define situations that do not appear in the document source or document tree, but can be matched on the page.

:first-child
The first child pseudo-class matches an element that is the first child of another element. It is most useful in situations where you want to call out the first instance of an element, but not every one.

For example, you might indent the first paragraph in a div to separate it from other paragraphs in that same content section:


div > p:first-child { text-indent: 0.5em; }
<div>
    <p>This is the first paragraph. It will be indented.</p>
    <p>Subsequent paragraphs will not be indented.</p>
</div>
<div>
    <p>If I open a new div, the first paragraph of it will be indented.</p>
</div>
<p>But paragraphs that are outside of a div will not be indented.</p>

You can also use the first-child selector without any parent element. This styles the first time that element is a child of any element. a:first-child { ... } styles the first link of any parent element, including the body tag.

Link pseudo-classes: :link and :visited
These pseudo-classes let you style unvisited links differently from visited ones.

The most common styling technique is to remove underlines from visited links.


a:link { color: blue; }
a:visited { text-decoration: none; }
<a href="http://webdesign.about.com">About Web Design</a>

Dynamic Pseudo-Classes: :hover, :active, and :focus
These pseudo-classes change how the links are rendered in response to user actions.

:hover applies when the user places the pointing device over the element but does not select it. :active applies when the element is activated such as when a mouse button is clicked. And :focus applies when the element has keyboard focus.


a:hover { color: red; }
a:active { color: gray; }
a:focus { background-color: yellow; }

In order for these classes to work, you must have them in the exact order: :link, :visited, :hover, :active. If you put :hover first, cascading rules will hide the property of the :hover rule with the :link and :visited rules. If you don't put :active last it will be overridden when the element is hovered over, even though it is active.

:lang
With this pseudo-class you can write CSS selectors that match based on what language the element is written in. This is very useful for designers who work with multi-language sites. You can use it to change the font of the pages or make other changes depending upon what language the page is defined as being.


:lang(en) { font-size: 1.1em; }
:lang(ru) { font-size: 1.2em; }
<body lang="ru">

CSS 2.1 Pseudo-Elements

Pseudo-elements are parts of the document that have physical form, but are not defined by an element. Pseudo-elements can only be appended to the end of a CSS selector.

:first-line
The :first-line pseudo-element applies to the first formatted line of a paragraph. If you style the first-line and then change the width of the browser window, the amount of styled text will be changed.


p:first-line { text-transform: capitalize; }
<p>This is a paragraph that should have multiple lines of text. Only the first line will be capitalized while the rest of the lines will be formatted exactly as they were typed. If the browser window is widened or narrowed, the first formatted line will change (after reloading the page) to reflect the change in the pseudo-element.</p>

This pseudo-element can only be applied to block-level elements.

:first-letter
The :first-letter pseudo-element selects the first letter of the first line of a block. It is most often used to create simple drop caps.


p:first-letter { font-size: 3em; }
<p>This is a paragraph, and the first letter would be three times as large as the other letters in the paragraph.</p>

Generated Content with :before and :after
Generated content is content that is created within the CSS document. It is most often used to do things like add quotations around blockquotes or elipses after truncanted text.


blockquote:before { content: open-quote; }
blockquote:after { content: close-quote; }
<blockquote>'The time has come,' the Walrus said.</blockquote>
p.cutoff:after { content: "..."; }
<p class="cutoff">She went to the store to buy some</p>

Internet Explorer does not support generated content, so if you have a lot of IE customers, you should consider avoiding these pseudo-elements.

CSS 3 Pseudo-Classes

But with CSS 3 there are even more situations that you can style using pseudo-classes. Browser support is varied for these selectors, so be sure to do ample testing, but it is getting better every day.

:last-child, :nth-child, and :nth-last-child
CSS 2.1 gave us the ability to style the first child of an element, but CSS 3 expands on that. You can now style the last child in a group or a specific element (based on it's order in the parent element's list) or even a variable element. This allows you to put a background color on every other row in a table, for example.


tr:nth-child(2n) { background-color: #ccc; } /* even numbered rows are gray */
tr:nth-child(2n+1) { background-color: #e7ecf1; } /* odd numbered rows are blue */

Match Element Types with :first-of-type, :last-of-type, :nth-of-type, and :nth-last-of-type
This allows you to select elements that may be common on your page, and then only style one of them (the first, last, or a specific number). For example, you might want to style the last paragraph that's inside a div element.


div > p:last-of-type { background-color: #ddd; }

:only-child and :only-of-type
When an element is all alone these pseudo-classes let you style them separately. So if you have several paragraphs with links in them, but only one paragraph has only one link in it. You can highlight that link with the :only-child pseudo-class.


p > a:only-child { color: green; }

:empty for Elements with No Children
This pseudo-class matches elements that don't have any children.

:target Lets You Match anchors
When you link to an internal bookmark or anchor it can be helpful to highlight that section of text to your readers. With the :target pseudo-class you can do so easily. If you point to a section of a page with an anchor such as http://www.example.com/index.html#section4 you can then highlight that section with the :target pseudo-class:


:target { background-color: yellow; }
<div id="section4"> ... </div>

UI Classes: :enabled, :disabled, :checked
These classes look at the user interface (UI) to determine if the element is marked enabled, disabled, or checked. This is most commonly found in forms. You would mark a form element disabled and then style it appropriately.


:disabled { color: #ddd; }
<input type="text" name="foo" value="bar" disabled />

:root
Matches the root element of the document. This is most useful for styling XML documents where the root element might not be the same on every page.

:not
The :not pseudo-class matches elements that are not matched by the selector indicated. So you could style every element on your page except the paragraphs, to see what text is not in a paragraph tag:


:not(p) { font-style: italic; }

CSS 3 Pseudo-Elements

CSS 3 has all the same pseudo-elements as CSS 2, and there is one new pseudo-element that may or may not be included in the specification. In CSS 3, you need to differentiate pseudo-elements from pseudo-classes by using a double colon (::) at the beginning of the element.

::selection
This is a pseudo-element that represents a part of the document that has been highlighted by the user. There are only a few style properties that can be applied to this selector, including: background and color properties as well as the cursor and outline properties. Using this selector, you can specify the background color that highlighted text can take, thus making it fit with your site styles even better.


::selection { background: #ddd; color: yellow; }