Advertisement

E-commerce Product Filter

| by Vladimir | 2 min read | code by Aryan Tayal
Intermediate

Tech & Dependencies

HTML CSS

Features

  • CSS Logic
  • Sticky Sidebar
  • No JavaScript

Browser Support

Chrome 105+ Edge 105+ Firefox 121+ Safari 15.4+

Core

This is a Pure CSS E-commerce Product Filter. It replaces JavaScript-based array filtering with native CSS relationship selectors. Its function is to toggle product visibility based on multiple checkbox states within a sidebar, offering an instant, script-free sorting mechanism for catalog grids.

Specs

  • Weight: ~7 KB. Zero dependencies. No JavaScript.
  • Performance: High. Relies exclusively on the browser’s native CSS evaluation engine, avoiding JavaScript array mapping and DOM reflow loops.
  • Theming / Customization: Core aesthetics are managed via CSS variables (--gray-dark, --gray-light). The structure utilizes CSS Grid for both the layout shell and the product catalog.
  • Responsiveness: Fluid. Native media queries collapse the grid columns and convert the sticky sidebar into a hidden overlay triggered by a floating action button on mobile viewports.
  • [!] Graceful Degradation: Fails completely if the browser does not support the :has() pseudo-class. In unsupported environments, all products remain visible regardless of checkbox states.

Anatomy

The system connects unrelated DOM trees using advanced sibling combinators.

  • HTML (The Skeleton): An <aside> wrapper contains standard <input type="checkbox"> elements. The adjacent <main> container holds .shoe-card items marked with specific data-* attributes (data-gender, data-sport, data-collection).
  • CSS (The Skin): Hides the native input interfaces to render custom visual checkboxes. It relies on position: sticky to keep the filter panel accessible during scrolling.
  • JS (The Nervous System): Absent. The logic is strictly state-driven.

Logic

The entire filtering mechanism is powered by the :has() relational pseudo-class:

aside:has(input[id="men"]:not(:checked)) + main > .shoe-card[data-gender="men"] {
  display: none;
}

Instead of using JavaScript to listen for change events, the CSS engine constantly evaluates the DOM tree. If the <aside> contains an unchecked “men” input, the selector steps forward to the adjacent <main> element and applies display: none to any child card matching data-gender="men". This declarative approach maps the form states directly to data attributes without intermediate computational logic.

Feel

Instant and absolute. Because the visibility logic is executed directly by the rendering engine, there is zero latency between clicking a filter and the grid updating. The interface snaps into its new state immediately, providing a raw, unfiltered response to user intent without loading spinners or transition delays.

Advertisement