Depending on which browsers you want to support, you can use the :checked pseudo-class selector in addition to hiding the radio buttons.
Using this HTML:
<input type="radio" id="toggle-on" name="toggle" checked ><label for="toggle-on">On</label ><input type="radio" id="toggle-off" name="toggle" ><label for="toggle-off">Off</label>
You can use something like the following CSS:
input[type="radio"].toggle { display: none; } input[type="radio"].toggle:checked + label { }
For example (to preserve a custom CSS summary), if you used Bootstrap , you can add class="btn" to your <label> elements and class="btn" them class="btn" to create a switch that looks like this:

... which just requires the following extra CSS:
input[type="radio"].toggle:checked + label { background-image: linear-gradient(to top,#969696,#727272); box-shadow: inset 0 1px 6px rgba(41, 41, 41, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); cursor: default; color: #E6E6E6; border-color: transparent; text-shadow: 0 1px 1px rgba(40, 40, 40, 0.75); } input[type="radio"].toggle + label { width: 3em; } input[type="radio"].toggle:checked + label.btn:hover { background-color: inherit; background-position: 0 0; transition: none; } input[type="radio"].toggle-left + label { border-right: 0; border-top-right-radius: 0; border-bottom-right-radius: 0; } input[type="radio"].toggle-right + label { border-top-left-radius: 0; border-bottom-left-radius: 0; }
I have included this, as well as additional fallback styles in the switch with the jsFiddle switch . Note that :checked is only supported in IE 9, so this approach is limited to new browsers.
However, if you need to support IE 8 and want to use JavaScript *, you can crack the pseudo-support for :checked without too much difficulty (although you can just as easily set classes directly on the shortcut at this point),
Using some quick and dirty jQuery code as an example of a workaround :
$('.no-checkedselector').on('change', 'input[type="radio"].toggle', function () { if (this.checked) { $('input[name="' + this.name + '"].checked').removeClass('checked'); $(this).addClass('checked');
You can then make a few changes to the CSS to complete the work:
input[type="radio"].toggle { position: absolute; left: -99em; } input[type="radio"].toggle:checked + label, input[type="radio"].toggle.checked + label { }
* If you use Modernizr, you can use the :selector test to determine if you need a fallback. I called my test "selectedselector" in the sample code, and subsequently the jQuery event handler is configured only if the test fails.