data-toggle-tags
Style checkboxes as selectable pill chips for tag-based filtering and multi-select. Pure CSS with optional JavaScript for max selection limits.
Overview
The data-toggle-tags attribute transforms a fieldset of checkboxes into selectable pill-shaped tags. The styling is pure CSS via :has(:checked) — JavaScript is only loaded when you need a max selection limit via data-max.
How It Works
Add data-toggle-tags to a <fieldset> containing checkbox inputs inside labels. The mechanism is primarily CSS:
- Each
<label>is styled as a pill chip with padding, border, and rounded corners - The checkbox inside each label is visually hidden with
opacity: 0 - CSS
:has(:checked)detects when a checkbox is selected and applies the active style - Clicking the label toggles the hidden checkbox, which toggles the visual state
- No JavaScript is needed for the basic toggle behavior
When data-max is set, a small JavaScript module is loaded. It listens for checkbox changes and disables unchecked checkboxes once the limit is reached, re-enabling them when selections are removed.
Attributes
| Attribute | Type | Description |
|---|---|---|
data-toggle-tags |
boolean | Placed on a <fieldset>. Enables pill chip styling for child checkbox labels. |
data-max |
number | Maximum number of selections allowed. When reached, unchecked checkboxes are disabled. Requires JavaScript. |
Basic Tags
Without data-max, toggle tags are entirely CSS-driven. Users can select and deselect any number of tags freely.
Max Selection Limit
Add data-max to cap the number of selections. When the limit is reached, remaining unchecked tags are disabled and visually muted. Deselecting a tag re-enables the others.
Pre-checked Tags
Add the native checked attribute to pre-select tags on load. This works with or without data-max.
Filter UI Pattern
Toggle tags work naturally in filter forms. The checkboxes submit as standard form values, making server-side filtering straightforward.
Form Participation
Because toggle tags use real checkboxes, they participate fully in form behavior without JavaScript:
- Submission — checked tags submit as
name=valuepairs - Reset —
<button type="reset">restores original checked states - Validation — native
requiredworks on individual checkboxes - FormData —
new FormData(form)includes all selected tags
Styling
The pill chip appearance is driven entirely by CSS. The :has(:checked) selector eliminates the need for JavaScript class toggling.
The checked state swaps the background to --color-primary and the text to --color-on-primary. Disabled tags (from data-max) use reduced opacity.
Dynamic Elements
Fieldsets added to the DOM after page load are automatically enhanced via a MutationObserver when data-max is present. No manual initialization is needed. Tags without data-max require no JavaScript at all.
Accessibility
- Native
<input type="checkbox">elements provide full keyboard support — Tab to navigate, Space to toggle - The
<fieldset>and<legend>provide a group label announced by screen readers - Checked/unchecked state is conveyed natively by the checkbox semantics
- Disabled state (from
data-max) is announced via the nativedisabledattribute - Form reset restores original checked states, including visual styling
- Focus indicators use
:focus-visibleon the label for clear keyboard navigation - Without JavaScript, checkboxes render as standard checkboxes with label text (progressive enhancement)