<ul class="toggle-btn__list">
    <li class="toggle-btn__item">
        <button class="toggle-btn__btn" role="switch" aria-checked="true" aria-labelledby="toggle-label_1" data-toggle-button>
        <span class="u-sr-only">On</span>
        <span class="u-sr-only">Off</span>
        <span class="toggle-btn__label" id="toggle-label_1">Toggle Button 1</span>
      </button>
        <!-- /.toggle-btn__btn -->
    </li>
    <!-- /.toggle-btn__item -->
    <li class="toggle-btn__item">
        <button class="toggle-btn__btn" role="switch" aria-checked="true" aria-labelledby="toggle-label_2" data-toggle-button>
        <span class="u-sr-only">On</span>
        <span class="u-sr-only">Off</span>
        <span class="toggle-btn__label" id="toggle-label_2">Toggle Button 2</span>
      </button>
        <!-- /.toggle-btn__btn -->
    </li>
    <!-- /.toggle-btn__item -->
</ul>
<!-- /.toggle-btn__list -->
<ul class="toggle-btn__list">
  {% for button in toggleButtons %}
    <li class="toggle-btn__item">
      <button class="toggle-btn__btn" role="switch" aria-checked="true" aria-labelledby="toggle-label_{{loop.index}}" data-toggle-button>
        <span class="u-sr-only">On</span>
        <span class="u-sr-only">Off</span>
        <span class="toggle-btn__label" id="toggle-label_{{loop.index}}">{{ button.label }}</span>
      </button>
      <!-- /.toggle-btn__btn -->
    </li>
    <!-- /.toggle-btn__item -->
  {% endfor %}
</ul>
<!-- /.toggle-btn__list -->
{
  "toggleButtons": [
    {
      "label": "Toggle Button 1"
    },
    {
      "label": "Toggle Button 2"
    }
  ]
}
  • Content:
    .toggle-btn {
    
      &__list {
        display: flex;
        flex-direction: column;
        margin: 0;
        padding: 0;
      }
    
      &__item {
        display: inline-flex;
        align-items: center;
        margin: 5px 0;
      }
    
      &__btn {
        position: relative;
        display: flex;
        border: 0;
        padding: 5px;
        background-color: transparent;
        cursor: pointer;
    
        // Switch styles
        &::before,
        &::after {
          display: block;
          margin: 0 3px;
          background: color(neutral, lighter);
          transition: 100ms cubic-bezier(.4, 0, .2, 1);
          content: '';
        }
    
        &::before {
          border-radius: 10px;
          width: 50px;
          height: 20px;
          opacity: .6;
        }
    
        &::after {
          position: absolute;
          top: 50%;
          box-shadow: 0 0 8px rgba(0,0,0,.2), 0 0 2px rgba(0,0,0,.4);
          border-radius: 50%;
          width: 25px;
          height: 25px;
          transform: translate(0, -50%);
        }
    
        &[role='switch'][aria-checked='true'] {
          &::before,
          &::after {
            background: rgba(color(primary, base), 1);
          }
    
          &::after {
            transform: translateX(50px) translateX(-100%) translateY(-50%);
          }
        }
      }
    
      &__label {
        @include font-size($base-font-size);
      }
    }
    
  • URL: /components/raw/toggle-button/_toggle-button.scss
  • Filesystem Path: components/toggle-button/_toggle-button.scss
  • Size: 1.2 KB
  • Content:
    const toggleButtons = document.querySelectorAll('[data-toggle-button]');
    
    for (let i = 0; i < toggleButtons.length; i++) {
      let thisToggle = toggleButtons[i];
    
      thisToggle.addEventListener('click', () => {
        if (thisToggle.getAttribute('aria-checked') == 'true') {
          thisToggle.setAttribute('aria-checked', 'false');
        } else {
          thisToggle.setAttribute('aria-checked', 'true');
        }
      });
    }
    
  • URL: /components/raw/toggle-button/toggle-button.js
  • Filesystem Path: components/toggle-button/toggle-button.js
  • Size: 407 Bytes

Usage

Toggle buttons are used to determine when something is on or off. All toggle buttons are grouped within an unordered list and each toggle buttons parent is a list item.

This toggle button comes with a configuration attribute, data-toggle-button, that links triggers the JavaScript click event.

Labelling Expectations

  • Each toggle button should include a role="switch" attribute.
  • Each toggle button should include an aria-checked attribute. If the button is toggled off, set aria-checked="false". If the button is toggled on, set aria-checked="true".
  • Each toggle button should include an aria-labelledby="id" attribute. That value should match the id of the toggle button label.

Focus Expectations

  • Toggle buttons should have a visible keyboard focus state

Keyboard Expectations

  • Enter or Space = Toggle button
  • Tab = Move to next focusable element