Custom checkboxes with CSS

Along similar lines to this post on radio controls in forms, we can simply style checkboxes by using :after or :before pseudo-elements on the controls label.

The HTML

 <input type="checkbox" class="form__checkbox" id="checkbox1" />
 <label for="checkbox1" class="my-label">Checkbox 1</label>

SCSS

 &:checked + .my-label:before {
   // the on styling for the box, using a url for a tick
   content: url( ... );
 }

.my-label {
 ...
 &:before {
  // The 'unchecked' styling for the box
  ...
 }
}
Screenshot of unchecked checkbox demo
Unchecked checkboxes
Screenshot of checked checkbox demo
Checked checkbox

See it in action with this CodePen demo.

Custom radio buttons with CSS

Using a combination of :after and :before selectors on the controls <label> to position pseudo-elements over the real form control.

This selector lets us use the :checked state of the element to apply a style to the controls label:


  // SCSS
  .checkbox:checked + .checkbox-label:after {
    // ... adds a 'spot' to indicate checked status
  }

We then also need to make sure we handle focus on the control so that our fancy styling can also indicate state on keyboard navigation:


  // SCSS
  .checkbox:focus + .checkbox-label:before{
    // ... add some styling to indicate focus/keyboard nav
  }

Here’s a demo of solution on CodePen

Customise radio buttons with only CSS

Dev notes

I’m not a huge fan of heavily customised form elements due to the huge variety of implementations of form controls on different devices. For example, how <select> elements are handled on mobile vs. desktop. Avoid the pain of trying to fix countless display bugs and keep your form customisation as simple as possible.

Animated CSS reveal on page load

I’m still playing with animations on page load and put together a little demo and some notes.

What do we want to animate?


@keyframes fadeinanimation {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

Now we can apply the animation to our elements (the .fadein class):


  .fadedin {
    opacity: 0;
    animation: fadeinanimation ease-in 1;
    animation-fill-mode: forwards;
    animation-duration: 1s;
    animation-delay: .2s;
 }

See it in action:

http://codepen.io/shellbryson/pen/pRJqxj