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.
Super clever!