Theme
On this page (3)
Component Skill — components/filter-bar/component-skill.md

Native basis

A <form method="get"> in one row: native Selects, checkbox chips (.mk-filter-bar-chip), a "More filters" Button with a count, and the result count; it scrolls on small screens.

Built from

Select, Button, Badge.

Web Platform APIs

:has()CSS scroll snap

Classes

.mk-filter-bar.mk-filter-bar-chip.mk-filter-bar-sep.mk-filter-bar-count

Data attributes

data-variant="sticky".

§Default

A GET form on one row - native Selects as pills, checkbox chips (:has(:checked) fills them), "More filters" with a count, and the result count; the row scrolls sideways on small screens.

§Sticky

data-variant='sticky': sticks to the top of its scroll container on a blurred surface - scroll the box.

§CSS view file

/* -- Filter Bar (website · Search & Navigation) ---------------------------
   Presents compact controls for narrowing a collection - selects, toggle chips and a "more filters" action on one scrollable row, with the count. */
@layer components {
  /* every box in the block measures border-box - the same on any page */
  :where(.mk-filter-bar, .mk-filter-bar *, .mk-filter-bar ::before, .mk-filter-bar ::after) { box-sizing: border-box; }
  .mk-filter-bar { width: 100%;
    & form { display: flex; align-items: center; gap: 0.5rem; padding-block: 0.5rem; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: thin; }
    & .select { width: auto; height: 2rem; padding-block: 0; font-size: 0.8125rem; border-radius: 999px; flex: none; }
    & .btn { flex: none; border-radius: 999px; }
  }
  .mk-filter-bar-chip { position: relative; display: inline-flex; align-items: center; gap: 0.375rem; height: 2rem; padding-inline: 0.75rem; border: 1px solid var(--border); border-radius: 999px; font-size: 0.8125rem; font-weight: 500; cursor: pointer; white-space: nowrap;
    flex: none;
    & input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
    & svg { width: 0.875rem; height: 0.875rem; }
    &:has(:checked) { border-color: var(--foreground); background: var(--foreground); color: var(--background); }
    &:has(:focus-visible) { outline: 2px solid var(--ring); outline-offset: 2px; }
  }
  .mk-filter-bar-sep { flex: none; width: 1px; height: 1.25rem; background: var(--border); }
  .mk-filter-bar-count { flex: none; margin-inline-start: auto; padding-inline-start: 1rem; color: var(--muted-foreground); font-size: 0.8125rem; white-space: nowrap; }
  .mk-filter-bar[data-variant="sticky"] { position: sticky; top: 0; z-index: 10; border-block-end: 1px solid var(--border); background: color-mix(in oklch, var(--background) 85%, transparent); backdrop-filter: blur(10px); }
  /* -- Accessibility ------------------------------------------- */
  @media (forced-colors: active) {
    .mk-filter-bar-chip:has(:checked) { background: Highlight; color: HighlightText; }
  }
}

Comments, ideas or improvements? Edit this page's source on GitHub