Styling native Checkboxes and Radio inputs (CSS Only)
Tags: css, frontend, showdev, beginners
Published: 2020-03-10 19:38:06

---
title: Styling native Checkboxes and Radio inputs (CSS Only)
published: true
description: 
tags: #css #frontend #showdev #beginners
cover_image: https://images.unsplash.com/photo-1478826160983-e6db8c7d537a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80
---

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.

```css
.element {
  appearance: none;
  -moz-appearance: none;
  -webkit-appearance: none;
}
```

## 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:

{% codepen https://codepen.io/felipperegazio/pen/vYOpJvb %}

First lets remove the checkboxes and radios appearance

```css
[type=radio],
[type=checkbox] {
   -webkit-appearance: none;
   -moz-appearance:    none;
   appearance:         none;
}
```

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:

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

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.

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

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

```css
[type=radio],
[type=radio]:checked::before{
  border-radius: 100%;
}
```

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

Cover image by Nadine Shaabana on Unsplash.