Styling HTML checkboxes only with CSS

No comments

Styling HTML checkboxes only with CSS

These days' web designs are usually more important than functionality or content itself and It's a real nightmare for every developer to realize dreams of designers. Those usually involve some super fancy styling over checkboxes, radio buttons or other input types which style can't be overridden because it's locked by browser.

Fortunately to keep functionality of one, they don't need to be styled, they can be easily faked with some HTML and CSS.

As checkboxes won't be restyled but will be faked, we're gonna need some HTML. Label will be needed as it supports for attribute which is used to connect click events on the text to checkboxes or radios. In addition, another element will be needed that will act as a checkbox. In my example I used span tag. Entire HTML code for new checkbox is below.

<input type="checkbox" id="checkbox-styled" />
<label for="checkbox-styled">
    <span></span>Checkbox After

Don't forget to link label and checkbox by setting label's for attribute to the same value as input's id (and make that value unique!). Otherwise click event won't be forwarded to the checkbox, therefore always receiving false or unchecked value in code logic. That's one of those stupid mistakes you can debug for hours.

Once the HTML structure is ready it is time to get rid of that ugly checkbox.

input[type="checkbox"] {

Half of the problem is now gone. Ugly checkbox is now gone, and if you click the text value will be correctly updated just not yet shown anywhere. Now let's make it pretty.

input[type="checkbox"] + label span:first-child {
    background: white;
    -webkit-box-shadow: 0px 0px 1px 1px #ddd ;
    -ms-box-shadow: 0px 0px 1px 1px #ddd ;
    box-shadow: 0px 0px 1px 1px #ddd ;
    cursor: pointer;
    vertical-align: middle;
    text-align: center;

The + selector might be strange for some. It means the next sibling. With it you can only target labels and spans that are next to a checkbox, so that anything else isn't overridden accidentally. The rest of it is usual CSS. display: inline-block is necessary so that everything is nicely aligned and that width and height aren't ignored which too are necesary.  As an additional eye candy I added some shadow and a cursor when user hovers over it making it more authentic.

Now only checked state is missing.

input[type="checkbox"]:checked + label span:first-child:before {
    content: "✔";
    color: #d9230f;

As always I tried to avoid images so I used Unicode symbol instead. It might not work on some operating system like fully stripped Linux PC's, but I can live with that. If you want to support anyone you can add SVG inside content or just set the background-image CSS property.

And a couple of more symbols for easy copy and paste:

Leave a Reply

Your email address will not be published.

Time limit is exhausted. Please reload CAPTCHA.