Skip to content

Segmented control ​

Sqrl custom

sq-segmented wrapper + Bootstrap btn-check / btn segments. Switches presentation of the same data (table ↔ cards) — not another page slice or a property filter (Choose a control). Patterns below; usage → Rules.

  • Wrapper: sq-segmented (+ optional sq-segmented-sm / sq-segmented-lg, rounded-pill).
  • One role="group" + shared name on radios; labels are label.btn for each input.btn-check.

Labels ​

Text segments: presentation names (List, Cards) — not filters (All / Mine) and not button-style verb + object.

html
<div class="sq-segmented" role="group" aria-label="Layout">
  <input
    type="radio"
    class="btn-check"
    name="seg-layout"
    id="seg-layout-list"
    autocomplete="off"
    checked
  />
  <label class="btn" for="seg-layout-list">List</label>
  <input
    type="radio"
    class="btn-check"
    name="seg-layout"
    id="seg-layout-cards"
    autocomplete="off"
  />
  <label class="btn" for="seg-layout-cards">Cards</label>
</div>

Icons ​

Icon-only: aria-label on each input.btn-check.

html
<div class="sq-segmented" role="group" aria-label="Layout">
  <input
    type="radio"
    class="btn-check"
    name="seg-icons"
    id="seg-icons-list"
    autocomplete="off"
    checked
    aria-label="List"
  />
  <label class="btn" for="seg-icons-list"><i class="bi bi-list-ul"></i></label>
  <input
    type="radio"
    class="btn-check"
    name="seg-icons"
    id="seg-icons-cards"
    autocomplete="off"
    aria-label="Cards"
  />
  <label class="btn" for="seg-icons-cards"><i class="bi bi-grid"></i></label>
</div>

Sizes ​

sq-segmented-sm, default, sq-segmented-lg (aligns with button heights).

html
<div class="sq-segmented sq-segmented-sm">…</div>
<div class="sq-segmented">…</div>
<div class="sq-segmented sq-segmented-lg">…</div>

Radius ​

Default track radius matches buttons; add rounded-pill on sq-segmented for a pill track.

html
<div class="sq-segmented">…</div>
<div class="sq-segmented rounded-pill">…</div>

More than two options ​

Two to four segments per group; same name on all radios in the group. Still presentation of the same set — not All / Mine filters.

html
<div class="sq-segmented" role="group" aria-label="Layout">
  <input
    type="radio"
    class="btn-check"
    name="layout"
    id="layout-list"
    autocomplete="off"
    checked
  />
  <label class="btn" for="layout-list">List</label>
  <input
    type="radio"
    class="btn-check"
    name="layout"
    id="layout-cards"
    autocomplete="off"
  />
  <label class="btn" for="layout-cards">Cards</label>
  <input
    type="radio"
    class="btn-check"
    name="layout"
    id="layout-board"
    autocomplete="off"
  />
  <label class="btn" for="layout-board">Board</label>
</div>

Disabled ​

disabled on input.btn-check (single option or whole group).

html
<input
  type="radio"
  class="btn-check"
  name="seg-disabled"
  id="seg-disabled-list"
  checked
  disabled
/>
<label class="btn" for="seg-disabled-list">List</label>

Rules ​

When to use ​

  • Exactly one presentation of the same records (list ↔ cards, list ↔ board) — not independent actions (use buttons), not property filters or another page of content (use tabs).
  • Usually in a toolbar or list header, not a form field.

Implementation ​

  • Mutually exclusive btn-check radios only — not btn-group, not mixed btn-primary inside the track.
  • Two to four options; larger sets → select or tabs.

Labels ​

Short nouns; icon-only inputs need aria-label on the input — Iconography.