← Back to UI screens

Live: try it with the mouse and the keyboard (Tab, arrows, Escape).

ScreenshotToggle switch component — mobile, corporate style
Theme

Toggle switch component — mobile, corporate style

Toggle switch UI component for websites and web apps, shown in Fernway, a fictional productivity product. Shows a list of on/off settings with labels and hints, switches on and off, a disabled switch, and every state (default, hover, focus-visible, on, disabled). Corporate style: IBM Plex Sans, a dark brand-coloured sidebar, 4px corners and subtle shadows. Comes with copyable HTML, CSS and a few lines of plain JavaScript (keyboard support and ARIA per the WAI-ARIA Authoring Practices), a live demo, and a DESIGN.md with light and dark colour tokens.

Open live HTML ↗ Download DESIGN.md
Pattern
Toggle switch
Device
Mobile
Style
Corporate
Product (fictional)
Fernway
Category
Productivity

Spec

Colours (light)
background #f3f9fc · surface #ffffff · text #101c23 · muted #55666f · primary #006e93 · accent #3d70c6
Colours (dark)
background #070f13 · surface #162127 · text #eaeff2 · muted #a5b4bb · primary #00b8f2 · accent #accbff
Fonts
IBM Plex Sans (headings and body), JetBrains Mono (code) · Google Fonts, under their own licences
Light and dark
Both included; follows the system setting
ARIA pattern
Switch (WAI-ARIA Authoring Practices)
Keyboard
Space or Enter flips the switch
States
default, hover, focus-visible, selected, disabled
toggle-switchmobileproductivitytogglelist

Code

Paste the HTML where the component goes, the CSS into your stylesheet and the script before </body>. The tokens block holds the light and dark colours; swap in your own.

HTML
<ul class="mgd-switches" aria-label="Notification settings">
  <li><span><span class="mgd-switches__label" id="sw-digest">Weekly email digest</span><span class="mgd-switches__hint" id="sw-digest-hint">A Monday summary of what changed in your projects.</span></span>
    <button class="mgd-switch" type="button" role="switch" aria-checked="true" aria-labelledby="sw-digest" aria-describedby="sw-digest-hint"><span class="mgd-switch__thumb"></span></button></li>
  <li><span><span class="mgd-switches__label" id="sw-desktop">Desktop notifications</span><span class="mgd-switches__hint" id="sw-desktop-hint">Pop-ups while Fernway is open in a browser tab.</span></span>
    <button class="mgd-switch" type="button" role="switch" aria-checked="false" aria-labelledby="sw-desktop" aria-describedby="sw-desktop-hint"><span class="mgd-switch__thumb"></span></button></li>
  <li><span><span class="mgd-switches__label" id="sw-mentions">Only when I'm mentioned</span><span class="mgd-switches__hint" id="sw-mentions-hint">Mute everything except @mentions and direct replies.</span></span>
    <button class="mgd-switch" type="button" role="switch" aria-checked="true" aria-labelledby="sw-mentions" aria-describedby="sw-mentions-hint"><span class="mgd-switch__thumb"></span></button></li>
  <li><span><span class="mgd-switches__label" id="sw-sms">Text message alerts</span><span class="mgd-switches__hint" id="sw-sms-hint">Add a phone number in your profile first.</span></span>
    <button class="mgd-switch" type="button" role="switch" aria-checked="false" aria-labelledby="sw-sms" aria-describedby="sw-sms-hint" disabled><span class="mgd-switch__thumb"></span></button></li>
</ul>
CSS
/* Tokens (light + dark) */
:root{--bg:#f3f9fc;--surface:#ffffff;--border:#cbdae2;--text:#101c23;--muted:#55666f;--primary:#006e93;--on-primary:#ffffff;--accent:#3d70c6;--font-h:"IBM Plex Sans",Georgia,serif;--font-b:"IBM Plex Sans",system-ui,sans-serif;--hw:600;
--c-bw:1px;--c-line:var(--border);--c-r:4px;--c-pill:4px;--c-sh:0 1px 2px rgb(0 0 0 / .08);--c-pop:0 8px 24px rgb(0 0 0 / .16);--c-tt:none;--c-ls:0;--c-fw:600;--c-fs:14px;--c-ring:2px solid var(--primary);--c-ind:3px;color-scheme:light}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--bg:#070f13;--surface:#162127;--border:#2b373e;--text:#eaeff2;--muted:#a5b4bb;--primary:#00b8f2;--on-primary:#111111;--accent:#accbff;color-scheme:dark}
}
:root[data-theme="dark"]{--bg:#070f13;--surface:#162127;--border:#2b373e;--text:#eaeff2;--muted:#a5b4bb;--primary:#00b8f2;--on-primary:#111111;--accent:#accbff;color-scheme:dark}

/* Component */
.mgd-sr{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.mgd-switches{list-style:none;margin:0;padding:0;max-width:640px;border-top:1px solid var(--border)}
.mgd-switches li{display:flex;align-items:center;justify-content:space-between;gap:20px;padding:16px 2px;border-bottom:1px solid var(--border)}
.mgd-switches__label{display:block;font:600 15px/1.35 var(--font-b);text-transform:var(--c-tt);letter-spacing:var(--c-ls)}
.mgd-switches__hint{display:block;margin-top:2px;color:var(--muted);font-size:13px}
.mgd-switch{flex:none;position:relative;width:48px;height:28px;padding:0;border:1.5px solid var(--muted);border-radius:999px;background:color-mix(in oklab,var(--muted) 22%,var(--bg));cursor:pointer;transition:background-color .14s,border-color .14s}
.mgd-switch__thumb{position:absolute;top:50%;left:3px;width:20px;height:20px;margin-top:-10px;border-radius:50%;background:var(--muted);box-shadow:0 1px 3px rgb(0 0 0 / .25);transition:transform .14s,background-color .14s}
.mgd-switch:hover,.mgd-switch.is-hover{background:color-mix(in oklab,var(--muted) 34%,var(--bg))}
.mgd-switch:focus-visible,.mgd-switch.is-focus{outline:var(--c-ring);outline-offset:3px}
.mgd-switch[aria-checked="true"],.mgd-switch.is-on{background:var(--primary);border-color:var(--primary)}
.mgd-switch[aria-checked="true"] .mgd-switch__thumb,.mgd-switch.is-on .mgd-switch__thumb{transform:translateX(20px);background:var(--on-primary)}
.mgd-switch:disabled,.mgd-switch.is-off{opacity:.45;cursor:not-allowed}
@media (forced-colors:active){.mgd-switch[aria-checked="true"] .mgd-switch__thumb{background:Highlight}}
@media (prefers-reduced-motion:reduce){.mgd-switch,.mgd-switch *{transition:none!important;animation-duration:2.4s!important}}
JavaScript
document.querySelectorAll(".mgd-switch").forEach(function (sw) {
  sw.addEventListener("click", function () { sw.setAttribute("aria-checked", sw.getAttribute("aria-checked") !== "true"); });
});

DESIGN.md

Component section (states, ARIA, keyboard)
## Component: Toggle switch

On and off settings that apply straight away, each with a visible label and a hint.

- **Pattern:** WAI-ARIA Authoring Practices, Switch (https://www.w3.org/WAI/ARIA/apg/patterns/switch/)
- **Roles and attributes:** Each switch is a <button role="switch"> with aria-checked, named by its visible label (aria-labelledby) and described by its hint (aria-describedby); a disabled switch uses the disabled attribute.
- **States drawn:** default, hover, focus-visible, selected, disabled
- **Focus:** a visible `:focus-visible` outline (2px solid primary), never removed
- **Style knobs (corporate):** border 1px, corners 4px, shadow `0 1px 2px rgb(0 0 0 / .08)`, labels sentence case
- **Motion:** transitions are short (≤160ms) and switched off under `prefers-reduced-motion: reduce`
- **Code:** HTML + CSS + a few lines of plain JavaScript (no libraries); colours come only from the tokens above, so light and dark both work

### Keyboard
- **Tab:** move between switches
- **Space / Enter:** turn the focused switch on or off

### Licence
Original Made Good Designs code: free to use and adapt in any project, including commercial ones, with no credit needed. Fonts are Google Fonts under their own licences.
AI

Build this with your AI

Fonts: IBM Plex Sans (Google Fonts)

Writing about this component?

More toggle switch components

Toggle switch component — web, corporate (Fernway)
web · corporate
Toggle switch component — mobile, minimal (Fernway)
mobile · minimal
Toggle switch component — mobile, editorial (Fernway)
mobile · editorial
Toggle switch component — mobile, brutalist (Fernway)
mobile · brutalist
Toggle switch component — mobile, luxury (Fernway)
mobile · luxury
Toggle switch component — mobile, playful (Fernway)
mobile · playful
Toggle switch component — mobile, retro (Fernway)
mobile · retro
Toggle switch component — mobile, monochrome (Fernway)
mobile · monochrome
Building with an AI coding agent? Every screen here is also in the free Made Good Designs MCP server: ask Claude, Cursor or ChatGPT to search_ui_screens (e.g. “billing settings, editorial style”), get_ui_flow for a whole journey, and get_ui_screen_code to pull the HTML and DESIGN.md straight into your project.

Save to board