Custom radio button using HTML and CSS

List of content

What and Why?

 Pretty same thing I am going to repeat if you ask me why we need a custom radio button element? The default radio button looks like it’s still in the ’90s. I mean, an HTML native radio button doesn’t support modern design (look wise).

Neither with the help of CSS nor with any other trick, the element is aesthetic resistant in itself.

Look and feel of a custom radio button element (UI)

We can design it like anything we want. For the look and feel, you can use any CSS styling or image. For the demo purpose, I have kept it as simple as possible. 

Demo here

custom radio button
custom radio button

But that won’t restrict you from designing it to anything you want. I am going to discuss the basic concept here, using that you can achieve all kind of designs for your custom radio element using HTML and CSS. Fair enough?

The behaviour of a custom radio element (UX)

First thing first, we have to understand where we should use a radio button. Well, we use it when there is only one option to select out of many.

Demo here

So, keep that in mind and never design it like a checkbox. You can if you want, but it is not worth the misrepresentation in UX.

Coming to the custom radio button component, we will be using a radio in the background. We are going to hide the default element and replace it with an image or CSS, whichever is suitable in your case.

You may ask, how this new image or CSS component would respond to our click event? Good question.

I said we are going to hide the element, but what we will keep is the label of that element. Then, will use a “:before” or “:after” CSS pseudo property to append our custom design before or after the label itself. 

The good thing about a label is that the click event to select a radio button would work if we click on the label. Hence, clicking on the label will set the checked property of the native radio button element to true or false. 

Rest is the CSS property, where we will manipulate the checked property to show our desired image or CSS accordingly.

File Structure


<!DOCTYPE html>
<link rel="stylesheet" type="text/css" href="./style.css">
   <p>Q. During what time of the day do you feel more productive?</p>
        <input type="radio" id="em" name="radio-group">
        <label for="em">Early Morning</label>
        <input type="radio" id="md" name="radio-group">
        <label for="md">Mid Day</label>
        <input type="radio" id="ln" name="radio-group">
        <label for="ln">Late Night</label>
         <input type="radio" id="ln2" name="radio-group">
         <label for="ln2" class="checkmark">Late Night</label>


[type="radio"]:not(:checked) {
    position: absolute;
    left: -9999px;
[type="radio"]:checked + label,
[type="radio"]:not(:checked) + label
    position: relative;
    padding-left: 28px;
    cursor: pointer;
    line-height: 20px;
    display: inline-block;
    color: #666;
[type="radio"]:checked + label:before,
[type="radio"]:not(:checked) + label:before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    width: 18px;
    height: 18px;
    border: 1px solid #ddd;
    border-radius: 100%;
    background: #fff;
[type="radio"]:checked + label:after
/*[type="radio"]:not(:checked) + label:after*/ {
    content: '';
    width: 12px;
    height: 12px;
    background: #3396fe;
    position: absolute;
    top: 4px;
    left: 4px;
    border-radius: 100%;
    -webkit-transition: all 0.2s ease;
    transition: all 0.2s ease;
[type="radio"]:not(:checked) + label:after {
    opacity: 0;
    -webkit-transform: scale(0);
    transform: scale(0);
[type="radio"]:checked + label:after {
    opacity: 1;
    -webkit-transform: scale(1);
    transform: scale(1);