Thursday, February 27, 2014

super pretty toggle checkboxes in css

Unfortunately I couldn't jam in enough CSS on Blogger/Blogspot to make this work inline in this bog entry, so I direct you to: and please "view source".

There you see 10 checkboxes.

The first is a boring checkbox: click on the box, a check appears.

The second adds the checkbox caption in a <label> tag.  I give the checkbox an id and then use the for attribute of the label to tell it what checkbox it refers to. But now you can click on the caption, which makes a much bigger hit area, and is a good UI practice. (It also makes thing better for screenreaders and other software, since the reader knows just what the caption refers to)

The third actually simplifies things: by putting the checkbox inside the label, we get rid of the need to id the checkbox or use the for attribute. (I didn't realize before today that you could do this nesting.)

Fourth just shows that the label appearing to the right of the checkbox is just a convention: now the whole area is clickable.

Example Five has us putting an arbitrary div inside the label, and showing that it too is part of clickable space.

Example Six gets interesting again.  The CSS for the clickable div is:
.example6 { 

The "~" tilde selector is less used than some selectors, and a bit odd. It says "any sibling following this one"-- order is important! (And :checked is a virtual selector for when the checkbox is checked). Net-net: a class "show" sibling of the checked input is background green, not red. We've reinforced the state set by the checkbox.

Example 7 shows that we can hide the checkbox itself. The code I'm borrowing from didn't use display:none, which I think might give a screenreader the wrong idea. Instead, it uses the more purely visual property "opacity". It also changed it to "position:absolute", so it didn't disrupt the flow of the other element parts.

Example 8 makes the display into a proper toggle. I had to do a little layout fudging to get this to work (in part to ensure the sibling relationship was preserved for both the background "show" and the moving toggle... CSS doesn't really support "parent" selectors, so there's no such thing as the "uncle" which I really wanted, so that the toggle could be a child of the show)

Example 9 specifies a CSS "transition" for the any changes to to the left property: (in a "cover all your bases for older browsers" sort of way)
.example9 .toggle {
-webkit-transition: left 0.3s ease-out;
-moz-transition: left 0.3s ease-out;
-ms-transition: left 0.3s ease-out;
-o-transition: left 0.3s ease-out;
transition: left 0.3s ease-out;
I've talked about jQuery transitions before...  CSS offers fewer options but still its nice to be able to make these effects in pure CSS.

Finally, 10 uses some rounded corners to make a slight less edge-y switch.

So what I found less familiar was the use of labels to create clever clickable areas, using a sibling relation to make an alternate representation of checkbox state, and then I'm slightly playing catch up with CSS transitions (most of my time diving into HTML5 was spent where jQuery was readily at hand, but I absolutely see the appeal of keeping such gloss in the CSS and out of the javascript code.)

1 comment: