How to design a CSS checkbox
Input styling - depending on what input needs to be styled it really can be a pain to work around all the little quirks each input element brings to the table. It goes without saying that the standard html checkbox is definitely one of the more tougher nuts to crack. And I'm not going to lie, this tutorial wont help the fact that checkboxes can't really be styled in a compatible and aestetically pleasing way.

So here's a disclaimer: if you're looking for a way to design checkboxes for browsers other than Firefox, Chrome or Chromium based browsers, you'll have better luck with this method from w3schools.

For everyone else, here is how it should look like:






How it works:


                
                    <input class="checkbox" type="checkbox" data-icon="check">
                
                
            
                .checkbox {
                      -webkit-appearance: none;
                      -moz-appearance: none;
                      appearance: none;

                      background: transparent;
                      border: 2px solid #7d5fff;
                      color: white;
                      margin: 5px;
                      width: 20px;
                      height: 20px;
                      border-radius: 4px;
                      cursor: pointer;
                      position: relative;
                      vertical-align: middle;
                    }

                    .checkbox:after {
                      content: attr(data-icon);
                      width: 20px;
                      height: 20px;
                      line-height: 20px;
                      text-align: center;
                      position: absolute;
                      top: -2px;
                      left: -2px;
                      color: inherit;
                      font-size: 0;
                      font-family: 'Material Icons';
                      transition: 80ms;
                    }

                    .checkbox:checked {
                      background: #7d5fff;
                    }

                    .checkbox:checked:after {
                      font-size: 18px;
                    }

                    .checkbox:disabled {
                      color: #bbb;
                      background: transparent;
                      border-color: #bbb;
                      cursor: default;
                    }

                    .checkbox:disabled:checked {
                      color: white;
                      background: #bbb;
                      border-color: #bbb;
                      cursor: default;
                    }
                
            
First we have to create a normal checkbox with a chosen class and a data-attribute. (In this case "data-icon") I explain why we use the attribute later.

Next up we style the checkbox by first disabling the default browser styling. This is done with appearance: none. Then we are free to design the checkbox to our desire. When we test it now we'll see two things:
Our own styling is applied
The checkmark has disappeared

So now we have to create the checkmark ourselfs. And there the CSS pseudo elements ::before and ::after come in handy. (This is the part where Edge stops playing nice and just goes back to it's standard checkbox design while completely ignoring our styling/appearance properties). Pseudo elements allow us to create two more elements inside the Original DOM element without writing more HTML. They also need to have the content property to be set. And while we could just put a background image in the pseudo-element I decided to use a neat little feature which comes with the content expression. By setting content to attr() we're now able to take any HTML attribute and put it in place of the inner content.

For example: content: attr(class) would give us "checkbox" as text.

With that alone we can use special characters like ✓ or ✗. But we can top this of by using any web-icon-font. In this example I use Googles Material Icons but fonts like Font Awesome should work too. When we now set content to attr(data-icon) and put a valid icon name in the data-attribute (For M.I. it would be "check" or "apps") it displays the icon instead of the text.

To finish this we have to disable the checkmark by default and only show it when the checkbox is checked. You can use font-size: 0px to hide it and set the font-size to something bigger when it's :checked. (Allows you to let it transition)

How you design your checkbox is up to you but with these little tricks it should be easy and fun to do so.

😉