Menu


Filter bar


Search, filters, sort and Clear all together above a list or a table, with the filters applied as chips and the number of results they leave.

Customize the preview


View

Options


The filter bar has no choices: it is drawn one way.

Examples


Usage

The search, the filters opener and the sort above the list, with the number of results under them. Tick filters in the menu; each one applied shows as a chip.

Query entered

A typed search shows the clear button in place of the key hint.

Filters applied

The filters applied as chips, each with a cross that names it, and Clear all. Remove one and focus moves to the chip that takes its place; the new count is read out.

Loading

While results load, the count gives way to the turning ring and “Updating results”, read out the same way.

View switch

A view switch at the end, for a list that can also be shown as a board.

Narrow

In a narrow space the search and the filters opener stay; the opener shows a drawer holding the filters and the sort, which the bar leaves out. The chips wrap onto more rows.

Guidelines


Purpose

Search, filters, sort and Clear all together above a list or a table, with the filters applied shown as chips and the number of results they leave. It is a search landmark, so a screen reader can jump to it, and every control in it keeps its own Tab stop. It differs from a toolbar, which is one Tab stop moved through with the arrow keys and is for commands, and from a search field alone, which narrows a list by its words only.

When to use

  • Above a list, a table or a board that people narrow by words and by a few attributes, and sort.
  • When the filters applied must stay in view, so nobody wonders why an item is missing.

When not to use

  • A single search box over a short list. Use the search field alone.
  • Commands for a view, such as refresh or download. Use a toolbar; it can hold a search field and a filters opener too.
  • Filters that take a page of their own, such as facets down the side of a large catalog. Lay those out on the page, with the chips of the filters applied above the results.
  • Saying there are no results or that something failed. That belongs to the results, under the bar.

Usage rules

Do

  • Show every filter applied as a chip, and the number of results left.
  • Name the bar, the search field and the sort list.
  • Keep the filters and the sort where a narrow page can reach them.

Don't

  • Hide filters that are on behind the opener's count alone.
  • Put the no-results message or an error inside the bar.
  • Clear the filters when someone leaves the page and comes back, unless they asked for it.
Do

Show every filter applied as a chip, with the number of results it leaves.

Don't

A count on the opener alone hides which filters are on; the reader has to open the menu to find out.

Anatomy

  • The block: a search landmark with a name of its own. It has no fill or edge; its controls keep theirs. Up to three rows, the large stack space apart.
  • controls: the first row. search holds the search field, which takes the room left over; filters holds the filters opener; sort holds the sort list at a fixed width; view holds an optional view switch at the end.
  • opener: the filters opener, the outline button with a funnel and its words, and beside it, while filters are applied, opener-count, the small badge with how many.
  • narrow-filters: an optional opener shown in place of the filters in a narrow space, such as one that opens a drawer holding the filters and the sort.
  • applied: the second row, shown only while filters are applied: each filter as a small removable chip, then clear, a button drawn as the small link that removes them all. The chips wrap onto more rows.
  • count: the last row, the number of results the filters leave, in Body SM; while results load, the spinner's ring and "Updating results" in its place.

The controls are the medium size, 40 tall.

Behavior

Ticking filters in the opener's menu applies them at once: each shows as a chip, the opener's badge counts them, and the count below says how many results are left. A chip's cross removes its filter; Clear all removes every one. The bar shows "Updating results" with the turning ring while the results load, and the count again when they arrive.

In a narrow space the search field and the filters opener stay and the sort list and the view switch go, since a narrow page reaches them where its filters open: a page can give a narrow opener of its own for a drawer that holds the filters and the sort. The applied chips stay in view and wrap.

The page holds the query, the filters applied and the count, and decides when the results change. Nothing moves.

Accessibility


What it does for you

  • The bar is a search landmark with a name, given as its label.
  • Tab goes through the search field, the filters opener, the sort list, the view switch, each chip's cross and Clear all, in that order.
  • The opener says its count in words after its own words ("Filters, 2 applied"), so a voice command for "Filters" still finds it; the badge is hidden from screen readers.
  • Each chip's cross is a real button named for its filter ("Remove Status: Open"). Removing one moves focus to the chip that takes its place, the next or else the one before; when the last goes, by its cross or by Clear all, focus goes back to the filters opener. A page that takes the filter away only once the results come back gets the same: focus waits on the cross until the chip goes.
  • The count is a status message: a screen reader reads each new count, and "Updating results", without focus moving. It is in the page from the start, so the first count is not read out on arrival.
  • The sort list is named for what it does ("Sort by"), so it is never taken for a filter.

What you must do

  • Name the bar with its label. A page with more than one names each differently.
  • Name the search field and the sort list.

How to test

  • With the keyboard only, Tab through the bar: the order is the search field, the filters opener, the sort list, the view switch, each chip's cross, then Clear all.
  • Remove a chip with Enter: focus moves to the chip that takes its place, and to the filters opener when the last goes.
  • With a screen reader, the bar is found as a search landmark by its name, the opener is read with its count, and each cross is read with its filter.
  • Change a filter: the new count is read out without focus moving.
  • With text at 200% and the page 320 pixels wide, the search, the filters and the sort stay reachable.
  • In a forced-color mode, the chips, crosses and focus rings are still visible.

Keyboard

Filter bar keys
KeyWhat it does
TaborShift+Tab
Moves focus along the bar: the search field, the filters opener, the sort list, the view switch, each chip's cross and Clear all.
EnterorSpace
On the filters opener, a chip's cross or Clear all, presses it.

Source


The files the filter bar is made of. Its folder on GitHub (opens in a new tab) holds them with its wrapper and its document.

Stylesheet
filter-bar.css
/* smbk-filter-bar — Filter bar. Figma "Filter bar" 7117:565: Layout (Wide, Narrow) × Condition (Pristine, Query
 * entered, Filters applied, Loading), 8 variants.
 * A column of up to three rows, the large stack space apart: the controls (the search field, the filters opener, the
 * sort list, the view switch), the filters applied as chips with Clear all, shown only while any are applied, and the
 * result count. The bar has no fill or edge of its own; its controls keep theirs. Every control is the system's own
 * component, at the medium size as Figma draws them; this sheet only lays them out.
 * Narrow (the layout switch): the search field and the filters opener stay; the sort list and the view switch go,
 * since a narrow page reaches them where its filters open, such as a drawer. A page that gives a narrow opener of its
 * own (narrow-filters) shows it in place of the filters part. */

.smbk-filter-bar {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: var(--smbk-space-stack-lg);
  min-inline-size: 0;
}

/* ---- the controls: the search field takes the room left over ---- */

.smbk-filter-bar__controls {
  display: flex;
  align-items: center;
  gap: var(--smbk-space-inline-md);
  min-inline-size: 0;
}

.smbk-filter-bar__search {
  display: flex;
  flex: 1 1 0;
  min-inline-size: 0;
}

.smbk-filter-bar__filters,
.smbk-filter-bar__view {
  display: inline-flex;
  flex: none;
  align-items: center;
}

.smbk-filter-bar__narrow-filters {
  display: none;
  flex: none;
  align-items: center;
}

.smbk-filter-bar__sort {
  display: flex;
  flex: none;
  inline-size: var(--smbk-size-filter-bar-sort-width);
}

/* The filters opener: the outline button, and beside it the number of filters applied in the small badge. The
   number is the badge's to show and the button's to say: the button's name carries it in words. */
.smbk-filter-bar__opener {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: var(--smbk-space-inline-xs);
}

/* ---- the filters applied: small removable chips that wrap onto more rows, Clear all after the last ---- */

.smbk-filter-bar__applied {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--smbk-space-inline-sm);
}

/* Clear all is a button drawn as the small link, since it acts on the page rather than going anywhere. */
.smbk-filter-bar__clear {
  flex: none;
}

/* ---- the result count: Body SM in the secondary text color; while results load, the spinner's ring and words
   that say so in its place ---- */

.smbk-filter-bar__count {
  display: flex;
  align-items: center;
  gap: var(--smbk-space-inline-xs);
  color: var(--smbk-color-text-subtle);
  font-family: var(--smbk-typography-body-sm-font-family);
  font-size: var(--smbk-typography-body-sm-font-size);
  font-weight: var(--smbk-typography-body-sm-font-weight);
  line-height: var(--smbk-typography-body-sm-line-height);
  letter-spacing: var(--smbk-typography-body-sm-letter-spacing);
  font-variant-numeric: tabular-nums;
}

/* ---- narrow ---- */

@container style(--smbk-layout: narrow) {
  .smbk-filter-bar__sort,
  .smbk-filter-bar__view,
  .smbk-filter-bar__controls:has(> .smbk-filter-bar__narrow-filters) > .smbk-filter-bar__filters {
    display: none;
  }

  .smbk-filter-bar__narrow-filters {
    display: inline-flex;
  }
}

/* ---- touch: the filters applied and Clear all stop their press areas halfway to each other ----
   On a touch screen each remove cross and Clear all take an invisible area, centred on them; in the row of filters
   applied, which wraps, each reaches only halfway into the row's gaps, so every filter stays one press. Nothing drawn
   moves. */

@media (pointer: coarse) {
  .smbk-filter-bar__clear {
    position: relative;
  }

  .smbk-filter-bar__clear::after {
    content: '';
    position: absolute;
  }

  .smbk-filter-bar__applied .smbk-chip__remove::after,
  .smbk-filter-bar__applied .smbk-filter-bar__clear::after {
    inset: max(min(0%, (100% - var(--smbk-size-target-comfortable)) / 2), var(--smbk-space-inline-sm) / -2);
  }
}
Tokens it reads
Filter bar tokens
Token and CSSValuePreviewFoundation
space.stack.lg--smbk-space-stack-lgcomfortable: 16pxcompact: 12pxchanges with densitySpacing
space.inline.md--smbk-space-inline-mdcomfortable: 8pxcompact: 6pxchanges with densitySpacing
size.filter-bar.sort-width--smbk-size-filter-bar-sort-width240pxSize
space.inline.xs--smbk-space-inline-xs4pxSpacing
space.inline.sm--smbk-space-inline-smcomfortable: 6pxcompact: 4pxchanges with densitySpacing
color.text.subtle--smbk-color-text-subtlelight: #4e555edark: #9ba5b1changes with themeColor
typography.body-sm--smbk-typography-body-sm-font-family--smbk-typography-body-sm-font-size--smbk-typography-body-sm-font-weight--smbk-typography-body-sm-line-height--smbk-typography-body-sm-letter-spacing--smbk-typography-body-sm-text-transformfontFamily: Geist, Geist Fallback, system-ui, sans-seriffontSize: 14pxfontWeight: 400lineHeight: 1.5letterSpacing: 0px

The quick brown fox

Typography
size.target.comfortable--smbk-size-target-comfortable44pxSize
Manifest
filter-bar.manifest.json
{
  "name": "filter-bar",
  "block": "smbk-filter-bar",
  "summary": "Search, filters, sort and Clear all together above a list or a table, with the filters applied as chips and the number of results they leave.",
  "adapt": "css",
  "axes": {},
  "flags": {},
  "parts": [
    "controls",
    "search",
    "filters",
    "narrow-filters",
    "sort",
    "view",
    "opener",
    "opener-count",
    "applied",
    "clear",
    "count"
  ],
  "figmaNodeId": "7117:565"
}