Quick Tips: CSS Click States without Javascript

April 24, 2012 at 5:17 pm By

There are countless moments in CSS development when you wish there was a :click psuedo class, similar to :hover. For now, that doesn’t exist, but this little hack will let you get around that.

How It Works

In CSS, you can check if a checkbox or radio button is ‘checked’ with the :checked pseudo element. For example, you could make the background of any checked input red if you wanted to, by doing something like this:

input:checked {
     background: red;
}

That’s all well and good, but how can we use that to our advantage? Well to start, we can connect the input up to a label using HTML’s for property. The for property finds an input with the same ID, and connects them. When you click on the label text, it will automatically check the radio button or checkbox.

<!-- Notice the ID and for properties are the same. Clicking -->
<!-- the label will check the checkbox. -->
<label for="the-checkbox">Click Me!</label>
<input type="checkbox" id="the-checkbox" /> 

Now lets implement a div into the form. We want this div to appear and disappear as the checkbox is checked and unchecked.

<label for="the-checkbox">Click Me!</label>
<input type="checkbox" id="the-checkbox" /> 
<!-- This is the div we want to appear and disappear -->
<div class="appear">Some text to appear</div>

Lets take a look at the CSS for this. We set .appear to not display, and change the cursor on the label to make it seem clickable. We’re also going to hide the input, so it seems like we’re clicking a link, and not a checkbox.

.clickable label {
    cursor: pointer;
    border-bottom: 1px solid #000;
    font-family: Arial, sans-serif;
}

.clickable .appear { 
    display: none;
    font-family: Arial, sans-serif;
    background: black;
    color: #fff;
    padding: 10px;
}

.clickable input {
    display: none;
}

Now what? Well we use sibling selectors to target the appear div, so that when the input is checked, it is being displayed.

.clickable input:checked ~ .appear {
    display: block;
}

The final code looks like this, with the same HTML as we had earlier.

.clickable label {
    cursor: pointer;
    border-bottom: 1px solid #000;
    font-family: Arial, sans-serif;
}

.clickable .appear { 
    display: none;
    font-family: Arial, sans-serif;
    background: black;
    color: #fff;
    padding: 10px;
}

.clickable input {
    display: none;
}
.clickable input:checked ~ .appear {
    display: block;
}

A Quick Demo

Remember, this is using just CSS!. Click the link below to see a quick demo.


Some text to appear

Problems

:checked has only just been supported since IE9, so if you require good IE support this probably isn’t the right route for you. Of course, this is all CSS3, so support is always a bit of an issue. I must add though that IE8 support is dropping rapidly. You could also use a library like Selectivizr alongside jQuery to get :checked to work in IE8.

This method is also highly non-semantic, so it might not be a good idea if semantics are important to you. Then again, it will still be HTML valid.