Hey,
Would it be of any interest in version four to do a pull request for a CSS only toggle switch? It would have animations and slide like you'd expect
Example image:
Essentially:
<label class="tgl">
<input type="checkbox" checked/>
<span class="tgl_body">
<span class="tgl_switch"></span>
<span class="tgl_track">
<span class="tgl_bgd"></span>
<span class="tgl_bgd tgl_bgd-negative"></span>
</span>
</span>
</label>
SCSS:
$toggle-height: 30px;
$toggle-width: 60px;
$switch-size: 30px;
$anim-slight-bounce: cubic-bezier(0.34,1.61,0.7,1);
$anim-speed-normal: 250ms;
$border-color: #dadde1;
$blue: #439fd8; // Guidebook blue
// BASE
// -------------------------------------
.tgl {
position: relative;
display: inline-block;
height: $toggle-height;
cursor: pointer;
> input {
position: absolute;
opacity: 0;
z-index: -1; /* Put the input behind the label so it doesn't overlay text */
visibility: hidden;
}
.tgl_body {
width: $toggle-width;
height: $toggle-height;
background: white;
border: 1px solid $border-color;
display: inline-block;
position: relative;
border-radius: 50px;
}
.tgl_switch {
width: $toggle-height;
height: $toggle-height;
display: inline-block;
background-color: white;
position: absolute;
left: -1px;
top: -1px;
border-radius: 50%;
border: 1px solid darken($border-color, 5%);
@include box-shadow(0 2px 2px rgba(0,0,0,.13));
@include transition(left $anim-slight-bounce $anim-speed-normal, transform $anim-slight-bounce $anim-speed-normal);
z-index: 1;
}
.tgl_track {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
overflow: hidden;
border-radius: 50px;
}
.tgl_bgd {
position: absolute;
right: -10px; // 10 compensates for animation bounce
top: 0;
bottom: 0;
width: $toggle-width - ($switch-size / 2) + 10; // 10 compensates for animation bounce
@include transition(left $anim-slight-bounce $anim-speed-normal, right $anim-slight-bounce $anim-speed-normal);
background: $blue url('http://petelada.com/images/toggle/tgl_check.png') center center no-repeat;
}
.tgl_bgd-negative {
right: auto;
left: -($toggle-width - ($switch-size / 2));
background: white url('http://petelada.com/images/toggle/tgl_x.png') center center no-repeat;
}
&:hover {
.tgl_switch {
border-color: darken($border-color, 13%);
@include transform(scale(1.06));
}
}
&:active {
.tgl_switch {
@include transform(scale(.95));
}
}
> :not(:checked) ~ .tgl_body {
> .tgl_switch {
left: $toggle-width - $switch-size;
}
.tgl_bgd {
right: -($toggle-width - ($switch-size / 2));
&.tgl_bgd-negative {
right: auto;
left: -10px;
}
}
}
}
Also could be a simpler one like:
HTML
<div class="switch">
<input id="cmn-toggle-4" class="cmn-toggle cmn-toggle-round-flat" type="checkbox">
<label for="cmn-toggle-4"></label>
</div>
CSS:
.cmn-toggle {
position: absolute;
margin-left: -9999px;
visibility: hidden;
}
.cmn-toggle + label {
display: block;
position: relative;
cursor: pointer;
outline: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
input.cmn-toggle-round-flat + label {
padding: 2px;
width: 120px;
height: 60px;
background-color: #dddddd;
-webkit-border-radius: 60px;
-moz-border-radius: 60px;
-ms-border-radius: 60px;
-o-border-radius: 60px;
border-radius: 60px;
-webkit-transition: background 0.4s;
-moz-transition: background 0.4s;
-o-transition: background 0.4s;
transition: background 0.4s;
}
input.cmn-toggle-round-flat + label:before, input.cmn-toggle-round-flat + label:after {
display: block;
position: absolute;
content: "";
}
input.cmn-toggle-round-flat + label:before {
top: 2px;
left: 2px;
bottom: 2px;
right: 2px;
background-color: #fff;
-webkit-border-radius: 60px;
-moz-border-radius: 60px;
-ms-border-radius: 60px;
-o-border-radius: 60px;
border-radius: 60px;
-webkit-transition: background 0.4s;
-moz-transition: background 0.4s;
-o-transition: background 0.4s;
transition: background 0.4s;
}
input.cmn-toggle-round-flat + label:after {
top: 4px;
left: 4px;
bottom: 4px;
width: 52px;
background-color: #dddddd;
-webkit-border-radius: 52px;
-moz-border-radius: 52px;
-ms-border-radius: 52px;
-o-border-radius: 52px;
border-radius: 52px;
-webkit-transition: margin 0.4s, background 0.4s;
-moz-transition: margin 0.4s, background 0.4s;
-o-transition: margin 0.4s, background 0.4s;
transition: margin 0.4s, background 0.4s;
}
input.cmn-toggle-round-flat:checked + label {
background-color: #8ce196;
}
input.cmn-toggle-round-flat:checked + label:after {
margin-left: 60px;
background-color: #8ce196;
}
Which results in:
First as a Pen:
http://codepen.io/kkirsche/pen/emyvPb
Second as a Pen:
http://codepen.io/kkirsche/pen/VYypVe
X-Ref: #1935
Might want to propose this for https://github.com/mdo/wtf-forms/ first.
Proposed for wtf-forms as an issue: mdo/wtf-forms#47
Thanks for the suggestion @cvrebert. I'll be happy to implement in either place or both based on feedback.
I'm probably in favor of it, but this exact proposal (the examples) are a little glitchy it looks like.
Sounds good. Let me know what glitches you run into and I'll be happy to attempt to revise them. Starting points if nothing else :+1:
Although I the example looks very nice I would like to note, that some designs based on bootstrap are flat and without rounded corners. I hope this will be considered in the final design of such a toggle/switch. Thanks
Punting on this鈥攚e're not leaving issues open for v4 until we do the alpha.
Do you plan to add this to Bootstrap 4?
no current plans for this, no
the more I've looked into this @paglias the more difficult it seems to ensure that it really works consistently across browsers while maintaining proper accessibility. I could just be missing something though of course
I understand, thanks anyway :)
Most helpful comment
First as a Pen:
http://codepen.io/kkirsche/pen/emyvPb
Second as a Pen:
http://codepen.io/kkirsche/pen/VYypVe