Create consistent cross-browser and cross-device toggle switches.

You can find here the OUDS Switch design guidelines.

Basic exampleLink to this section: Basic example

<div class="switch-item">
  <div class="control-item-assets-container">
    <input class="control-item-indicator" type="checkbox" role="switch" value="" id="switchDefault" checked />
  </div>
  <div class="control-item-text-container">
    <label class="control-item-label" for="switchDefault">Label</label>
  </div>
</div>
<div class="switch-item">
  <div class="control-item-assets-container">
    <input class="control-item-indicator" type="checkbox" role="switch" value="" id="switchDefault2" />
  </div>
  <div class="control-item-text-container">
    <label class="control-item-label" for="switchDefault2">Label</label>
  </div>
</div>
html
Bootstrap $enable-bootstrap-compatibility: true
<div class="form-check form-switch">
  <input class="form-check-input" type="checkbox" role="switch" id="switchCheckDefault" />
  <label class="form-check-label" for="switchCheckDefault">Default switch checkbox input</label>
</div>
<div class="form-check form-switch">
  <input class="form-check-input" type="checkbox" role="switch" id="switchCheckChecked" checked />
  <label class="form-check-label" for="switchCheckChecked">Checked switch checkbox input</label>
</div>
html

ApproachLink to this section: Approach

Browser default switches are replaced with the help of .control-item-indicator[role="switch"]. Switches are for selecting one or several options in a list.

Switches are implemented using .control-item-* classes, see below.

Control itemLink to this section: Control item

Control item is an abstraction for several non-text input components that have similar behavior and layout. It contains an <input /> indicator, a text container for the label and an optional icon.

We use the future friendly child check selector (:has) for all our <input /> states, like :invalid or :disabled. When combined with the .control-item-label class, we can easily style the text for each item based on the <input />’s state.

.control-item-assets-container controls the position of the .control-item-indicator and the optional icon.

.control-item-text-container contains the label and optional helper text and controls their positioning.

.control-item-label extend their clickable area until a .checkbox-standalone, .radio-button-standalone, .switch-standalone or a position: relative; is found in the page hierarchy. This ensure a consistent approach, whatever the DOM is. Consequently, none of the elements next to the label should be interactive.

.control-item-indicator uses customized Solaris icons to indicate checked states.

VariantsLink to this section: Variants

DividerLink to this section: Divider

You can display a divider by adding .control-item-divider to a .control-item.

<div class="switch-item control-item-divider">
  <div class="control-item-assets-container">
    <input class="control-item-indicator" type="checkbox" role="switch" value="" id="switchDivider" />
  </div>
  <div class="control-item-text-container">
    <label class="control-item-label" for="switchDivider">Label</label>
  </div>
</div>
<div class="switch-item control-item-divider">
  <div class="control-item-assets-container">
    <input class="control-item-indicator" type="checkbox" role="switch" value="" id="switchDivider2" />
  </div>
  <div class="control-item-text-container">
    <label class="control-item-label" for="switchDivider2">Label</label>
  </div>
</div>
html

IconLink to this section: Icon

You can display an icon by adding .control-item-assets-container with an icon (SVG or font-icon most likely) inside as a child of a .control-item.

<div class="switch-item">
  <div class="control-item-assets-container">
    <input class="control-item-indicator" type="checkbox" role="switch" value="" id="switchWithSVG" />
  </div>
  <div class="control-item-text-container">
    <label class="control-item-label" for="switchWithSVG">Label</label>
  </div>
  <div class="control-item-assets-container">
    <svg aria-hidden="true">
      <use xlink:href="/docs/0.5/assets/img/ouds-web-sprite.svg#heart-recommend"/>
    </svg>
  </div>
</div>
<div class="switch-item">
  <div class="control-item-assets-container">
    <input class="control-item-indicator" type="checkbox" role="switch" value="" id="switchWithIconFont" />
  </div>
  <div class="control-item-text-container">
    <label class="control-item-label" for="switchWithIconFont">Label</label>
  </div>
  <div class="control-item-assets-container">
    <span class="icon si si-settings" aria-hidden="true"></span>
  </div>
</div>
html

Helper textLink to this section: Helper text

You can display an helper text by adding a .control-item-helper as a sibling of a .control-item-label, don’t forget to make it accessible by adding an aria-describedby attribute on the input.

Helper Text

Helper Text

<div class="switch-item">
  <div class="control-item-assets-container">
    <input class="control-item-indicator" type="checkbox" role="switch" aria-describedby="switchHelperTextDescription" id="switchHelperText" value="" />
  </div>
  <div class="control-item-text-container">
    <label class="control-item-label" for="switchHelperText">Label</label>
    <p class="control-item-helper" id="switchHelperTextDescription">Helper Text</p>
  </div>
</div>
<div class="switch-item">
  <div class="control-item-assets-container">
    <input class="control-item-indicator" type="checkbox" role="switch" aria-describedby="switchHelperTextDescription2" id="switchHelperText2" value="" />
  </div>
  <div class="control-item-text-container">
    <label class="control-item-label" for="switchHelperText2">Label</label>
    <p class="control-item-helper" id="switchHelperTextDescription2">Helper Text</p>
  </div>
</div>
html

ReverseLink to this section: Reverse

You can reverse the component by adding .control-item-reverse to a .control-item.

<div class="switch-item control-item-reverse">
  <div class="control-item-assets-container">
    <input class="control-item-indicator" type="checkbox" role="switch" value="" id="switchReverse" name="switchReverse" checked />
  </div>
  <div class="control-item-text-container">
    <label class="control-item-label" for="switchReverse">Label</label>
  </div>
</div>
<div class="switch-item control-item-reverse">
  <div class="control-item-assets-container">
    <input class="control-item-indicator" type="checkbox" role="switch" value="" id="switchReverse2" name="switchReverse" />
  </div>
  <div class="control-item-text-container">
    <label class="control-item-label" for="switchReverse2">Label</label>
  </div>
</div>
html
Bootstrap $enable-bootstrap-compatibility: true

Put your checkboxes, radios, and switches on the opposite side with the .form-check-reverse modifier class.

<div class="form-check form-switch form-check-reverse">
  <input class="form-check-input" type="checkbox" role="switch" id="switchCheckReverse" />
  <label class="form-check-label" for="switchCheckReverse">Reverse switch checkbox input</label>
</div>
html

StatesLink to this section: States

DisabledLink to this section: Disabled

Add the disabled attribute and the associated <label> are automatically styled to match with a lighter color to help indicate the input’s state.

<div class="switch-item">
  <div class="control-item-assets-container">
    <input class="control-item-indicator" type="checkbox" role="switch" value="" id="switchIndeterminateDisabled" disabled />
  </div>
  <div class="control-item-text-container">
    <label class="control-item-label" for="switchIndeterminateDisabled">Label</label>
  </div>
</div>
<div class="switch-item">
  <div class="control-item-assets-container">
    <input class="control-item-indicator" type="checkbox" role="switch" value="" id="switchCheckedDisabled" checked disabled />
  </div>
  <div class="control-item-text-container">
    <label class="control-item-label" for="switchCheckedDisabled">Label</label>
  </div>
</div>
html
Bootstrap $enable-bootstrap-compatibility: true
<div class="form-check form-switch">
  <input class="form-check-input" type="checkbox" role="switch" id="switchCheckDisabled" disabled />
  <label class="form-check-label" for="switchCheckDisabled">Disabled switch checkbox input</label>
</div>
<div class="form-check form-switch">
  <input class="form-check-input" type="checkbox" role="switch" id="switchCheckCheckedDisabled" checked disabled />
  <label class="form-check-label" for="switchCheckCheckedDisabled">Disabled checked switch checkbox input</label>
</div>
html

Read onlyLink to this section: Read only

To create a read only switches the input should be replaced by a span element with role="switch", aria-readonly and aria-disabled attributes. The switch will be accessible to keyboard navigation and assistive technologies thanks to aria-labelledby and tabindex but other interactions will be prevented.

Label

Label

<div class="switch-item">
  <div class="control-item-assets-container">
    <span class="control-item-indicator" role="switch" aria-readonly="true" aria-disabled="true" tabindex="0" aria-checked="false" aria-labelledby="switchReadonlyLabel"></span>
  </div>
  <div class="control-item-text-container">
    <p class="control-item-label" id="switchReadonlyLabel">Label</p>
  </div>
</div>
<div class="switch-item">
  <div class="control-item-assets-container">
    <span class="control-item-indicator" role="switch" aria-readonly="true" aria-disabled="true" tabindex="0" aria-checked="true" aria-labelledby="switchReadonlyCheckedLabel"></span>
  </div>
  <div class="control-item-text-container">
    <p class="control-item-label" id="switchReadonlyCheckedLabel">Label</p>
  </div>
</div>
html

InvalidLink to this section: Invalid

The invalid state is the equivalent of the ‘Error’ state that you can find in the design specification.

You can display an invalid switch by adding .is-invalid to a .control-item-indicator. Please take a look at our Validation page to know more about this.

<div class="switch-item">
  <div class="control-item-assets-container">
    <input class="control-item-indicator is-invalid" type="checkbox" role="switch" value="" id="switchInvalid" />
  </div>
  <div class="control-item-text-container">
    <label class="control-item-label" for="switchInvalid">Label</label>
  </div>
</div>
<div class="switch-item">
  <div class="control-item-assets-container">
    <input class="control-item-indicator is-invalid" type="checkbox" role="switch" value="" id="switchInvalid2" />
  </div>
  <div class="control-item-text-container">
    <label class="control-item-label" for="switchInvalid2">Label</label>
  </div>
</div>
html
Bootstrap $enable-bootstrap-compatibility: true
<div class="form-check form-switch">
  <input class="form-check-input is-invalid" type="checkbox" value="" id="checkInvalid" role="switch" />
  <label class="form-check-label" for="checkInvalid">
    Invalid checkbox
  </label>
</div>
html

GroupLink to this section: Group

When switches belong to a group (e.g., in a form), you must provide clear context by using a <legend> element inside a <fieldset> for the group title, this way screen readers will read the legend before navigating through the switches.

Switches group example

Helper text

Also a longer helper text, it will also wrap at some point depending on the component width

<div class="row">
  <fieldset class="col-md-6">
    <legend>Switches group example</legend>
    <div class="switch-item control-item-divider">
      <div class="control-item-assets-container">
        <input class="control-item-indicator" type="checkbox" role="switch" value="" id="switchGroup1" aria-describedby="switchGroup1Description" />
      </div>
      <div class="control-item-text-container">
        <label class="control-item-label" for="switchGroup1">Label</label>
        <p class="control-item-helper" id="switchGroup1Description">Helper text</p>
      </div>
      <div class="control-item-assets-container">
        <svg aria-hidden="true">
          <use xlink:href="/docs/0.5/assets/img/ouds-web-sprite.svg#heart-recommend"/>
        </svg>
      </div>
    </div>
    <div class="switch-item control-item-divider">
      <div class="control-item-assets-container">
        <input class="control-item-indicator" type="checkbox" role="switch" value="" id="switchGroup2" checked aria-describedby="switchGroup2Description" />
      </div>
      <div class="control-item-text-container">
        <label class="control-item-label" for="switchGroup2">A longer label for showing behavior in this case, switch indicator and icon will stick to the top area of the component</label>
        <p class="control-item-helper" id="switchGroup2Description">Also a longer helper text, it will also wrap at some point depending on the component width</p>
      </div>
      <div class="control-item-assets-container">
        <svg aria-hidden="true">
          <use xlink:href="/docs/0.5/assets/img/ouds-web-sprite.svg#heart-recommend"/>
        </svg>
      </div>
    </div>
  </fieldset>
</div>
html

StandaloneLink to this section: Standalone

This is commonly used to build custom component and shouldn’t be used alone. Remember to provide some sort of accessible name for assistive technologies (for instance, using aria-labelledby, a .visually-hidden, aria-label or a second label). See the forms overview accessibility section for details.

For the standalone Switch, we provide a completely different architecture to ease the integration inside your projects.

<label class="switch-standalone">
  <input class="control-item-indicator" type="checkbox" role="switch" value="" />
  <span class="visually-hidden">Label</span>
</label>
html

Native switchesLink to this section: Native switches

Progressively enhance your switches for mobile Safari (iOS 17.4+) by adding a switch attribute to your input to enable haptic feedback when toggling switches, just like native iOS switches. There are no style changes attached to using this attribute in Bootstrap as all our switches use custom styles.

<div class="switch-item">
  <div class="control-item-assets-container">
    <input class="control-item-indicator" type="checkbox" role="switch" value="" id="switchNative" switch />
  </div>
  <div class="control-item-text-container">
    <label class="control-item-label" for="switchNative">Label</label>
  </div>
</div>
html

Be sure to read more about the switch attribute on the WebKit blog. Safari 17.4+ on macOS and iOS both have native-style switches in HTML while other browsers simply fall back to the standard checkbox appearance. Applying the attribute to a non-Bootstrap checkbox in more recent versions of Safari will render a native switch.