skip to content
menu
components · filter bar

filter bar

A filter bar lets people narrow a list down: a search, a few facets to filter by, a button that clears them all, and the count of what is left. When the bar is narrow, the facets fold away behind one “filters” button.

when to use

  • Above a list or a table, for the search and the two to four facets that narrow it.
  • With the count of the results, such as “312 of 2,500”, so people see the filters work, and people who use a screen reader hear it.
  • Under the filter tabs and above the toolbar, the way the worklist arranges them.

when to use something else

  • For a few key figures that each pick one part of the list. Use filter tabs, which show each part's count.
  • To sort. People sort with the column headers of the data table.
  • For a form that is sent, such as settings or a new item. Use fields and a save button, as in forms and settings. The filter bar filters as the values change, and sends nothing.
  • For actions on the list. Use a toolbar.

anatomy

  1. Bar. A row that wraps onto more lines when it has to. It is a search landmark: a region that people who use a screen reader can jump straight to.
  2. Search (optional). A search field with a small square magnifying glass in front. It grows and shrinks with the bar, within limits.
  3. Facets. A facet that keeps one value is a short lowercase label and a select; while it filters, its value turns blue. A facet that keeps several values is a multi select.
  4. Your own controls (optional). They come after the facets, and fold away with them.
  5. End. Pushed to the right: the count of what is left, and “clear all”, a quiet button. On a narrow bar, “clear all” moves to the end of the folded facets.
  6. Filters button (narrow bars only). A standard button that shows and hides the facets: “filters”, or “filters · 2” while two facets are set.

variants and states

On a wide bar, everything sits in one row, which wraps when it has to.

On a narrow bar, the facets fold away behind the “filters” button. The bar goes by its own width, not the screen's. The search and the button share the first line, and the facets open in a column under them, with “clear all” at their end. The count keeps a line of its own, and takes no room while there is no count. The button counts the facets that are set, not the search.

A search can also stand on its own, with a count:

A facet is set while it filters. A facet with one value is set when its value isn't the option that means no filter; a facet with several values is set when anything in it is chosen. The “clear all” button works while any facet is set or the search holds text, and it is disabled otherwise.

behaviour

  • The list filters as the values change: with every key people type in the search, and as soon as they change a facet.
  • The “clear all” button empties the search and resets every facet.
  • esc in the search clears it, when it holds text.
  • The “filters” button starts closed, and stays open or closed for as long as the bar is on the page. tab skips the folded facets.

The full keyboard map is on the filter bar's React page.

accessibility

  • The bar is a search landmark, named “filters” unless you give it a name, so people who use a screen reader can jump to it. With two filter bars on one page, give each its own name.
  • The search field has a name of its own: “search”, unless you give it one. The placeholder is only a hint: it is gone with the first key people type.
  • A facet's label is its name, such as “kind”.
  • The count is announced. It is a live region: each change is read out whole, such as “312 of 2,500”, when the screen reader has a pause. It is how someone who is typing hears that the list changed, also when nothing is left.
  • Pressing “clear all” moves focus to the search field, because the button disables itself once everything is clear.

Today:

  • On a narrow bar, “clear all” folds away with the facets, so people can reach it only once “filters” is open.
  • “clear all” and “filters” are fixed English words, and can't be translated.
  • “clear all” only knows the search and the facets. A control of your own, after the facets, doesn't turn it on.
  • A narrow bar with your own controls, or “clear all”, but no facets shows no “filters” button. The controls and “clear all” stay folded away, with no way to open them.

content

  • Search. The placeholder says what can be searched: “search titles”. Give the search field's name the same words.
  • Facet labels. A noun: “kind”, “aired”, “state”.
  • The no-filter option. First in every select, in plain words: “all”, “any time”.
  • The count. What is left, out of what: “312 of 2,500”, with thousands separators. While nothing filters, show the total, “2,500”, or nothing.
  • Two to four facets. With more, the bar turns into a form.

do and don't

do
The count says what is left: people see the filters work, and screen readers hear each change.
don't
No count: people can't tell whether the filters did anything, and people who use a screen reader hear nothing as the list changes.
do
The no-filter option comes first, so every facet has a way back.
don't
No “all” option: the facet can never stop filtering, and “clear all” has nothing to go back to.
  • Multi select: the facet that keeps several values.
  • Filter tabs: key figures above the filter bar, each picking one part of the list.
  • Empty state: its search kind, which the list shows when the filters leave nothing, with a “clear filters” button.
  • Worklist: the tabs, the filter bar, the toolbar and the table, each in its place.

specs

part in code spec
Bar FilterBar, named by label (default “filters”) role="search". A flex row that wraps, with gaps of 8px between lines and 12px between items (--s-2 × --s-3).
Search search: value, onChange, placeholder, label (default “search”) An Input with type="search" at md, 34px tall, with a 14px square search glyph in front. It starts at 240px and grows or shrinks between 180 and 420px.
Select facet filters: type: 'select'; emptyValue is its no-filter value (default '') A visible label (JetBrains Mono 12px, --fg-muted, lowercase, on one line) and a native Select at md, at least 128px wide, 8px apart. While it is set, its value shows in --cloud-blue.
Multi select facet filters: type: 'multiselect' A MultiSelect at md.
Your controls children After the facets; they fold with them.
Count resultCount JetBrains Mono 12px, --fg-muted, tabular figures. A live region (aria-live="polite", aria-atomic="true") that is always on the page, so the first count is announced too.
Clear all onClearAll A ghost md button, “clear all”, pushed to the end with the count. Enabled while a facet is set or the search holds text. It moves focus to the search before it disables itself.
Filters toggle narrow only A default md button, “filters” or “filters · 2”, with aria-expanded and aria-controls. Folded facets are hidden, out of the tab order.
  • Narrow: collapseBelow, 640px by default, measured on the bar's own width. The search and the toggle share the first line; the facets open in a full-width column below, each select up to 260px wide, with clear all at their end; the count takes a line of its own, and an empty count takes no room.
  • Set: a select facet is set while its value isn't emptyValue; a multi select facet while its value isn't empty. The toggle counts the set facets, not the search.
  • Keys: esc in the search clears it, when it holds text. Typing filters on every keystroke.