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.
Animated Checkboxes

From our sponsor: Ship fast and never break a thing with Shortcut (formerly Clubhouse.io).

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>
	<ul>
		<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>
	</ul>
</form>

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:
AnimatedCheckboxes01

The classic check mark for checkboxes:
AnimatedCheckboxes02

A fill drawing for a radio button:
AnimatedCheckboxes03

The filler text in the demo is from Corporate Ipsum.

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

Tagged with:

Mary Lou

ML is a freelance web designer and developer with a passion for interaction design. She studied Cognitive Science and Computational Logic and has a weakness for the smell of freshly ground peppercorns.

http://www.codrops.com

Stay up to date with the latest web design and development news and relevant updates from Codrops.

Feedback 57

Comments are closed.
  1. Hello Mary Lou,
    I wanted to ask if there is a way to apply different animations within the same form.
    I have a form in which there are both checkboxes and radio buttons. How can I do?
    Thank you very much!

  2. Very good,

    Any clever types know how to add play on page scroll/position for the animations?

    It will save me very un-sociable weekend 🙂

  3. Not bad but actually seem to really work in Chrome only. Even Firefox and IE11 (on Win8.1preview at least) on desktop do not work properly. I understand it is a proof of concept but I also guess a lot of people think this works at least on major desktop browsers (even if ignoring mobile) and will not bother to even check. I think a proof of concept for the web should at least work crossbrowser and not single browser only.

    All is not bad as the SVGs at least show: IE11 simple displays ’em without animation, Firefox is actually annoying as it flickers and seems to do the animation several times.
    So it kinda works but as said, for the web it is really an *experiment* and the article should clearly state that it should not be used on any website (yet). Would be nice to develop even experiments a little bit further…

  4. Hi, I’ve enjoyed many of your tutorials..but these really remind me of cheesy flash animations. The best out of all of them I think is the first “X” example…the others, I feel, aren’t subtle enough.

    Thanks for your great work though on all these cool examples.

  5. This is very cool… Exactly what I needed for a project of mine.

    But there is one problem with the script…. The SVG’s doesn’t work when you set some of the checkboxes to be pre-checked.

    Is there an easy way to fix this? 🙂

  6. Thanks this is just what I was searching for. My recent project is now complete! After a few tweaks it works in other browsers besides Google Chrome.

  7. Great tutorial 🙂 I wonder if somebody made it work with dynamically added elements.

  8. PreChecked FIX:
    Change svgcheckbx.js controlCheckbox() function to this:

    function controlCheckbox(el, type, svgDef) {
    var svg = createSVGEl(svgDef);
    el.parentNode.appendChild(svg);

    if (el.checked) { draw(el, type); }
    else {
    el.addEventListener(‘change’, function() {
    if (el.checked) {
    draw(el, type);
    } else {
    reset(el);
    }
    });
    }
    }

    • this will work:

      function controlCheckbox(el, type, svgDef) {
      var svg = createSVGEl(svgDef);
      el.parentNode.appendChild(svg);
      if (el.checked)
      {

      draw(el, type);

      }

      el.addEventListener(‘change’, function() {
      if (el.checked) {
      draw(el, type);
      } else {
      reset(el);
      }
      });

      }

    • This works for both Checkbox & Radio’s preChecked fix :

      function controlCheckbox(el, type, svgDef) {
      var svg = createSVGEl(svgDef);
      el.parentNode.appendChild(svg);
      if (el.checked) {
      draw(el, type);
      }
      el.addEventListener(‘change’, function() {
      if (el.checked) {
      draw(el, type);
      } else {
      reset(el);
      }
      });
      }

      function controlRadiobox( el, type ) {
      var svg = createSVGEl();
      el.parentNode.appendChild( svg );
      if (el.checked) {
      draw(el, type);
      }
      el.addEventListener( ‘change’, function() {
      resetRadio( el );
      draw( el, type );
      } );
      }

    • To change the color and the size of the checkmark go into component.css and on line 103 (stroke: #fdfcd3;) you can change the colour and on 104 (stroke-width: 13px;) you can change the width of the stroke. You can change the actual size of the mark by altering the width and height properties on lines 94 and 95.

  9. This is a really great little script, thanks so much for putting it all together!

    Just a note – I noticed that by default it only works when the required classes are applied to a form element, but I think it would be better to actually make it work with any possible html element. So I ended up removing the form part from the script and now I can apply the classes and use this animation in any element such as a div etc.

  10. Hi,
    Somehow I can reset the check box using jquery below but the SVG graphic does not go away. Text highlight is reset bu the radiobuttton is still decorated. Any idea how to fix this? Here is my code to reset.

    $(‘input[type=radio]’).prop(‘checked’, function () {
    return this.getAttribute(‘checked’) == ‘checked’;
    });

    Great tutorial.
    Mo