JSFiddle - React, Tailwind, and code Playground
by Ариан Шапиро
HTML
<div class="switch">
<input type="checkbox">
<label><i></i></label>
</div>
CSS
*,
*:after,
*:before {
box-sizing: border-box;
}
.switch input {
/* First, we make it as wide as the container */
position: absolute;
width: 100%;
height: 100%;
/* Then, we put it on top of everything else */
z-index: 100;
/* Last, we make it invisible */
opacity: 0;
/* This one is just for ergonomy */
cursor: pointer;
}
.switch {
width: 90px;
height: 25px;
margin: 50px auto;
position: relative;
}
.switch label {
display: block;
width: 100%;
height: 100%;
position: relative;
background: #a5a39d;
border-radius: 40px;
box-shadow:
inset 0 2px 4px 1px rgba(0,0,0,0.2),
0 1px 0 rgba(255,255,255,0.5);
}
.switch label:after {
content: "";
position: absolute;
z-index: -1;
top: -8px; right: -8px; bottom: -8px; left: -8px;
border-radius: inherit;
background: #ccc; /* Fallback */
background: -webkit-linear-gradient(#f2f2f2, #ababab);
box-shadow: 0 0 4px rgba(0,0,0,0.3),
0 1px 1px rgba(0,0,0,0.25);
}
.switch label:before {
content: "";
position: absolute;
z-index: -1;
top: -12px; right: -12px; bottom: -12px; left: -12px;
border-radius: inherit;
background: #eee; /* Fallback */
background: -webkit-linear-gradient(#e5e7e6, #eee);
box-shadow: 0 1px 0 rgba(255,255,255,0.5);
-webkit-filter: blur(1px); /* Smooth trick */
filter: blur(1px); /* Future-proof */
}
.switch label i {
display: block;
height: 100%;
width: 60%;
position: absolute;
right: 40%;
top: 0;
z-index: 2;
border-radius: inherit;
background: #b2ca9e; /* Fallback */
background: -webkit-linear-gradient(#f7f2f6, #b2ac9e);
box-shadow:
inset 0 1px 0 white,
0 0 4px rgba(0,0,0,0.3),
0 5px 5px rgba(0,0,0,0.2);
-webkit-transition: all 0.3s ease-out;
}
.switch label i:after {
content: "";
position: absolute;
left: 15%;
top: 25%;
width: 70%;
...
JavaScript
/*
* In order to make the switch really slide, you have to :
* add "transition: all 0.3s ease-out" to the .label i
* change "left: 0;" to "right: 40%" on .label i
*
* Problem : you see .label i:before (ON or OFF) moving as well. Could we fix it ? Yes, but only on Firefox, because its the only browser supporting animations and transitions on pseudo-elements.
*/