By Emily Lewis

Getting to Know CSS3 Selectors: Other Pseudo-Classes

By Emily Lewis
Help us help you! You'll get a... FREE 6-Month Subscription to SitePoint Premium Plus you'll go in the draw to WIN a new Macbook SitePoint 2017 Survey Yes, let's Do this It only takes 5 min

In the first of this two-part series, I covered the new CSS3 structural pseudo-classes, which target elements according to their position in the document tree or their relation to other elements. In this article, I’ll review the remaining pseudo-classes introduced in CSS3: the state-based, target, and negation pseudo-classes.

UI Element State Pseudo-Classes

While structural pseudo-classes rely on an element’s relative position, state-based pseudo-classes target elements according to their state, such as whether an element is active or focused. You should already be familiar with the idea of state pseudo-classes (like :link, :visited, :hover and :active), which were introduced in CSS1 for anchor (<a>) elements.

In CSS2.1, the :focus pseudo-class was introduced, and it expanded state-based selectors beyond hyperlinks to form elements like input and textarea. CSS3 brings three more pseudo-classes you can use to target UI states for form elements: :disabled, :enabled and :checked.

Syntax Review

The syntax for all pseudo-classes is simple. Each pseudo-class name begins with a colon:

:pseudo-class {}

Your selector can include just the pseudo-class, like the preceding example, which will target all relevant elements, or you can be more specific by appending the pseudo-class to an element (e), class or id selector, like this:

e:pseudo-class {}

    .class:pseudo-class {}

#id:pseudo-class {}

With the state-based pseudo-classes, the browser applies the selector only when the specified state is true in the UI. In the following example, the styles specified will render on the screen only when the user hovers over the link. All other link states won’t render these styles.

a:hover {

    background-color: #ccc;

    text-decoration: none;



The :disabled pseudo-class targets input elements that have the disabled attribute, which makes the input element unclickable and unusable:

<input type="text" name="name" disabled />

This example uses the Boolean disabled attribute in HTML5, but you can also declare this attribute in previous versions of HTML:

<input type="text" name="name" disabled="disabled" />

For both approaches, most browsers use a default presentation for disabled inputs, where the field border is slightly grayed out compared with the enabled input, as shown below.

Default Styling of Disabled and Enabled Form Inputs

However, you can use the :disabled pseudo-class to override this default style and obtain the results shown here.

input:disabled {

    background-color: #ccc;

    border: 0;

    padding: 3px 2px;


Disabled Form Input with Unique Style

You can also achieve this effect with an attribute selector if you aren’t using the Boolean disabled attribute:

input[disabled="disabled"] {

    background-color: #ccc;

    border: 0;

    padding: 3px 2px;


Which selector you use ultimately depends on your project.


The :enabled pseudo-class targets the default, enabled state of inputs:

input:enabled {

    background-color: rgb(255, 255, 255);

    border: 1px solid rgb(125,104,99);


Because the default state of form elements is enabled, I’m not sure when I would need to use this selector. An element selector would work just as well, and maybe better, depending on the project. But for purposes of demonstration, consider a short form with radio buttons that includes an Other option that lets users enter their own value in a text input. The HTML for this form is shown below, and below that is the form.


    <legend>What's your favorite zombie movie?</legend>

    <input type="radio" name="FavMovie" id="28Days" />

    <label for="28Days">28 Days Later</label>

    <input type="radio" name="FavMovie" id="Army" />

    <label for="Army">Army of Darkness</label>

    <input type="radio" name="FavMovie" id="Night" />

    <label for="Night">Night of the Living Dead</label>

    <input type="radio" name="FavMovie" id="Reanim" />

    <label for="Reanim">Re-Animator</label>

    <input type="radio" name="FavMovie" id="Shaun" />

    <label for="Shaun">Shaun of the Dead</label>

    <input type="radio" name="FavMovie" id="Other" />

    <label for="Other">Other</label>

    <input type="text" id="OtherEntry" disabled />

    <input type="submit" />


Form with a Disabled Text Input Field

In the HTML, the text input for the Other option is set to disabled, and I’ve left the default browser styling in place. But when a user selects the Other radio button, I want to enable the disabled input. The disabled attribute can be removed with a little JavaScript, and the style can change slightly, as shown here, to help notify the user that the input field can accept entry. The form now appears as it’s shown further down.

input:enabled {

    background-color: rgb(255, 255, 204);


Selecting the Other Option Enables the Input Field and Applies a Style


The :checked pseudo-class targets radio and checkbox inputs that are selected. This allows you to style elements that are preselected by the developer via the checked attribute or selected by the user in the UI. The :checked pseudo-class might be useful in a matrix or long list of radio buttons (or checkboxes) in which a user could have difficulty determining which option is selected. For the sake of brevity, let’s look at how :checked can be applied to a simple opt-out form on which a radio button is preselected (see Figure 6).

The HTML for this example includes a radio button with the Boolean checked attribute:


    <legend>Do you want text notifications of the zombie apocalypse?</legend>

    <input type="radio" name="notify" id="yes" checked /><label for="yes">Yes</label>

    <input type="radio" name="notify" id="no" /><label for="no">No</label>

    <input type="submit" />


And here’s the CSS to target the selected radio button:

input:checked {

    border: 1px solid rgb(255, 0, 0);


Given that other selectors can be used with these pseudo-classes, I could be even more specific by combining :checked with an attribute selector:

input[type="radio"]:checked {

    border: 1px solid rgb(255, 0, 0);


Opera Rendering of a Preselected Radio Button

Unfortunately, most browsers restrict styling of radio and checkbox inputs. In these cases, the styles specified with the :checked selector simply won’t display. Of the browsers I use, only Opera/OS X delivered the results shown, and frankly, it’s just ugly and would probably confuse the user. However, you could use the :checked pseudo-class along with the adjacent sibling combinator to style the label text for a checked radio button. Here’s the CSS. You can see the results below.

input:checked + label {

    background-color: rgb(255, 255, 204);

    color: rgb(255, 0, 0);



The :target Pseudo-Class

CSS3 also includes a few new pseudo-classes that aren’t structural or state-based. The :target pseudo-class selects an element with an id that is linked to by using a fragment identifier. Fragment identifiers appear at the end of a URL, indicated with a hash mark (#) followed by an anchor (<a>) name or element id.

For example, in a long article I might want to include a table of contents that links to the article’s major sections. To set this up, I need to assign ids to serve as the fragment identifiers for the content I want to target (in this case, headings):

<h2 id="rotnruin">Rot &amp; Ruin</h2>

<p>Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains morbo vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris...</p>

<h2 id="romero">Romero Zombies</h2>

<p>Cum horribilem walking dead resurgere de crazed sepulcris creaturis, zombie sicut de grave feeding iride et serpens. Pestilentia, shaun ofthe dead scythe ...<p>

Then I need to link to these ids:


    <li><a href="#rotnruin">Rot &amp; Ruin</a></li>

    <li><a href="#romero">Romero Zombies</a></li>



A Table of Contents with Links to Main Sections

After I have the HTML structure in place, I can style the h2 elements to have a different appearance when a user jumps to a section via the table of content links. Here’s the CSS, with the results shown below.

h2:target {

    background: rgb(125,104,99);

    border: 0;

    color: rgb(255, 255, 255);

    padding-left: 10px;


Heading That Is the Target of the Referring Link

The Negation Pseudo-Class

Referred to as the negation pseudo-class, :not(x) targets elements that are not matched by the selector (x) specified within parentheses. The syntax for :not(x) allows virtually all types of selectors to be specified, from simple element, id or class selectors to combinators and other pseudo-classes.

As examples, you could specify styles for all links that aren’t children of a section element, for all paragraphs that don’t have a assigned or for input elements that aren’t submit buttons:

:not(section) a {}

p:not(.intro) {}

input:not([type="submit"]) {}

Why use Pseudo-Classes?

It’s easy to look at these pseudo-classes (and those covered in Part 1) and wonder why you would use them in favor of the (arguably) more straightforward selectors. The answer is tied to the project you are working on.

Sometimes, a CMS will limit access to markup, which means you can’t add ids or classes. The same is true for some legacy systems. And sometimes unique situations come up where these pseudo-classes make sense.

The goal of understanding these selectors, at least for me, isn’t to pick one and use it exclusively. Instead, it’s about building an arsenal of options you can use for any situation or project.

Browser Support and Processing

As I detailed in Part 1, all modern browsers, including Internet Explorer 10 and 9, support CSS3 pseudo-classes. If you are targeting an older browser version that offers limited or buggy CSS3 selector support, you will need to use a polyfill like Selectivizr. It’s also worth mentioning that browser processing of CSS3 selectors is comparatively less efficient than that for other selectors. Again, what you use should always come down to your project. If you need help evaluating the performance of your selectors, check out CSS Lint and the CSS Test Creator.

Additional Resources

This two-part series covers the basics of CSS3 pseudo-classes, but there’s much more you can experiment with. I recommend the following online resources to give you more ideas about what’s possible:

Also, I very highly recommend Zoe Gillenwater’s Stunning CSS3. In this book, you get lots of practical examples of pseudo-classes, along with a ton of other fantastic CSS3 information and resources.

See also SitePoint’s CSS Reference and CSS books.

Login or Create Account to Comment
Login Create Account
Get the latest in Front-end, once a week, for free.