HTML5 CSS Crossview

A couple weeks ago while browsing reddit I stumbled across a very cool Android UI button that I thought was genius. https://github.com/cdflynn/crossview  In particular this element would be great for lists where you want to add or remove options, like a choose your toppings list for a burger, add or remove toppings.

I thought that this would be a great time to learn about CSS transitions and make a version of the element in HTML5 and CSS with as little JavaScript as I possibly could. My first few attempts managed to get the cross to appear and then when applying

tranform: rotate(45deg);

I got a nasty little issue because the center of the 2 elements that I was rotating were in different places and it just didn’t work at all. I contacted my CSS guru friend over at scottlittle.me and asked for some advice. He pointed me towards using a label and attaching it to a checkbox to handle the toggle states. to handle the centering of the cross we figured out a method of using ::before and ::after pseudo elements.

It took me a little while to work out the details but I managed to come up with something that worked well. Using a combination of the label, :before and :after pseudo selectors in addition to a :checked selector I was able to make the whole element work without any JavaScript. An added bonus to the methods I found was that it scales very well simply by changing the width and height of the label. I was hoping to be able to wrap the whole thing up in some easy to use package but when I looked at Web Components support on Can I Use, things looked quite abysmal. I may eventually look to wrap this up as a Polymer Element once Polymer hits 1.0 (breaking changes are expected between 0.9 and 1.0).

Here is the final product:

Go ahead and click on it to go between adding or removing an option. And since this is just a hidden checkbox plus a label it will submit just like a checkbox!
I don’t have IE9 to run this on but looking at caniuse.com and MDN, this should support everything going back to IE9 (plus I added the necessary vendor prefixes for Safari and IE)

*Feature image taken from cdflynn’s github, linked above.

Here’s the css I used:

input.add-remove[type=checkbox]{
  display:none;
}

input.add-remove[type=checkbox] + label{
  width:40px;
  height:40px;
  display:inline-block;
  position:relative;
  z-index:1;
}

input.add-remove[type=checkbox] + label:before {
  content:"";
  left: 50%;
  width: 10%;
  margin-left: -5%;
  position:absolute;
  z-index:-1;
  height: 100%;
  color: #ccc;
  background:red;
  font-style: italic;
  -webkit-transition:-webkit-transform .3s;
  transition:transform .3s;
} 

input.add-remove[type=checkbox] + label:after {
  content:"";
  position:absolute;
  top: 50%;
  height: 10%;
  margin-top: -5%;
  width: 100%;
  background:red;
  z-index:-1;
  color: #ccc;
  font-style: italic;
  -webkit-transition:-webkit-transform .3s;
  transition:transform .3s;
}

input.add-remove[type=checkbox]:checked + label {
  color: #f00;
  font-style: normal;
  z-index:1;
}

input.add-remove[type=checkbox]:checked + label:before {
  -webkit-transform:rotate(-45deg);
  -ms-transform:rotate(-45deg);
  transform:rotate(-45deg);
} 

input.add-remove[type=checkbox]:checked + label:after {
  -webkit-transform:rotate(135deg);
  -ms-transform:rotate(135deg);
  transform:rotate(135deg);
}

You can get this and the alternate version (remove-add and add-remove) together from my Github project for this element here.

One thought on “HTML5 CSS Crossview

Leave a Reply

Your email address will not be published. Required fields are marked *