<div>
<label class="switch smiley">
<input type="checkbox" checked>
<span>Smiley</span>
<svg viewBox="0 0 16 16">
<circle cx="10.5" cy="5.5" r="1.5"></circle>
<circle cx="5.5" cy="5.5" r="1.5"></circle>
<path d="M1,3 C1.55228475,3 2,2.55228475 2,2 C2,1.63181017 1.66666667,0.9651435 1,0 C0.333333333,0.9651435 0,1.63181017 0,2 C0,2.55228475 0.44771525,3 1,3 Z"></path>
<path d="M3,12.6 C4.66666667,11.1333333 6.33333333,10.4 8,10.4 C9.66666667,10.4 11.3333333,11.1333333 13,12.6"></path>
</svg>
</label>
<label class="switch">
<input type="checkbox">
<span>Normal</span>
</label>
<em>Non-JS only works with Google Chrome right now,<br>because of the CSS Attribute <a href="https://caniuse.com/#feat=css-motion-paths" target="_blank">d: path()</a></em>
</div>
<!-- dribbble -->
<a class="dribbble" href="https://dribbble.com/shots/5296488-Smiley-switch-animation" target="_blank"><img src="https://cdn.dribbble.com/assets/dribbble-ball-mark-2bd45f09c2fb58dbbfb44766d5d1d07c5a12972d602ef8b32204d28fa3dda554.svg" alt=""></a>
$primary: #5628EE;
$secondary: #23C4F8;
$lightGrey: #99A3BA;
$grey: #3F4656;
$darkGrey: #2F3545;
.switch {
height: 22px;
display: block;
position: relative;
cursor: pointer;
input {
display: none;
& + span {
padding-left: 40px;
min-height: 22px;
line-height: 22px;
display: block;
color: $lightGrey;
position: relative;
white-space: nowrap;
&:not(:empty) {
padding-left: 40px + 8;
}
&:before,
&:after {
content: '';
display: block;
position: absolute;
border-radius: 11px;
}
&:before {
top: -1px;
left: 0;
width: 40px;
height: 22px;
border: 1px solid $grey;
transition: all .3s ease;
}
&:after {
width: 16px;
height: 16px;
background: $darkGrey;
top: 2px;
left: 3px;
transition: all .45s ease;
}
& + svg {
display: none;
}
}
&:checked {
& + span {
&:before {
background: $primary;
border-color: $primary;
}
&:after {
background: #fff;
transform: translate(18px, 0);
}
}
}
}
&:hover {
input {
&:not(:checked) {
& + span {
&:before {
border-color: $secondary;
}
}
}
}
}
&.smiley {
input {
& + span {
& + svg {
width: 12px;
height: 12px;
position: absolute;
z-index: 1;
left: 5px;
top: 4px;
display: block;
transform-origin: 50% 50%;
backface-visibility: hidden;
transform: translateZ(0) scale(1.0, 1.0);
transition: transform .45s ease;
circle {
stroke: none;
fill: $lightGrey;
transition: fill .3s ease;
}
path {
&:nth-child(3) {
opacity: 0;
transform: translate(2px, 5px);
fill: #fff;
}
&:last-child {
stroke-width: 1.6;
stroke: $lightGrey;
fill: none;
stroke-linecap: round;
stroke-linejoin: round;
transition: stroke .3s ease, d .45s ease;
}
}
}
}
&:not(:checked) {
& + span {
& + svg {
path {
&:nth-child(3) {
animation: sad .5s linear .45s;
}
}
}
}
}
&:checked {
& + span {
& + svg {
transform: translateX(18px) translateZ(0) scale(1.0, 1.0);
circle {
fill: $primary;
&:nth-child(2) {
transform-origin: 50% 50%;
animation: wink .5s linear .45s;
}
}
path {
&:last-child {
stroke: $primary;
d: path('M3,10.6 C4.66666667,11.8 6.33333333,12.4 8,12.4 C9.66666667,12.4 11.3333333,11.8 13,10.6');
}
}
}
}
}
}
}
}
@keyframes wink {
0%, 100% {
transform: scaleY(1);
}
50% {
transform: scaleY(.6);
}
}
@keyframes sad {
0% {
opacity: 0;
transform: translate(2px, 5px);
}
50% {
opacity: 1;
transform: translate(2px, 7px);
}
100% {
opacity: 0;
transform: translate(2px, 7px);
}
}
em {
display: table;
text-align: center;
font-style: italic;
color: rgba($lightGrey, .5);
font-size: 11px;
line-height: 16px;
font-style: italic;
margin: 20px auto 0 auto;
transition: color .3s ease;
a {
color: $lightGrey;
display: inline-block;
}
}
html {
-webkit-font-smoothing: antialiased;
}
* {
box-sizing: border-box;
&:before,
&:after {
box-sizing: border-box;
}
}
// Center & dribbble
body {
min-height: 100vh;
font-family: Roboto, Arial;
color: #ADAFB6;
background: #171C28;
display: flex;
justify-content: center;
align-items: center;
.switch {
display: table;
min-width: 102px;
margin: 20px auto;
}
.dribbble {
position: fixed;
display: block;
right: 20px;
bottom: 20px;
img {
display: block;
height: 28px;
}
}
}
View Compiled
// Fallback for other Browser than Google Chrome
// Check if d: path('') is supported
if(!CSS.supports('d', 'path("")')) {
$('.switch.smiley').each(function(e) {
var self = $(this);
var input = self.children('input');
self.find('svg path:last-child')[0].setAttribute('d', ((input.is(':checked')) ? 'M3,10.6 C4.66666667,11.8 6.33333333,12.4 8,12.4 C9.66666667,12.4 11.3333333,11.8 13,10.6' : 'M3,12.6 C4.66666667,11.1333333 6.33333333,10.4 8,10.4 C9.66666667,10.4 11.3333333,11.1333333 13,12.6'));
input.change(function(e) {
self.find('svg path:last-child')[0].setAttribute('d', ((input.is(':checked')) ? 'M3,10.6 C4.66666667,11.8 6.33333333,12.4 8,12.4 C9.66666667,12.4 11.3333333,11.8 13,10.6' : 'M3,12.6 C4.66666667,11.1333333 6.33333333,10.4 8,10.4 C9.66666667,10.4 11.3333333,11.1333333 13,12.6'));
});
});
}