Hey look, I am an alert. You can close me without JavaScript, but CSS3 instead. Just click on the (×). Go on, try!
Hey look, I am an alert. You can close me without JavaScript, but CSS3 instead. Just click on the (×). Go on, try!

I have been wondering for some time how to add a close button to alerts, or popups that will hide their contents without JavaScript? CSS3 and the checkbox hack have lately come to the rescue.

CSS3 adds a :checked state to HTML inputs of type checkbox, that can control any CSS property of nearby elements. The click behaviour is performed by the label pointing at the checkbox via its :for attribute.

With that in mind, let's build the markup for a simple alert:

html
<div class="ll-hideable info">
    <input type="checkbox" id="ll-hideable-close-1" class="ll-hideable-close" />
    <label for="ll-hideable-close-1" class="ll-hideable-close-label">&times;</label>

    <div class="ll-hideable-content">
        Hey look, I am an alert.
        You can close me without JavaScript, but CSS3 instead. 
        Just click on the (&times;). 
        Go on, try!
    </div>
</div>

It's important that the value of the label's :for attribute matches the id of its checkbox. And the ids must be unique on the page.

We have namespaced our CSS classes with ll-hideable prefix to avoid clashes with other third-party libraries.

We hide the checkbox by setting its :visibility to hidden, and only show its label. The latter is also positioned in a style similar to normal alert boxes, like the ones provided by Bootstrap for example.

css
.ll-hideable-close {
    display: none;
}

.ll-hideable {
    position: relative;
}

.ll-hideable-close-label {
    position: absolute;
    right: 1em;
    top: .5em;
    cursor: pointer;
}

Now, when the user clicks on the label, the browsers set the value of the checkboxes' :checked attribute to true. When that happens, let's make sure we hide all the sibling elements of the checkbox, and itself.

css
.ll-hideable-close:checked,
.ll-hideable-close:checked ~ .ll-hideable-close-label,
.ll-hideable-close:checked ~ .ll-hideable-content {
    display: none;
}

And voila! (You can try the effect above if you haven't already.)

The examples on top of the page use Twitter's Bootstrap alerts' style. The functionality is created using CSS3, which is supported by Chrome, Firefox, Opera, and IE10.