Animating Checkboxes and Radio Buttons with Sprite Sheets

Sprite sheets can be used to create animated checkboxes and radio buttons without any Javascript. Click the checkbox below to see it in action.

Background

A sprite sheet animation is created with a single image containing multiple frames side by side. The image is clipped to show one frame at a time. Changing the clip position from frame to frame creates an illusion of animation.

Typically, sprite sheet animations are created in HTML by using the sheet as a background image and then moving the background position to reveal different frames. The sprite sheet must be made of equal-sized frames arranged in a single row or column. Below you can see a sprite sheet with 11 frames in a row. Each frame is 50px × 50px.

Star sprite sheet

Only one frame is show at a time by clipping the background image. The clipping is shown by the blue rectangle below. Move the slider to see how the background position affects which frame is shown inside the clipping rectangle. The background image is repeated. The first frame would show up again if the background position value gets too high. The image below is 550px wide (11 × 50px), so -500px is the position of the last frame.

background-position: 0px

The sprite sheet can be a PNG or SVG image. The benefit of PNG is that it looks the same in all browsers. The benefit of SVG is that it is resolution independent and stays crisp if the page is zoomed in or it is shown on HiDPI screens.

Sprite sheets are not the only way to create animations for web pages. CSS animations, CSS transitions, Javascript animations and animated GIFs all have their own use cases. Sprite sheets are good if:

  • a CSS-only solution is desired
  • complex animations are needed (CSS transitions can only display a transition between two values)
  • older browsers need to be supported (sprite sheets can be made to work in IE11 and IE10)
  • animation needs to be run when needed (playback of animated GIFs can’t be controlled)

There’s always many ways to do things in HTML and CSS, so you may find alternate ways to style checkboxes and radio buttons. The solution given here is only one option.

Creating Sprite Sheets in Keyshape

You can export PNG or SVG sprite sheets in Keyshape with these steps:

  1. Select the File > Export menu command.
  2. Select either SVG or PNG format.
  3. Select Sprite Sheet as the animation type.
  4. Choose the begin and end times. Usually, the defaults values are good here.
  5. Choose the frame rate. Usually, the default frame rate is fine.
  6. Select the Single Row algorithm.
  7. Press the Export button.

The Keyshape file for the star sprite sheet can be found at the bottom of this page.

When you play back the animation in Keyshape, check the Animation > Stepped Playback option to enable frame-by-frame playback. That ensures that the animation is played back the same way it will look after exporting it as frames.

Styling Checkboxes

Here’s the animated checkbox again:

To use sprite sheets in checkboxes, the appearance property is set to none. It removes the native look and allows background images to be used instead. When the checkbox is pressed, the background is animated. Here’s HTML code for it:

<input id="my-checkbox-id" class="my-checkbox" type="checkbox"><label for="my-checkbox-id">Animated Checkbox</label>

Below is the CSS code for it. When you use this with your own sprite sheets, you need to change some of the values:

  • Change the background url to point to your sprite sheet image
  • Change all widths and heights to match the exported document size (50px × 50px in this example)
  • Change background-position to the exported sheet width minus one frame size (550px - 50px = 500px in this example, the value needs to be negative: -500px)
  • Change the transition time to the exported end time (0.5s in this example)
  • Change the transition steps to the total frame count minus one (11 - 1 = 10 in this example)
.my-checkbox {
  background: url('my-sheet.svg');  /* CHANGE this to your sprite sheet filename */
  width: 50px;              /* CHANGE this to your document width */
  height: 50px;             /* CHANGE this to your document height */
  -webkit-appearance: none; /* removes native look of the checkbox for Safari */
  appearance: none;         /* removes native look of the checkbox */
  vertical-align: middle;
}
.my-checkbox:checked {    /* styles the checkbox checked state */
  background-position: -500px;
  transition: background-position 0.5s steps(10, start);
}

Note that the above doesn’t include a style for a disabled state and it should be added if needed.

Styling Radio Buttons

Radio buttons can be styled the same way as checkboxes. Here’s three buttons with the star animation.




Here’s the HTML code for the radio buttons:

<input id="my-radio-1" class="my-radio" type="radio" name="my-group"><label for="my-radio-1">First</label><br>
<input id="my-radio-2" class="my-radio" type="radio" name="my-group"><label for="my-radio-2">Second</label><br>
<input id="my-radio-3" class="my-radio" type="radio" name="my-group"><label for="my-radio-3">Third</label><br>

The label element is optional, but consider accessibility if you leave it out.

Again, the appearance property is set to none and the background property is animated.

.my-radio {           /* styles for the radio button */
  background: url('my-sheet.svg');  /* CHANGE this to your sprite sheet filename */
  width: 50px;              /* CHANGE this to your document width */
  height: 50px;             /* CHANGE this to your document height */
  -webkit-appearance: none; /* removes native look of the checkbox for Safari */
  appearance: none;         /* removes native look of the checkbox */
  vertical-align: middle;   /* used to align radio button with label */
}
.my-radio:checked {      /* styles the radio button checked state */
  background-position: -500px;      /* CHANGE to sprite sheet width minus one frame width */
  transition: background-position 0.5s steps(10, start); /* CHANGE time and steps */
}

Compatibility for older browsers and Internet Explorer 11

The code above works in all modern browsers, but if support for older browsers is needed, then more code needs to be written.

Here’s an animated checkbox with better compatibility.

The HTML code for the checkbox looks like this:

<input id="my-checkbox2-id" class="my-checkbox2" type="checkbox"><span></span> <label for="my-checkbox2-id">Animated Checkbox</label>

Since the appearance property isn’t supported by older browsers, there’s an extra <span> element after the input element to display the animation. The <label> element is optional. Again, consider accessibility if you leave the label element out.

The idea is that the input element is made invisible by changing its opacity. That hides it, but keeps it accessible for focusing and screen readers. Then, the span element is moved over the input element and styled with a background image. The span element width and height are set to the size of one frame to clip the background image. When the checkbox is checked, the background position is animated in steps to the last frame position.

The CSS code to style the checkbox is shown below with comments.

.my-checkbox2 {              /* styles for the checkbox */
  width: 50px;              /* CHANGE this to your document width */
  height: 50px;             /* CHANGE this to your document height */
  opacity: 0;               /* this hides the native checkbox */
  vertical-align: middle;   /* used to align checkbox with label */
}
.my-checkbox2+span {         /* styles the span element after the checkbox */
  background: url('my-sheet.svg');  /* CHANGE this to point to your image */
  width: 50px;              /* CHANGE this to your document width */
  height: 50px;             /* CHANGE this to your document height */
  margin-left: -50px;       /* CHANGE this to your document width, this moves span element over checkbox */
  display: inline-block;    /* this is needed to get width, height and margin functional */
  pointer-events: none;     /* this passes mouse clicks through to underlying checkbox */
  vertical-align: middle;   /* used to align checkbox with label */
}
.my-checkbox2:checked+span {         /* styles the checkbox checked state */
  background-position: -500px;      /* CHANGE to sprite sheet width minus one frame size */
  transition: background-position 0.5s steps(10, start); /* CHANGE time and steps */
}
.my-checkbox2:focus+span {   /* focus style for keyboard users */
  outline: 2px solid #87ceeb;
}

Accessibility

If you have a checkbox or radio button without a label, then you should use an aria-label attribute to describe the meaning of the button. Normal browsers won’t display aria-label, but assistive technologies, such as screen readers, can use it. Here’s examples:

<input id="my-favorite-checkbox" class="my-checkbox" type="checkbox" aria-label="Favorite item">

<input id="my-radio-1" class="my-radio" type="radio" name="my-group" aria-label="First">

Keyshape Files

Document History

- Changed to use the appearance property.
- Changed to use classes for styling.
- Document created.