ComponentsFilter Bar
Filter Bar
componentSearch, facets and removable active-filter chips — the query surface for any list.
Filter bar
Search, facets, range & active-filter chips — the query block.
Best practices
Do
- Active filters render as removable chips in the bar — the query state stays visible, not buried in dropdowns.
- Offer a clear-all once two or more filters are active.
- Keep the bar to one row; overflow goes into a 'More filters' popover.
Don't
- Don't duplicate the query state in a table toolbar next to it — one owner per surface.
- Don't make the search input full-width inside the bar; it shares the row with the facets.
Composes: Search Input · Tag Input · Select · Segmented control / Toggle group · Slider · Button · Badge & Chip
Best practices
Do
- Active filters render as removable chips in the bar — the query state stays visible, not buried in dropdowns.
- Offer a clear-all once two or more filters are active.
- Keep the bar to one row; overflow goes into a 'More filters' popover.
Don't
- Don't duplicate the query state in a table toolbar next to it — one owner per surface.
- Don't make the search input full-width inside the bar; it shares the row with the facets.
Recipe CSS
This is the exact CSS your kit ships for Filter Bar — token-driven, so it re-themes with every knob. Get it (and the rest) from the configurator's Use kit panel.
/* === Filter bar ===
The query BLOCK that sits above a list or table: a search field, faceted selects,
an autocomplete, a range, plus an active-filter chip row that summarises and
clears the current query. COMPOSES the querying atoms (.searchinput · .select /
.combobox · .taginput chips · .segctrl · .slider) on the height-invariant
.toolbar, so a real filtering UI is rebuildable from the kit.
Anatomy
.filterbar frame (surface + border + radius)
.toolbar the controls row (search · selects · range · actions)
.filterbar__active active-filter chips + "Clear all" (only when filtered)
.filterbar__active-label
.filterbar__count result count (trailing, in the active row) */
.filterbar { border: 1px solid var(--k-border); border-radius: var(--k-radius-md); background: var(--k-surface); padding: var(--k-s-12); display: flex; flex-direction: column; gap: var(--k-s-10); container: filterbar / inline-size; }
/* Container query (B2) — the facet toolbar already wraps; under ~440px it stacks
* each control full-width so every facet is clearly tappable on a narrow
* container (vs wrapped-but-cramped). Responds to the bar's own width. */
@container filterbar (max-width: 440px) {
.filterbar .toolbar { flex-direction: column; align-items: stretch; }
.filterbar .toolbar__spacer { display: none; }
}
/* A labelled control cluster inside the bar (e.g. "Score" + a slider) — the eyebrow
* names the control without stealing height from the toolbar's one-row invariant. */
/* The slider/label cluster is a control in the bar — give it the bar's height
(inherited --tb-h) so its thin track centers on the one-height row. */
.filterbar__group { display: inline-flex; align-items: center; gap: var(--k-gap, var(--k-s-8)); white-space: nowrap; min-height: var(--tb-h, var(--k-control-h-sm)); }
.filterbar__group-label { font-size: var(--k-type-eyebrow); font-weight: var(--k-weight-medium); text-transform: uppercase; letter-spacing: var(--k-track-eyebrow); color: var(--k-fg-muted); }
/* Active-filter row — divider above, the current facets as removable chips, a
* trailing result count, and a text "Clear all". Hidden until something is filtered. */
.filterbar__active { display: flex; align-items: center; flex-wrap: wrap; gap: var(--k-s-8); padding-top: var(--k-s-10); border-top: var(--k-divider); }
.filterbar__active-label { font-size: var(--k-type-eyebrow); font-weight: var(--k-weight-semibold); text-transform: uppercase; letter-spacing: var(--k-track-eyebrow); color: var(--k-fg-muted); }
.filterbar__count { margin-left: auto; font-size: var(--k-type-small); color: var(--k-fg-muted); white-space: nowrap; }
.filterbar__clear { font-size: var(--k-type-small); color: var(--k-primary); background: none; border: 0; cursor: pointer; padding: 0; }
.filterbar__clear:hover { text-decoration: underline; }