Fun Friday thing! Natalya on CodePen made a super fun Pen.
You know how clicking a <label>
with a for
attribute that matches a checkbox input, it will toggle the input to checked or unchecked? That, combined with the :checked selector in CSS and the sibling combinator forms The Checkbox Hack, and you can use that to do all kinds of fun stuff.
Natalya used it to build a toggle switch where in the off/left position it shows one emoji, and it slides to the on/right position where it switches to a different emoji.
See the Pen Kitty Toggle by Natalya (@tallys) on CodePen.
I thought whittle it down a bit to the most basic level I could, so if you wanted to snag this idea for something you’re working on, you’d have a more clear building block.
See the Pen Emoji Toggles by Chris Coyier (@chriscoyier) on CodePen.
<!-- The wrap for everything, so you can position it wherever.
Also, so all the other elements are siblings. -->
<div class="emoji-toggle emoji-travel">
<!-- The input is first, so the ~ selector can select siblings after it. -->
<input type="checkbox" id="toggle2" class="toggle">
<!-- The emoji is a psuedo element on this. -->
<div class="emoji"></div>
<!-- This is absolutely positioned over everything.
Also, the split/label comes from using both :before and :after -->
<label for="toggle2" class="well"></label>
</div>
The input itself is visually hidden, but absolutely positioned on top of everything so that clicking pretty much anywhere will toggle the checkbox, and thus change the emoji and it’s position.
There is a bit more code than this, but these are the most vital bits of CSS:
.emoji-toggle {
position: relative;
.well { // the label
cursor: pointer;
}
.toggle { // the checkbox
appearance: none;
background: transparent;
position: absolute;
width: 100%;
height: 100%;
cursor: pointer;
z-index: 100;
// "off"
~.emoji:before {
content: "emoji unicode here";
position: absolute;
left: 0;
top: -15px;
font-size: 40px;
z-index: 1;
transition: 0.2s;
}
// "on"
&:checked {
~.emoji:before {
content: "different emoji unicode here";
left: 100%;
margin-left: -1em;
}
}
}
}
Sass for Versions
To make different versions of it, it required changing the pseudo element content on four different selectors with nested states. It was sorta mind-bending, so I made a quick Sass @mixin
to help me. This is the kind of thing I love using preprocessors for – it’s not too fancy, it just helps abstract something that would be very wordy otherwise.
@mixin emojiType($leftEmoji, $rightEmoji, $leftLabel, $rightLabel) {
.toggle {
~.emoji:before {
content: $leftEmoji;
}
&:checked {
~.emoji:before {
content: $rightEmoji;
}
}
~label {
&:before {
content: $leftLabel;
}
&:after {
content: $rightLabel;
}
}
}
}
// Usage
.emoji-happy {
@include emojiType(
"\01F604", "\01F620", "Happy", "Mad"
);
}
Getting Unicode For Emojis
You may have noticed the unicode values for the emojis are like “\01F604” in the CSS content. Fortunately Tim Whitlock has a pretty solid reference page for this info.

So if the unicode for “grinning face” is “U+1F601”, in CSS pseudo content, that becomes “\01F601” because of how CSS escapes stuff.
Mileage My Vary
Emojis are weird. I’ve heard this doesn’t work correctly on all setups. Different browser/platform/versions have different emojis available. I’m sure none of us are surprised.
The first example does not work in chrome (the 2nd emoji does not show up; when I switch to firefox the first example works; but the 2nd example(s) all have the input box visible and above the emoji. On Chrome, the 2nd example’s first line does not have any emojis.
BUT overall a really cool example; one that should work well with icons (like fontawesome) too.
Robert, it may have been fixed in the time between your comment and this reply, but it looks/works fine for me (on OS 10.7, Chrome 45).
Still seeing the issues I reported. Chris said there are some issues with emoji’s on various browsers, so I’m not surprised; and I’m sure a bit of tweaking the css would fix firefox. I’m still convinced this is a great bit of UI — intuitive and user-friendly.
I can confirm the same problem in my Windows 7 PC (only at work, I swear). Anyway, I also enjoyed this example very much!
a ha.
Seems to work fine here.
However I notice that the state can be changed by clicking on the :before and :after content in any order thereby putting it out of sequence as you can click what appears to be the opposing label.
In the second example the one with the five emoji icons it can be overcome by adding this
Even works in IE which is a bonus any day of the week.
Hey Chris! Thanks for taking a look at little Kitty Toggle. I’ll be at CSS Dev Conf this Oct to give you a proper high five in person! 😺
This is what I see on OS X:
And this is what I see on Windows 7:
The OS X “off” emoticon is a lot sadder than the Windows 7 one. This perhaps goes to show why using Unicode emoticons like these is problematic, and I sometimes I wonder whether including them in Unicode was a good idea.
It looks like my screenshots were filtered out! Here they are:
OS X screenshot: https://imgur.com/Tw8PIK7.png
Windows 7 screenshot: http://imgur.com/QVPf93M.png
(Maybe the posting guidelines for comments should mention that images aren’t supported, and the preview tab should not display images if they aren’t go to be in the final comment.)
One issue. People will try to drag and move the switch from side to side rather than just point and click – and moving doesn’t work. Tested on my fellows in company.
HI, I have a questions. Can We change color of these icons , I tried it on windows ,wordpad and I could, but I can’t do it on browser with css.