Styled Checkboxes

Styling checkboxes and radio buttons through a label-based veneer.

First, a caveat: restyling form elements is dangerous business.

There’s a reason browsers don’t easily allow this: from a user experience standpoint, the best UI is a familiar one. You can easily confuse users mucking around with novel controls.

The lesson? Don’t go overboard. Remember what Spider-man taught us.

Faux Checkboxes. Adjacent Label.

First, a basic example. We hide the actual input element by setting visibility, position, and z-index to tuck the element out of sight behind the label.

Then, we create a :before pseudo-element to serve as our input on the label. This gives us nigh-unlimited styling potential. We’ll keep it basic for the moment — just a basic square.

Last, we create a third style using the pseudo-class :checked and the adjacent label’s faux input.

In short, we create our own input element and simply style it differently if the input field is checked.

Click some checkboxes!

In this example, note the input element is outside the label, which uses the for attribute to identify it:

<input type="checkbox" class="plumbing" name="opt" id="opt" value="1"><label class="porcelain" for="opt">One</label>

We’ll cover the alternative syntax next.

Faux Radio Buttons. Parent Label.

The radio button works the same way. To differentiate it in the barebones example, we’ll simply add a border-radius to the pseudo-element if the selected element has a [type=radio] attribute.

Pick your options:

Here, the label is a parent element of the input, the former of which we cannot style based on the input’s :checked state — there are no parent selectors. Therefore, we added a span tag immediately after the input element to host our styled “field”.

<label><input type="radio" class="plumbing" name="opt" id="opt" value="One"><span class="porcelain">One</span></label>

Label as checkbox.

In the above examples, we’ve been using the :before pseudo element to create faux-input elements, but the label itself is still a sibling selector, and can be just as effective as an input of its own.

*This, one could argue, is a good example of not following the lessons that Spider-Man taught us.

What’s your favorite color?

See below for this CSS code.

Le Code: Base CSS

Le Code: Color Label CSS