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(+ optionalsq-segmented-sm/sq-segmented-lg,rounded-pill). - One
role="group"+ sharednameon radios; labels arelabel.btnfor eachinput.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-checkradios only — notbtn-group, not mixedbtn-primaryinside the track. - Two to four options; larger sets → select or tabs.
Labels
Short nouns; icon-only inputs need aria-label on the input — Iconography.