DEV Community

Cover image for Styling native Checkboxes and Radio inputs (CSS Only)
Felippe Regazio
Felippe Regazio

Posted on

31 7

Styling native Checkboxes and Radio inputs (CSS Only)

So, do you want to style native radio and checkboxes without relying on JavaScript, plugins or dozens of wrappers, is that right? Well, thats possible :)

The provider of all that magic is the appearance css property. The appearance is used to apply or remove a system-native style to/from a web element.

Here's a link to know more about:
https://developer.mozilla.org/en-US/docs/Web/CSS/appearance.

But if you take a look on the 'Can i use' you may note that this property is only well supported when setting its value to "none", and thats exactly what we need . This is because the different apperance values may show different results depending on your system and browser engine, but all the browsers suport the appearance:none very well because there is no secret, it just removes the element native style. So, for that purpose, we have a good support.

https://caniuse.com/#search=appearance

Another thing that worth to say: The appearance cares ONLY about the element style. That means that if i set appearance: none to a checkbox, the element is still a checkbox, but without any appearance (system style). The opposite is also valid, giving an element appearance: button, for example, will not turn that element in a button, the element will only have the button appearance.

This is how we must use this property.

.element {
  appearance: none;
  -moz-appearance: none;
  -webkit-appearance: none;
}
Enter fullscreen mode Exit fullscreen mode

Coding

Now lets code. The idea its very simple, we will remove the checkbox and radio inputs native style and apply our own. If the browser doesn't support the appearance selector there is no harm, the native checkboxes and radios will be used instead. This is the result:

First lets remove the checkboxes and radios appearance

[type=radio],
[type=checkbox] {
   -webkit-appearance: none;
   -moz-appearance:    none;
   appearance:         none;
}
Enter fullscreen mode Exit fullscreen mode

Now we will apply our appearance. You can combine the above properties and this ones in a single selector, but lets split it to the sake of the post:

[type=radio],
[type=checkbox] {
  width: 20px;
  height: 20px;
  border: solid 1px #cccccc;
  margin-right: 8px;
  position: relative;
}
Enter fullscreen mode Exit fullscreen mode

Now lets say how we want our elements to be when they are checked. Remember: we removed the appearance, not the behavior. The ideia here is, when the element is checked we will use a ::before (pseudo-element) to fill the empty space. Thats why our element is setted to position: relative, because the ::before will be absolutely placed inside it, giving the "checked" appearance.

[type=radio]:checked::before,
[type=checkbox]:checked::before {
  content: "";
  width: 14px;
  height: 14px;
  background-color: #ffa500;
  position: absolute;
  top: 2px;
  left: 2px;
}
Enter fullscreen mode Exit fullscreen mode

And finally, lets round the radio corners to differentiate them from the checkboxes:

[type=radio],
[type=radio]:checked::before{
  border-radius: 100%;
}
Enter fullscreen mode Exit fullscreen mode

Thats all, folks. Now we have our styled checkboxes and radio inputs 🎉

Cover image by Nadine Shaabana on Unsplash.

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (7)

Collapse
 
bourhaouta profile image
Omar Bourhaouta •

It looks great, for me to have a more natural css toggles I always add cursor: pointer and user-select: none to the label.

In the demo, if you click on the radio button it'll check the checkbox above, if you could fix the for attributes.

Collapse
 
felipperegazio profile image
Felippe Regazio • • Edited

Nice tunes. But adding the user select none leads to some usability benefit or is pure aesthetic? Im asking in case someone wants to copy the text on the label, that should be a valid situation, maybe.

And must be some issue with input names. I'll fix it for sure, thanks for the notice :)

Collapse
 
bourhaouta profile image
Omar Bourhaouta •

It's just pure aesthetic, avoiding selecting the text after a double-click.

I tend to think about toggles as buttons, as the text in it won't be selectable because it's not interesting to be selected.

It's just my opinion.

Thread Thread
 
felipperegazio profile image
Felippe Regazio •

Nice, is definitely a good point. I also like to bind label+checkbox as as a button, but I don't usually add user-select:none. Ill adopt it for some situations,thanks!

Collapse
 
davide profile image
Davide Scarioni •

Awesome, I did't know about the appearance property, I always use display: none to hide the original checkbox and radio button. Thank you!

Collapse
 
paddyh4 profile image
Pradeep Chavan •

Thanks. Very Helpful.

Collapse
 
danielskiala profile image
danielskiala •

thank you so much

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post

đź‘‹ Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay