Également disponible en : Français
In the past, I worked on several projects looking for a way to deal with custom styles proposed by some good designers to change aspect of form controls like checkbox, radio, file input, etc. As you may know, these elements are historically not style-able for accessibility reasons. (as I’ve heard). Still. I have a way to style checkboxes and radio buttons… Ready?
Codes and styles I will show you use CSS level 3 selectors. Old browsers are not concerned by the changes Im going to propose. An automatic fallback to the classical old styles will benefit to these old engines.
Why styling checkboxes or radio buttons?
To harmonize styles between browsers, for sure, but also to make some of them more effective in precise contexts. One of the most common need (to me) is to improve accessibility in a “touch context”. Tappable area for checkbox and radio are too often too small.
Also, color contrasts on default checkboxes on Mac for instance, are really poor. I can’t even understand why it is so badly desinged.
Maybe your goal is elsewhere, so I’m not gonna go deeper into the reasons, let’s jump into my technical solution.
Slightly modify the checkboxes appearance
With this example, we will write a solid base for our CSS. It will give me the possibility to explain how selectors are working.
What I want to get.
HTML – Checkbox basic code
Let’s start with the HTML code. A simply composed code with one
label and one
input in each
You have now in the order 4 checkboxes: 1 empty, 1 checked and 1 disabled and 1 disabled checked.
Please be careful with the
FOR attributes. You have to “link” label and checkbox together thanks to these attributes, by giving them the same value. It’s mandatory for accessibility reason, and for the trick to work.
CSS – Customize checkboxes
input:checkbox element is not stylable, not that much, not enough. We will play with the styles of the
label element and its two pseudo-elements.
It’s precisely in those selectors that you will find the magic: It’ll display custom checkbox with my recent browser, and classical ones with my old browser. If you don’t need to support old browser (below IE11), you can use a easier to write code.
As you can see, the selectors are simpler, I removed all the
:checked part I used to make sure Internet Explorer doesn’t understand the whole selector. Otherwise it tooks only part of the style and it makes it unusable for IE users.
A bit of explanation in the code itself: The first declaration allows you to place the checkbox under the upcoming custom checkbox to hide it visually without using
opacity: 0; and to preserve readability for screen readers. The second one makes the label element more attractive. The space is done to fit the future checkbox size.
relative position is useful here to precisely place the checkbox (the
label becoming the reference).
Targetting only recent browsers
All our custom styles will use this type of selector:
[type="checkbox"]:not(:checked) in there declaration. Which means if the web browser doesn’t recognize the selector, these styles will not be applied. It’s a kind of feature detection thanks to the selector.
If you don’t have to support IE below version 11, use the second syntax I provided just above.
Create the custom CSS checkboxes
Now, we will visually create the checkboxes thanks to
::after (the check symbol) and
::before (to make the box) pseudo-elements.
The first two declarations are for the box and the check symbol aspects (size, color, etc). The two next define the states: not-checked or checked. An animation is played because of the
Styling different checkbox states
Basics done, now we will set the other status: disabled, disabled checked, focused). Find below some styling ideas, but feel free to edit them.
That’s all for these custom styles.
Advanced checkbox styling
I will not explain everything about this demonstration, the idea is exactly the same.
You can now compose a more complex HTML code using the same logic, pseudo-class and pseudo-elements.
Here another idea of what you can do with this code.
These two demonstrations are using respectively
em and pixel unit (
px) to make examples more understandable for this last one. You should try with
rem to create a more flexible and maintainable code, depending on your experience and web project.
Styling Radio Buttons
Hey! Now you got the idea and this example of code with checkboxes, I’m sure you can handle it with radio buttons. I won’t go into the code, but if you need any advice, jump into the comments section or reach me on Twitter. I’ll help you 😊
Looking for ideas?
Now you can do what you want with checkboxes (or radio), find below so inspiration to go further.
And yes, really, you can do the same with radio buttons. Did you try?
If you want to learn more on readable, usable and accessible forms, read this article about forms by Geri Reid.