Reputation: 2159
I'm styling my checkboxes to look like toggle switches which works beautifully in Chrome, UC Browser, Safari for Windows and is a bit choppy in Firefox but acceptable. Unfortunately in Edge it doesn't work at all.
I've looked through the CSS properties I'm using and it appears as though all are supported by Edge so I don't understand what I'm missing.
.toggle{
width:34px;
height:16px;
border-radius:40px;
position:relative;
-webkit-appearance: none;
margin:2px 0 0 0px;
box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.4);
background: -webkit-linear-gradient(#c6c6c6,#e3e3e3);
cursor:hand;cursor:pointer;pointer:hand;
outline: 0;
}
.toggle:checked{
background: -webkit-linear-gradient(#77178F,#AD73BB);
box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.4);
}
.toggle:before {
content:'';
letter-spacing:1px;
color: rgba(0,0,0,.15);
font-size:10px;
font-weight:100;
text-shadow:1px 1px 1px rgba(255,255,255,1);
width:7px;
height:7px;
padding:2px;
top:2px;
left:2px;
position:absolute;
border-radius:40px;
background: linear-gradient(#ebebeb,#f1f1f1);
box-shadow: -2px 2px 8px rgba(0, 0, 0, 0.2),
-1px 1px 2px rgba(0, 0, 0, 0.3),
inset 1px 1px 1px #ffffff;
transition: all 0.4s;
}
.toggle:checked:before {
left:20px;
background:#f1f1f1;
}
.toggle:checked:after {
background: linear-gradient(#d8eec4,#5fa718);
box-shadow: inset -1px -1px 4px #417f0b,
inset 1px 1px 2px #5b9f1a;
}
<input type=checkbox class=toggle>
It looks to me like -webkit-appearance:none
is not doing what it's supposed to (hide the original checkbox) but that also is supposedly supported.
If anybody has any experience with this issue and can give me some insight it would be much appreciated.
Upvotes: 1
Views: 5639
Reputation: 2606
Adding another flexible variation of the selected answer to the mix: https://codepen.io/hawatt/pen/MWKyJJZ
HAML
.toggle-switch
%input{type: 'checkbox', id: 'away-from-desk' }
%span.toggle-handle
%label{'for' => 'away-from-desk'} Away from desk
SCSS
$toggle-width: 2.8rem;
$toggle-height: 1.5rem;
$toggle-handle-diameter: calc(#{$toggle-height} * 0.8);
.toggle-switch {
position: relative;
display: flex;
align-items: center;
input {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
width: $toggle-width;
height: $toggle-height;
display: inline-flex;
position: relative;
border-radius: $toggle-height;
overflow: hidden;
outline: none;
border: none;
cursor: pointer;
background-color: #c0c0c0;
transition: all ease 0.3s;
z-index: 0;
text-indent: -5000px;
}
.toggle-handle {
pointer-events: none;
display: flex;
position: absolute;
z-index: 2;
width: $toggle-handle-diameter;
height: $toggle-handle-diameter;
background: #fff;
border-radius: 50%;
left: 0;
margin: 0 0.35rem;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
transition: all ease 0.3s;
}
input:checked,
input.enabled {
background-color: dodgerblue;
& + .toggle-handle {
left: calc(#{$toggle-width} - #{$toggle-handle-diameter} - 0.25rem);
}
}
label {
cursor: pointer;
}
}
Upvotes: 0
Reputation: 381
You could add a label to meet your requirements as a workaround. In this way you could connect a label with a checkbox and apply the styles to the label instead of the checkbox itself.
Here is my testing code.
CSS.
.toggle {
visibility: hidden;
opacity: 0;
}
.toggle + label {
width: 34px;
height: 16px;
border-radius: 40px;
position: relative;
box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.4);
background: linear-gradient(#c6c6c6,#e3e3e3);
cursor: pointer;
outline: 0;
display: inline-block;
}
.toggle + label:before {
content: '';
letter-spacing: 1px;
color: rgba(0,0,0,.15);
font-size: 10px;
font-weight: 100;
text-shadow: 1px 1px 1px rgba(255,255,255,1);
width: 7px;
height: 7px;
padding: 2px;
top: 2px;
left: 2px;
position: absolute;
border-radius: 40px;
background: linear-gradient(#ebebeb,#f1f1f1);
box-shadow: -2px 2px 8px rgba(0, 0, 0, 0.2), -1px 1px 2px rgba(0, 0, 0, 0.3), inset 1px 1px 1px #ffffff;
transition: all 0.4s;
}
.toggle:checked + label {
background: linear-gradient(#77178F,#AD73BB);
box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.4);
}
.toggle:checked + label:before {
left: 20px;
background: #f1f1f1;
}
.toggle:checked + label:after {
background: linear-gradient(#d8eec4,#5fa718);
box-shadow: inset -1px -1px 4px #417f0b, inset 1px 1px 2px #5b9f1a;
}
HTML
<input type="checkbox" class="toggle" id="mycheckbox">
<label for="mycheckbox" />
Upvotes: 0
Reputation: 794
It's better to hide a checkbox, wrap it with another element (e.g. label) and add a sibling to the checkbox. You can find an example of checkbox-switch here https://www.w3schools.com/howto/howto_css_switch.asp.
Or you can adjust code below:
.toggle {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.toggle input[type=checkbox] {
opacity: 0; /* or use display: none; to hide default checkbox */
width: 0;
height: 0;
}
.toggle .slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(#ebebeb, #f1f1f1);
box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.4);
-webkit-transition: .4s;
transition: .4s;
}
.toggle .slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background: #ffffff;
-webkit-transition: .4s;
transition: .4s;
}
.toggle input[type=checkbox]:checked + .slider {
background: linear-gradient(#77178F,#AD73BB);
box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.4);
}
.toggle input[type=checkbox]:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
.toggle .slider.round {
border-radius: 34px;
}
.toggle .slider.round:before {
border-radius: 50%;
}
<label class="toggle">
<input type="checkbox">
<span class="slider round"></span>
</label>
Upvotes: 1