Radio Toggle Switch on/off

v0.1a

Lights

Implementing this component

The Markup

				
	<form id="toggle-switch-on-off">
        <fieldset class="toggle-switch t-neutral">
            <legend class="toggle-switch__title">Lights</legend>
            <div class="toggle-switch__inner">
                <input class="toggle-switch__radio" type="radio" name="switch" id="radio-toggle-switch-off" checked>
                <label class="toggle-switch__label" for="radio-toggle-switch-off">Off</label>
                <input class="toggle-switch__radio" type="radio" name="switch" id="radio-toggle-switch-on">
                <label class="toggle-switch__label" for="radio-toggle-switch-on">On</label>
            </div>
        </fieldset>
    </form>
				
			

CSS: Theming

				
	/* Theming */
.t-neutral .toggle-switch__label {
    color: #000;
}
.t-neutral .toggle-switch__radio + label:before {
    background: #fff;
    border: 1px solid #ddd;
}
.t-neutral .toggle-switch__radio:nth-of-type(1) + label {
    background: #eee;
    color: #222;
}
.t-neutral .toggle-switch__radio:nth-of-type(2) + label {
    background: #222;
    color: #fff;
}
/* set keyboard focus for each to be slightly different */

/* On Button */
.t-neutral .toggle-switch__radio:focus ~ label:nth-of-type(1) {
    background: #ccc;
    color: #222;
}
/* Off Button */
.t-neutral .toggle-switch__radio:focus ~ label:nth-of-type(2) {
    background: #444;
    color: #fff;
}

				
			

CSS: Component

				
/* Component */
.toggle-switch__inner {
    display: block;
    height: 3.75em;
    max-width: 6.5em;
    overflow-x: hidden;
    position: relative;
    z-index: 1;
}
.toggle-switch:after {
    clear: both;
    content: "";
    display: table;
}
.toggle-switch__title ~ .toggle-switch__inner .toggle-switch__radio {
    left: -9999px;
    opacity: 0;
    position: absolute;
    visibility: none;
}

.toggle-switch__label {
    border-radius: 40px;
    cursor: pointer;
    display: block;
    float: left;
    opacity: 0;
    padding: 1em;
    position: absolute;
    transition: opacity 0.2s ease;
    -webkit-user-select: none;
    user-select: none;
    width: 100%;
}

/* The circular switch */
.toggle-switch__radio + label:before {
    border-radius: 50%;
    content: "";
    display: block;
    height: 3.3em;
    position: absolute;
    top: 0;
    transition: transform 0.3s ease-in-out;
    width: 3.3em;
}

.toggle-switch__radio:nth-of-type(1) + label {
    text-align: right;
}

.toggle-switch__radio:nth-of-type(1) + label:before {
    left: 0;
    transform: translateX(4em);
}

.toggle-switch__radio:nth-of-type(2) + label {
    text-align: left;
}
.toggle-switch__radio:nth-of-type(2) + label:before {
    right: 0;
    transform: translateX(-4em);
}

/* our transition for each radio button,
        move the 'switch' left or right, and fade out
        the not currently active button
    */

.toggle-switch__radio + label {
    z-index: 5;
}
.toggle-switch__radio:checked + label {
    opacity: 1;
    z-index: 1;
}
.toggle-switch__radio:checked + label:before {
    transform: translateX(0);
}


				
			

About the component

TBD.

Screen Readers

Apple Voiceover

TBD.

JAWS

TBD.

NVDA

TBD.

Keyboard control

TBD.

High Contrast

TBD.

Inputs

TBD.

Cross browser notes

TBD.

Cross device notes

TBD.