Wednesday, February 24th, 2010

Custom checkbox and radio buttons using CSS

Category: CSS

In my never ending quest to find weird and wonderful ways to abuse CSS and all its little intricacies, I have come up with a pretty good way of using CSS to create custom radio and checkbox inputs without JavaScript, that are accessible, keyboard controlled, don’t use any hacks and degrade nicely in non supporting browsers. The journey wasn’t easy and I was on the brink of filing it in the “to crazy” folder, never to be seen again. Luckily I had a brain wave that paid off and actually allowed this to be a very viable solution that degrades beautifully and works in 80% of the browsers. This is my story.


Ryan “the CSS Ninja” goes from here to explain his quest which includes fun CSS such as:

  1. p:not(#foo) > input + label:before
  2. {
  3.     background: url(gr_custom-inputs.png) 0 -1px no-repeat;
  4.     position: absolute;
  5.     z-index: 2;
  6.     left: 16px;
  7.     content: "\00a0\00a0\00a0"; /* 3x   */
  8.     overflow: hidden;
  9.     width: 16px;
  10.     height: 16px;
  11.     margin: 0 3px 0 -16px;
  12. }
  14. p:not(#foo) > input[type=radio]:checked + label:before {
  15.     background-position: -32px -73px;
  16. }
  18. input[type=radio]:hover + label:before,
  19. input[type=radio]:focus + label:before {
  20.     background-position: -32px -19px;
  21. }
  22. input[type=radio]:hover:checked + label:before,
  23. input[type=radio]:focus:checked + label:before {
  24.     background-position: -32px -91px;
  25. }
  26. input[type=radio]:hover:disabled + label:before,
  27. input[type=radio]:focus:disabled + label:before {
  28.     background-position: -32px -55px;
  29. }
  30. input[type=radio]:hover:disabled:checked + label:before,
  31. input[type=radio]:focus:disabled:checked + label:before {
  32.     background-position: -32px -127px;
  33. }
  34. input[type=radio]:active + label:before {
  35.     background-position: -32px -37px;
  36. }
  37. input[type=radio]:active:checked + label:before {
  38.     background-position: -32px -109px;
  39. }

He also reminded me of pointer events:

The CSS property pointer-events allows authors to control whether or when an element may be the target of a mouse event. This property is used to specify under which circumstance (if any) a mouse event should go “through” an element and target whatever is “underneath” that element instead.

There is a lot of Ninja in this one. Nice job.

Posted by Dion Almaer at 6:32 am

3.9 rating from 78 votes


Comments feed TrackBack URI

Ouch. That’s hardcore CSS.

Btw, you’ve got a weird overflow on the left side of your code box – the numbers are getting chopped off.

Comment by Skilldrick — February 24, 2010

Once again the thorn in the side (IE) of most commercial web developers ruins the party

Comment by RoryH — February 24, 2010

Regarding what Skilldrick said:

This overflow can be fixed by changing the padding-left value of the rule

#maincontent ol {… }

from 20px to 30px

Regards, NicBright

Comment by NicBright — February 24, 2010

Exploration and experimentation are awesome, nice work! Don’t listen to the developers that would rather climb into the coffin that IE7 and IE6 have prepared for them.

PS: You guys really should add the link to the source in the article.

Comment by zachleat — February 24, 2010

No wonder I didn’t realise my article got on here, no link love. Thanks ck2 for posting the link.

Comment by Ahrjay — February 24, 2010

…And must of been in their queue for a while, article has since been updated to use a single sprite image.

Comment by Ahrjay — February 24, 2010

check out these custom css3 forms. Webkit browser needed!

Comment by iwebkit — March 27, 2010

it removed my link. anyway here it is:

Comment by iwebkit — March 27, 2010

Leave a comment

You must be logged in to post a comment.