Material Switcher
by Andrey Izman
HTML
<div class="slider-block">
<label for="slider1" class="slider-label">Get notified about new posts</label>
<div id="slider1" class="slider-box" aria-label="Get notified about new posts" tabindex="0" role="checkbox" aria-checked="false">
<div class="slider-outline"></div>
<div class="slider-picker"></div>
</div>
</div>
<div class="slider-block">
<div id="slider2" class="slider-box" aria-label="Get notified about new posts" tabindex="0" role="checkbox" aria-checked="false">
<div class="slider-outline"></div>
<div class="slider-picker"></div>
</div>
<label for="slider2" class="slider-label">Get notified about new posts</label>
</div>
<div class="slider-inline">
<label for="slider1" class="slider-label">Get notified about new posts</label>
<div id="slider1" class="slider-box" aria-label="Get notified about new posts" tabindex="0" role="checkbox" aria-checked="false">
<div class="slider-outline"></div>
<div class="slider-picker"></div>
</div>
</div>
<div class="slider-inline">
<div id="slider2" class="slider-box" aria-label="Get notified about new posts" tabindex="0" role="checkbox" aria-checked="false">
<div class="slider-outline"></div>
<div class="slider-picker"></div>
</div>
<label for="slider2" class="slider-label">Get notified about new posts</label>
</div>
SCSS
body {
padding: 16px;
}
.slider-block {
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
display: -webkit-box;
display: -moz-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
margin: 0 -16px;
padding: 16px;
-webkit-box-direction: normal;
box-direction: normal;
-webkit-box-orient: horizontal;
box-orient: horizontal;
-webkit-flex-direction: row;
flex-direction: row;
-webkit-box-align: center;
box-align: center;
-webkit-align-items: center;
align-items: center;
}
.slider-label {
margin-bottom: 0!important;
}
.slider-block > *:first-child {
-webkit-box-flex: 1 1;
-webkit-flex: 1 1;
flex: 1 1;
margin-right: 8px;
+ .slider-box,
+ .slider-label {
-webkit-box-flex: 0 0 auto;
-webkit-flex: 0 0 auto;
flex: 0 0 auto;
}
}
.slider-box {
-webkit-user-select: none;
-webkit-tap-highlight-color: transparent;
-webkit-box-sizing: content-box;
box-sizing: content-box;
cursor: pointer;
display: inline-block;
height: 20px;
outline: none;
position: relative;
vertical-align: middle;
width: 37px;
z-index: 0;
}
.slider-box:before {/*slider-bar*/
content: '';
display: block;
-webkit-transition: border-color .3s ease;
transition: border-color .3s ease;
border: 7px solid #b9b9b9;
-webkit-border-radius: 7px;
border-radius: 7px;
position: absolute;
top: 3px;
width: 23px;
box-sizing: content-box;
}
.slider-inline {
display: inline-block;
padding: 16px 0;
> *:first-child {
margin-right: 8px;
}
}
.slider-outline {
-webkit-transform: scale(2.5);
transform: scale(2.5);
-webkit-transition: opacity .15s ease, left .3s ease;
transition: opacity .15s ease, left .3s ease;
background-color: rgba(0, 0, 0, 0.2);
-webkit-border-radius: 100%;
border-radius: 100%;
height: 20px;
left: 0;
opacity: 0;
outline: .1px solid transparent;
pointer-events: none;
position: absolute;
width: 20px;
z-index: -1;
}
.slider-picker {
...
JavaScript
const delay = (() => {
let t;
return (next, ms) => {
t && clearTimeout(t);
next && (t = setTimeout(next, ms || 150));
};
}) ();
const attchecked = "aria-checked", slactive = "slider-active", slanimate = "slider-animate", slchecked = "slider-checked";
$(".slider-box").on("click", function() {
let slide = $(this), label = $(slide.prev("label")[0] || slide.next("label")[0]);
if (slide.attr(attchecked) == 'true') {
slide.addClass(slanimate).removeClass(slchecked).attr(attchecked, "false");
label.removeClass(slchecked);
delay(() => slide.removeClass(slactive).removeClass(slanimate));
} else {
slide.addClass(slanimate).addClass(slchecked).attr(attchecked, "true");
label.addClass(slchecked);
delay(() => slide.addClass(slactive).removeClass(slanimate));
}
});