Skip to content

Instantly share code, notes, and snippets.

@tflori
Created February 24, 2020 16:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tflori/b99a5a09654f08d4c27c66d0f5d7bb5e to your computer and use it in GitHub Desktop.
Save tflori/b99a5a09654f08d4c27c66d0f5d7bb5e to your computer and use it in GitHub Desktop.
3-way-switch
<body>
<div class=form-group>
<label>user:edit</label>
<div class=three-way-switch>
<input type=radio id=user-edit-0 name=user:edit value=0>
<label for=user-edit-0 class="left negative">revoke</label>
<input type=radio id=user-edit-N name=user:edit value="" checked>
<label for=user-edit-N class=icon>&#x25cf;</label>
<input type=radio id=user-edit-1 name=user:edit value=1>
<label for=user-edit-1 class="right positive">grant</label>
</div>
</div>
<div class=form-group>
<label>user:a</label>
<div class=three-way-switch>
<input type=radio id=user-a-0 name=user:a value=0>
<label for=user-a-0 class="left negative">revoke</label>
<input type=radio id=user-a-N name=user:a value="" checked>
<label for=user-a-N class=icon>&#x25cf;</label>
<input type=radio id=user-a-1 name=user:a value=1>
<label for=user-a-1 class="right positive">grant</label>
</div>
</div>
</body>
jQuery(function($) {
$.fn.backgroundColor = function() {
let styles = []
.concat(...[...this[0].ownerDocument.styleSheets].map(s => [...s.cssRules||[]]))
.filter(r => this[0].matches(r.selectorText));
let backgroundColor = 'transparent';
styles.map(function (style) {
if (style.style.backgroundColor) {
backgroundColor = style.style.backgroundColor
}
});
return backgroundColor;
};
$('.three-way-switch').each(function () {
const $selector = $('<div class=selector>');
$(this).append($selector);
$(this).find('label').css({
'background': 'none',
'box-shadow': 'none',
});
});
$('.three-way-switch input').on('change', function () {
if (!$(this).is(':checked')) {
return;
}
let $next = $(this).next();
let $selector = $(this).closest('.three-way-switch').find('.selector');
$selector.css('left', $next.position().left);
$selector.css('width', $next.outerWidth());
$selector.css('background', $next.backgroundColor())
}).trigger('change');
$(window).on('resize', function () {
$('.three-way-switch input').trigger('change');
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
html *,body * { box-sizing: border-box; }
.form-group {
display: flex;
margin: 20px;
> label {
width: 200px;
}
}
.three-way-switch {
background: #f0f0f0;
font-size: 10px;
font-family: 'Open Sans', Roboto, sans-serif;
border-radius: calc(1em + 4px);
height: calc(2em + 4px);
padding: 2px;
position: relative;
display: flex;
input {
position: absolute;
opacity: 0;
top: 0;
left: 0;
z-index: -1;
}
.selector {
min-width: 2em;
height: 2em;
border-radius: 1em;
transition: left 0.3s, background 0.3s, width 0.3s;
position: absolute;
z-index: 1;
box-shadow: 0 4px 4px 0 rgba(0,0,0,0.2);
}
label {
height: 2em;
border-radius: 1em;
line-height: 2em;
padding: 0 1em;
text-align: center;
min-width: 2em;
display: block;
min-height: 2em;
color: #555;
cursor: pointer;
background: none;
text-transform: uppercase;
transition: background 0.3s, color 0.3s;
z-index: 2;
&.icon {
padding: 0;
}
}
input:checked + label {
background: #555;
color: #fff;
box-shadow: 0 4px 4px 0 rgba(0,0,0,0.2);
&.positive {
background: #393;
}
&.negative {
background: #933;
}
}
}
@media (max-width: 800px) {
.three-way-switch {
font-size: 16px;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment