Animated Checkboxes and Radio Buttons with SVG

By animating an SVG path with JavaScript, we can do many fancy things. Today we want to show you some effects for checkboxes and radio buttons. The idea is to hide the inputs, use pseudo-elements to create a more appealing style and then animate the SVG paths once an input is selected.

Today we’d like to share some fancy “check” animations for checkboxes and radio buttons with you. The idea is to animate an SVG to create a nice visual effect for selecting a checkbox or radio input. There are many possibilities for the animated graphic, like a cross, a check mark, a circle and so on. The technique for animating the SVG paths is by Jake Archibald and you can read how it works in detail in his article Animated line drawing in SVG.

Please note that this is just a proof-of-concept and not a complete solution. The SVG path transition might not work in all browsers, especially mobile ones.

For the custom checkbox or radio button we use the ::before pseudo-element of the label and we hide the input by setting the opacity to 0. It’s actually there, on top of the pseudo-element, so that we can simply click on it and retain the default input selection behavior. We also make the label clickable by setting the value of the for attribute to the ID of the input.

Initially, we also add the necessary SVG elements after the inputs with JavaScript. They won’t be visible because their paths are empty; once we select an input, we’ll animate the paths with an appropiate transition.

Here is an example of a form structure:

<form class="ac-custom ac-checkbox ac-cross">
	<h2>How do you collaboratively administrate empowered markets via plug-and-play networks?</h2>
		<li><input id="cb1" name="cb1" type="checkbox"><label for="cb1">Efficiently unleash information</label></li>
		<li><input id="cb2" name="cb2" type="checkbox"><label for="cb2">Quickly maximize timely deliverables</label></li>
		<li><input id="cb3" name="cb3" type="checkbox"><label for="cb3">Dramatically maintain solutions</label></li>
		<li><input id="cb4" name="cb4" type="checkbox"><label for="cb4">Completely synergize relationships</label></li>
		<li><input id="cb5" name="cb5" type="checkbox"><label for="cb5">Professionally cultivate customer service</label></li>

We are using an unordered list with the inputs and labels.

The core styles for making the input invisible and creating the box out of the pseudo-element is the following:

.ac-custom label {
	display: inline-block;
	position: relative;
	font-size: 2em;
	padding: 0 0 0 80px;
	vertical-align: top;
	color: rgba(0,0,0,0.2);
	cursor: pointer;
	transition: color 0.3s;

.ac-custom input[type="checkbox"],
.ac-custom input[type="radio"],
.ac-custom label::before {
	width: 50px;
	height: 50px;
	top: 50%;
	left: 0;
	margin-top: -25px;
	position: absolute;
	cursor: pointer;

.ac-custom input[type="checkbox"],
.ac-custom input[type="radio"] {
	opacity: 0;
	display: inline-block;
	vertical-align: middle;
	z-index: 100;

.ac-custom label::before {
	content: '';
	border: 4px solid #fff;
	transition: opacity 0.3s;

When an input get’s checked, we’ll animate the opacity of the “pseudo-checkbox” and the color of the label:

.ac-custom input[type="checkbox"]:checked + label,
.ac-custom input[type="radio"]:checked + label {
	color: #fff;

.ac-custom input[type="checkbox"]:checked + label::before,
.ac-custom input[type="radio"]:checked + label::before {
	opacity: 0.8;

As you can see, we are using the adjacent sibling selector for targeting the label and its pseudo element. This can be buggy in some browsers so you might want to add the input inside of the label like shown in example B on the label Wiki page: HTML/Elements/label – W3C Wiki.

We noticed a small glitch for the last example in Firefox (24.0) on Mac. For some reason the end of the SVG drawing is shortly shown before it gets animated.

Here are a couple of screenshots of some of the styles:

A hand-drawn circle around a radio button:

The classic check mark for checkboxes:

A fill drawing for a radio button:

The filler text in the demo is from Corporate Ipsum.

I hope you enjoyed these animations and find them inspiring and useful!

Tagged with:

Manoela Ilic

Manoela is the main tinkerer at Codrops. With a background in coding and passion for all things design, she creates web experiments and keeps frontend professionals informed about the latest trends.

Stay in the loop: Get your dose of frontend twice a week

👾 Hey! Looking for the latest in frontend? Twice a week, we'll deliver the freshest frontend news, website inspo, cool code demos, videos and UI animations right to your inbox.

Zero fluff, all quality, to make your Mondays and Thursdays more creative!

Feedback 57

Comments are closed.
  1. Where is the actual part about using the SVG though? I see in the code demo that you are adding/removing markup to the SVG code based on the “change” event, but where are you firing the event? I feel like there are missing pieces to the puzzle here…

  2. Trying to get this to work with a newer version of modernizr and can’t figure out which options should be checked. can you help?