CSS - Turn 2 Radio Buttons into 1 Switch
css, sass
Solution
Here's a partial solution. You have to put the label after the radio respectively and switch the text inside the labels (because when one is selected you want clicking the label to toggle the other). You can add the animation of the background image's position yourself and make it look like it's sliding.
http://jsfiddle.net/Lpvg4/
HTML
<div class="switch-wrapper">
<input type="radio" name="gender-p-653-0" value="1" checked="checked" id="field-gender-male" /><label for="field-gender-male">Female</label>
<input type="radio" name="gender-p-653-0" value="2" id="field-gender-female" /><label for="field-gender-female">Male</label>
</div>
CSS
/* style the labels */
label[for=field-gender-male], label[for=field-gender-female] {
position: relative;
display: block;
width: 80px;
background-color: white;
padding: 0 20px;
margin: 0;
line-height: 20px;
text-align: center;
font-size: 16px;
border: 1px solid gray;
border-radius: 1em;
}
/* hide the radios */
#field-gender-male, #field-gender-female {
display: none;
}
/* background image position */
label[for=field-gender-male] {
background-position: top right;
}
label[for=field-gender-female] {
background-position: top left;
}
/* when checked hide */
#field-gender-male:checked + label,
#field-gender-female:checked + label {
display: none;
}
/* background image */
label[for=field-gender-male],
label[for=field-gender-female] {
background-repeat: no-repeat;
background-image: url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAAAAMwAAZgAAmQAAzAAA/wArAAArMwArZgArmQArzAAr/wBVAABVMwBVZgBVmQBVzABV/wCAAACAMwCAZgCAmQCAzACA/wCqAACqMwCqZgCqmQCqzACq/wDVAADVMwDVZgDVmQDVzADV/wD/AAD/MwD/ZgD/mQD/zAD//zMAADMAMzMAZjMAmTMAzDMA/zMrADMrMzMrZjMrmTMrzDMr/zNVADNVMzNVZjNVmTNVzDNV/zOAADOAMzOAZjOAmTOAzDOA/zOqADOqMzOqZjOqmTOqzDOq/zPVADPVMzPVZjPVmTPVzDPV/zP/ADP/MzP/ZjP/mTP/zDP//2YAAGYAM2YAZmYAmWYAzGYA/2YrAGYrM2YrZmYrmWYrzGYr/2ZVAGZVM2ZVZmZVmWZVzGZV/2aAAGaAM2aAZmaAmWaAzGaA/2aqAGaqM2aqZmaqmWaqzGaq/2bVAGbVM2bVZmbVmWbVzGbV/2b/AGb/M2b/Zmb/mWb/zGb//5kAAJkAM5kAZpkAmZkAzJkA/5krAJkrM5krZpkrmZkrzJkr/5lVAJlVM5lVZplVmZlVzJlV/5mAAJmAM5mAZpmAmZmAzJmA/5mqAJmqM5mqZpmqmZmqzJmq/5nVAJnVM5nVZpnVmZnVzJnV/5n/AJn/M5n/Zpn/mZn/zJn//8wAAMwAM8wAZswAmcwAzMwA/8wrAMwrM8wrZswrmcwrzMwr/8xVAMxVM8xVZsxVmcxVzMxV/8yAAMyAM8yAZsyAmcyAzMyA/8yqAMyqM8yqZsyqmcyqzMyq/8zVAMzVM8zVZszVmczVzMzV/8z/AMz/M8z/Zsz/mcz/zMz///8AAP8AM/8AZv8Amf8AzP8A//8rAP8rM/8rZv8rmf8rzP8r//9VAP9VM/9VZv9Vmf9VzP9V//+AAP+AM/+AZv+Amf+AzP+A//+qAP+qM/+qZv+qmf+qzP+q///VAP/VM//VZv/Vmf/VzP/V////AP//M///Zv//mf//zP///wAAAAAAAAAAAAAAACH5BAEAAPwALAAAAAAUABQAAAhTAPcJHLgPgMGDBBMOPMgQocKCDSMaTCixIgCCFiUujIiRI0SHCht+BEkx48ONFU8KNKmS5cmMFx9yFCmT4UqPN2mOhBkzJ8+ePl2WTKkyKNCBAQEAOw==);
}
Problem
I'm working on a project where the owner wants 2 radio buttons to behave as one ios-style switch - using only CSS. Most of the examples that I see on this use checkboxes - which makes sense - but the markup cannot be changed. I've been looking at this: http://ghinda.net/css-toggle-switch/ And I made an example of what I'm trying to do: http://codepen.io/phillipkregg/pen/wgqIx Is there a way to recreate this by leaving the markup as-is in the 2nd link? Thanks in advance. Markup: ``` <!-- This works fine --> <h3>This works fine since it's just one input</h3> <label class="checkbox toggle ios" style="width: 100px" onclick=""> <input type="checkbox" /> <span> Wireless <span>On</span> <span>Off</span> </span> <a class="slide-button"></a> </label> <br> <h3> This is a little tricky - since it should behave as one switch, but there are actually 2 inputs</h3> <!-- I'm trying to recreate the above with the markup below ( 1 switch for 2 inputs) --> <div class="switch-wrapper"> <label for="field-gender-male"> <input type="radio" name="gender-p-653-0" value="1" checked="checked" id="field-gender-male"> Male </label> <label for="field-gender-female"> <input type="radio" name="gender-p-653-0" value="2" id="field-gender-female"> Female </label> </div> ``` CSS (This is from the ghinda.net project I linked to above): ``` * { font-family: sans-serif; } @charset "UTF-8"; /* * CSS TOGGLE SWITCHES * Unlicense * * Ionuț Colceriu - ghinda.net * https://github.com/ghinda/css-toggle-switch * */ /* Toggle Switches */ /* Shared */ @-webkit-keyframes bugfix { from { position: relative; } to { position: relative; } } /* Checkbox */ /* Radio Switch */ /* Hide by default */ .switch .slide-button, .toggle span span { display: none; } /* We can't test for a specific feature, * so we only target browsers with support for media queries. */ @media only screen { /* Checkbox toggle */ .toggle { display: block; height: 30px; /* Outline the toggles when the inputs are focused */ /* Bugfix for older Webkit, including mobile Webkit. Adapted from: * http://css-tricks.com/webkit-sibling-bug/ */ -webkit-animation: bugfix infinite 1s; position: relative; padding: 0; margin-left: 100px; /* Position the label over all the elements, except the slide-button * Clicking anywhere on the label will change the switch-state */ /* Don't hide the input from screen-readers and keyboard access */ } .toggle * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .toggle .slide-button { display: block; -webkit-transition: all 0.3s ease-out; -moz-transition: all 0.3s ease-out; -o-transition: all 0.3s ease-out; transition: all 0.3s ease-out; } .toggle label, .toggle > span { line-height: 30px; vertical-align: middle; } .toggle input:focus ~ .slide-button, .toggle input:focus + label { outline: 1px dotted #888; } .toggle label { position: relative; z-index: 3; display: block; width: 100%; } .toggle input { position: absolute; opacity: 0; z-index: 5; } .toggle input:checked ~ .slide-button { right: 50%; } .toggle > span { position: absolute; left: -100px; width: 100%; margin: 0; padding-right: 100px; text-align: left; } .toggle > span span { position: absolute; top: 0; left: 0; z-index: 5; display: block; width: 50%; margin-left: 100px; text-align: center; } .toggle > span span:last-child { left: 50%; } .toggle .slide-button { position: absolute; right: 0; top: 0; z-index: 4; display: block; width: 50%; height: 100%; padding: 0; } /* Radio switch */ .switch { display: block; height: 30px; /* Outline the toggles when the inputs are focused */ /* Bugfix for older Webkit, including mobile Webkit. Adapted from: * http://css-tricks.com/webkit-sibling-bug/ */ -webkit-animation: bugfix infinite 1s; position: relative; padding: 0; /* Generate styles for the multiple states */ } .switch * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .switch .slide-button { display: block; -webkit-transition: all 0.3s ease-out; -moz-transition: all 0.3s ease-out; -o-transition: all 0.3s ease-out; transition: all 0.3s ease-out; } .switch label, .switch > span { line-height: 30px; vertical-align: middle; } .switch input:focus ~ .slide-button, .switch input:focus + label { outline: 1px dotted #888; } .switch input { position: absolute; opacity: 0; } .switch label { position: relative; z-index: 2; float: left; width: 50%; height: 100%; margin: 0; text-align: center; } .switch .slide-button { position: absolute; top: 0; left: 0; padding: 0; z-index: 1; width: 50%; height: 100%; } .switch input:last-of-type:checked ~ .slide-button { left: 50%; } .switch.switch-3 label, .switch.switch-3 .slide-button { width: 33.33333%; } .switch.switch-3 input:checked:nth-of-type(2) ~ .slide-button { left: 33.33333%; } .switch.switch-3 input:checked:last-of-type ~ .slide-button { left: 66.66667%; } .switch.switch-4 label, .switch.switch-4 .slide-button { width: 25%; } .switch.switch-4 input:checked:nth-of-type(2) ~ .slide-button { left: 25%; } .switch.switch-4 input:checked:nth-of-type(3) ~ .slide-button { left: 50%; } .switch.switch-4 input:checked:last-of-type ~ .slide-button { left: 75%; } .switch.switch-5 label, .switch.switch-5 .slide-button { width: 20%; } .switch.switch-5 input:checked:nth-of-type(2) ~ .slide-button { left: 20%; } .switch.switch-5 input:checked:nth-of-type(3) ~ .slide-button { left: 40%; } .switch.switch-5 input:checked:nth-of-type(4) ~ .slide-button { left: 60%; } .switch.switch-5 input:checked:last-of-type ~ .slide-button { left: 80%; } /* Standalone Themes */ /* Candy Theme * Based on the "Sort Switches / Toggles (PSD)" by Ormal Clarck * http://www.premiumpixels.com/freebies/sort-switches-toggles-psd/ */ .candy { background-color: #2d3035; border-radius: 3px; color: #fff; font-weight: bold; text-align: center; text-shadow: 1px 1px 1px #191b1e; -webkit-box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.3), 0 1px 0px rgba(255, 255, 255, 0.2); -moz-box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.3), 0 1px 0px rgba(255, 255, 255, 0.2); box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.3), 0 1px 0px rgba(255, 255, 255, 0.2); } .candy input:checked + label { color: #333; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); } .candy .slide-button { border: 1px solid #333; background-color: #70c66b; border-radius: 3px; background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0)); background-image: -moz-linear-gradient(top, rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0)); background-image: -o-linear-gradient(top, rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0)); background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0)); -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), inset 0 1px 1px rgba(255, 255, 255, 0.45); -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), inset 0 1px 1px rgba(255, 255, 255, 0.45); box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), inset 0 1px 1px rgba(255, 255, 255, 0.45); } .candy > span { color: #333; text-shadow: none; } .candy span { color: #fff; } .candy.blue .slide-button { background-color: #38a3d4; } .candy.yellow .slide-button { background-color: #f5e560; } /* Android Theme */ .android { background-color: #464747; border-radius: 1px; color: #fff; -webkit-box-shadow: inset rgba(0, 0, 0, 0.1) 0 1px 0; -moz-box-shadow: inset rgba(0, 0, 0, 0.1) 0 1px 0; box-shadow: inset rgba(0, 0, 0, 0.1) 0 1px 0; /* Selected ON toggle */ } .android > span span { -webkit-transition: all 0.1s ease-out; -moz-transition: all 0.1s ease-out; -o-transition: all 0.1s ease-out; transition: all 0.1s ease-out; } .android > span span:first-of-type { opacity: 0; } .android .slide-button { background-color: #666; border-radius: 1px; -webkit-box-shadow: inset rgba(255, 255, 255, 0.2) 0 1px 0, rgba(0, 0, 0, 0.3) 0 1px 0; -moz-box-shadow: inset rgba(255, 255, 255, 0.2) 0 1px 0, rgba(0, 0, 0, 0.3) 0 1px 0; box-shadow: inset rgba(255, 255, 255, 0.2) 0 1px 0, rgba(0, 0, 0, 0.3) 0 1px 0; } .android.toggle input:first-of-type:checked ~ .slide-button { background-color: #0E88B1; } .android.toggle input:first-of-type:checked ~ span span { opacity: 0; } .android.toggle input:first-of-type:checked ~ span span:first-of-type { opacity: 1; } .android.switch, .android > span span { font-size: 85%; text-transform: uppercase; } /* iOS Theme */ .ios.toggle { color: lightgrey; } .ios.toggle .slide-button { width: 30px; background-color: white; border: 1px solid lightgrey; border-radius: 100%; -webkit-transition: all 0.3s ease-out; -moz-transition: all 0.3s ease-out; -o-transition: all 0.3s ease-out; transition: all 0.3s ease-out; -webkit-box-shadow: inset 0 -3px 3px rgba(0, 0, 0, 0.025), 0 1px 4px rgba(0, 0, 0, 0.15), 0 4px 4px rgba(0, 0, 0, 0.1); -moz-box-shadow: inset 0 -3px 3px rgba(0, 0, 0, 0.025), 0 1px 4px rgba(0, 0, 0, 0.15), 0 4px 4px rgba(0, 0, 0, 0.1); box-shadow: inset 0 -3px 3px rgba(0, 0, 0, 0.025), 0 1px 4px rgba(0, 0, 0, 0.15), 0 4px 4px rgba(0, 0, 0, 0.1); } .ios.toggle > span span { width: 100%; left: 0; } .ios.toggle > span span:first-of-type { opacity: 0; padding-left: 30px; } .ios.toggle > span span:last-of-type { padding-right: 30px; } .ios.toggle > span:before { content: ""; display: block; width: 100%; height: 100%; position: absolute; left: 100px; top: 0; background-color: #fafafa; border: 1px solid lightgrey; border-radius: 30px; -webkit-transition: all 0.3s ease-out; -moz-transition: all 0.3s ease-out; -o-transition: all 0.3s ease-out; transition: all 0.3s ease-out; -webkit-box-shadow: inset rgba(0, 0, 0, 0.1) 0 1px 0; -moz-box-shadow: inset rgba(0, 0, 0, 0.1) 0 1px 0; box-shadow: inset rgba(0, 0, 0, 0.1) 0 1px 0; } .ios.toggle input:first-of-type:checked ~ .slide-button { left: 0; } .ios.toggle input:first-of-type:checked ~ span:before { border-color: #53d76a; -webkit-box-shadow: inset 0 0 0 30px #53d76a; -moz-box-shadow: inset 0 0 0 30px #53d76a; box-shadow: inset 0 0 0 30px #53d76a; } .ios.toggle input:first-of-type:checked ~ span span { opacity: 0; } .ios.toggle input:first-of-type:checked ~ span span:first-of-type { opacity: 1; color: white; } .ios.switch { background-color: #fafafa; border: 1px solid lightgrey; border-radius: 30px; color: #868686; -webkit-box-shadow: inset rgba(0, 0, 0, 0.1) 0 1px 0; -moz-box-shadow: inset rgba(0, 0, 0, 0.1) 0 1px 0; box-shadow: inset rgba(0, 0, 0, 0.1) 0 1px 0; } .ios.switch .slide-button { background-color: #53d76a; border-radius: 25px; -webkit-transition: all 0.3s ease-out; -moz-transition: all 0.3s ease-out; -o-transition: all 0.3s ease-out; transition: all 0.3s ease-out; } .ios input:checked + label { color: #3a3a3a; } } ```