GitHub

Components / Form & Input / Toggle

Toggle beta

A button that stays pressed — for bold, for pinning, for anything that is a state, not an action.

Preview
<div style="display:flex;gap:14px;align-items:center;flex-wrap:wrap">
  <button class="k-tgl" type="button" aria-pressed="true"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 21s-7-5.5-7-11a7 7 0 0 1 14 0c0 5.5-7 11-7 11Z"/><circle cx="12" cy="10" r="2.6"/></svg> Pinned</button>
  <div class="k-tgroup" role="group" aria-label="Text formatting">
    <button class="k-tgl" type="button" aria-pressed="true" style="font-weight:700">B</button>
    <button class="k-tgl" type="button" aria-pressed="false" style="font-style:italic">I</button>
    <button class="k-tgl" type="button" aria-pressed="false" style="text-decoration:underline">U</button>
  </div>
</div>
.k-tgl{display:inline-flex;align-items:center;gap:7px;height:34px;padding:0 13px;border-radius:9px;border:1px solid var(--k-line);background:var(--k-bg);color:var(--k-ink-2);font-family:var(--k-font);font-size:13px;font-weight:500;cursor:pointer;transition:background .13s,border-color .13s,color .13s}
.k-tgl:hover{border-color:var(--k-border-strong);color:var(--k-ink)}
.k-tgl[aria-pressed="true"]{background:var(--k-ink);border-color:var(--k-ink);color:var(--k-bg);font-weight:600}
.k-tgl:focus-visible{outline:2px solid var(--k-accent);outline-offset:2px}
.k-tgroup{display:inline-flex;gap:5px;padding:4px;border:1px solid var(--k-line);border-radius:12px;background:var(--k-bg)}
.k-tgroup .k-tgl{border-color:transparent}
.k-tgroup .k-tgl[aria-pressed="true"]{border-color:var(--k-ink)}
document.querySelectorAll('.k-tgl').forEach(btn => {
  btn.addEventListener('click', () => {
    btn.setAttribute('aria-pressed', String(btn.getAttribute('aria-pressed') !== 'true'));
  });
});

Usage

For state that lives on the button itself: formatting, filters, pins. If pressing it does something and finishes, that is a Button; if it stays down, it is this.

Accessibility

aria-pressed carries the state, and the pressed style is more than color — weight and fill change too, so the state survives grayscale.

Related parts