How To Style Checkbox And Radio Buttons Using CSS

Temani Afif

Written by Web Developer

April 17, 2022
How To Style Checkbox And Radio Buttons Using CSS

We all agree that the default styles applied to input elements like checkbox and radio aren’t that good. They are also different between browsers. For this reason, we always tend to update the default styles to create our design.

In this post, we will study CSS techniques that allow us to update the style of such elements without extra HTML code. Yes, we are going to give a fresh look to our <input> elements using only CSS!

In this post, I will focus on the CSS part so all the demos will include only the <input> elements for simplicity.

Styling Radio Buttons CSS Tricks


Let’s start with a basic example:

As you can see in the demo, I am not adding any extra HTML code. Only a few lines of CSS are needed.

The first step is to disable the default browser styles using the following code:

input {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
}

Now, we have a “naked” radio button that we can style as we want. What I am doing next is pretty simple. I am giving the checkbox a dimension, a border, and some padding:

input {
  width: 40px;
  height: 40px;
  border: 5px solid grey;
  padding: 5px;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  cursor:pointer;   /* don't forget this as well */
}

Then, I am using the :checked pseudo-class to update the style when the element is checked

input:checked {
  background: green content-box;
  border-color: green;
}

I am adding a background that will cover only the content area (thanks to content-box) leaving a gap with the border. I am also giving the border a green color. That’s all!

This basic example illustrates how we can style a radio element without using any extra element. Of course, we will not stop there. We are going to add more CSS to have a better design.

Let’s update the previous example by introducing some CSS variables and transitions:

input {
  --s: 40px;
  
  width: var(--s);
  aspect-ratio: 1; /* OR height: var(--s) for old browsers */
  border: calc(var(--s)/8) solid var(--_c,grey);
  padding: calc(var(--s)/8);
  background: var(--_c,#0000) content-box;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  cursor: pointer;
  transition: .3s;
}
input:checked {
  --_c: green;
}

Instead of setting each property individually, I define one variable (--s) that I use to set the dimension, padding, border, etc. By only adjusting that variable, we can easily control the overall size.

I am doing the same with the coloration. Since the border and background need to be green on checked, I am defining one variable for that purpose.

Let’s consider a more fancy animation

Things start to get more funny! Instead of simply changing the colors, we are having a size animation of the inner part.

To do this, I am using a gradient instead of background color and I am changing the background-size on :checked

input {
  --s: 40px;
  --c: green;
  
  width: var(--s);
  aspect-ratio: 1;
  border: calc(var(--s)/8) solid var(--_c,grey);
  padding: calc(var(--s)/8);
  background: linear-gradient(var(--c) 0 0) 50%/0 0 no-repeat content-box;
  transition:.3s;
}
input:checked {
  --_c: var(--c);
  background-size: 100% 100%;
}

Notice the usage of another variable that allows me to control the color as well.

For the rounded radio button, we need a radial-gradient instead of a linear one

.round {
  border-radius: 50%;
  background: radial-gradient(farthest-side,var(--c) 96%,#0000 ) 50%/0 0 no-repeat content-box;
}

Let’s add an effect to the border:

In addition to the gradient, I am using an outline:

input {
  --s: 40px;
  --c: green;
  
  border: calc(var(--s)/8) solid grey;
  outline: calc(var(--s)/8) solid var(--_c,#0000);
  outline-offset: calc(var(--s)/4);
}
input:checked {
  --_c: var(--c);
  background-size: 100% 100%;
  outline-offset: calc(var(--s)/-8);
  border-color: #0000
}

I am defining an outline equal to the border width. Initially, the outline color is transparent and the offset is a positive value expressed with the variable --s. On :checked, I change the color of the outline, I make the offset negative to create an overlap with the border and I change the color of the border to transparent.

We have a cool radio button with only CSS a stated in the introduction. Not only this, but we can easily adjust things using CSS variables.

Below two more examples to show a full code including custom radio buttons

Styling Checkbox CSS Tricks


Styling a checkbox is the same as styling a radio button. The only difference between both is their functional part which is out of the scope of this post.

For this one, I will focus on my favorite design which is the toggle (also called switch)

input {
  --s:40px;
  
  height: var(--s);
  padding: calc(var(--s)/10);
  box-sizing: content-box;
  aspect-ratio: 2;
  border-radius: var(--s);
  background:
    radial-gradient(farthest-side,#fff 97%,#0000) 
     left/var(--s) 100% content-box no-repeat,
    grey;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  cursor: pointer;
  transition: .3s;
}
input:checked {
  background-position: right;
  background-color: green;
}

Like all the previous examples, we are going to use a CSS variable to control the size and then a gradient for the main trick.

At first glance, it may look difficult but the trick is pretty simple. We use a radial-gradient to create a circle placed on the left side within the content area (thanks to content-box). The padding will define the gap between the circle and the edge. On :checked we update the position to the right which will create the sliding effect thanks to the transition. As simple as that!

Let’s not forget about changing the background-color to green or whatever color you want to show the checked state.

Let’s consider another idea of a checkbox

input {
  --s:80px; /* adjust this to control the size*/
  
  height: var(--s);
  aspect-ratio: 2;
  padding: calc(var(--s)/5);
  border-radius: var(--s);
  background:
    radial-gradient(farthest-side,#fafafa 85%,#0005,#0000) left/var(--s) 100% no-repeat,
    linear-gradient(90deg,#20b68f 50%,#939393 0) right/200% 100% content-box;
  transition: 0.5s;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  cursor: pointer;
}
input:checked {
  background-position: right,left;
}

For this one, we are going to rely on two gradients. Like the previous one, a radial-gradient will create the circle. For the main background, we will consider a linear-gradient.

Below is an illustration to see how the bottom gradient behaves.

The linear-gradient has a width equal to twice the element width (the 200%) defined with two colors (the grey and green one) then we slide it from left to right as we do with the circle. Since it’s a background, we won’t see its overflowing part.

As you can see, using the same technique (background and gradients) we made 2 different checkbox using only the input element. And this is only a small overview of the possibilities. We can push the limit of CSS and create more fancy checkbox.

Here are a few more examples I recently made:

Conclusion


Thanks to modern CSS techniques we no more need to rely on hacks or a ton of HTML code to create fancy checkbox and radio buttons. All that is needed is the native input element and our creativity to get almost any design we want.

Check out our hosting options. We offer plans for WordPress, cloud hosting, managed cloud servers, and more, all of which can help you ensure your website is built on a strong foundation.

Frequently Asked Questions


Can you migrate my existing website over?

Yes, and without issue. Regardless of how many websites you’re managing, we’ll bring all of them under the Verpex wing free of charge. Just send us the details of your websites when you’ve signed up to get started.

If I move my site to Verpex do I need to change domain name?

No, we make the transfer process easy and you can keep your current domain name.

How do I choose a design for my website?

One of the most important things when creating a website for your art is the design. Even though your pieces of art might be amazing, people will leave if your site is hard to navigate. This is why it’s important that the site is easy on the eyes and easy to navigate.

Will you be able to fully restore the website if something goes wrong?

Should anything happen, your website can be restored fully with the help of JetBackup5

How can I monitor the bandwidth usage of my accounts?

To monitor the bandwidth usage of your resold accounts, go to WHM -> View Bandwidth Usage

Affiliate program vs reseller hosting: what is the difference? which is better?

Both have advantages and disadvantages and one isn’t better than the other. Rather, each will be better in different circumstances. Those looking to build a business should try reselling, while those wanting passive income should become affiliates. You can learn more about the differences between reseller hosting and affiliate programs on our blog.

How can I create custom plans for each individual account?

You can get the step-by-step procedure to create custom plans for an individual account in this guide

Is there a money-back guarantee?

Yes, Verpex offers a 45-day money-back guarantee if you're not satisfied with your eCommerce hosting.

Temani Afif
About the Author
Temani Afif

Temani Afif is an expert web developer, a content creator, and a CSS addict. He is the mastermind behind css-challenges.com, css-generators.com, css-only.art, css-articles.com, and a lot of CSS stuff. He's also an active contributor at Stack Overflow answering all kinds of CSS questions.

View all posts by Temani Afif
Discount

Enter Discount Code MOVEME During The SIGN UP Process To Get 90% Off Your First Month

with the discount code

MOVEME

Use Code Now
Jivo Live Chat