E-commerce Product Filter
See the Pen E-commerce Product Filter.
Tech & Dependencies
Features
- ✓ CSS Logic
- ✓ Sticky Sidebar
- ✓ No JavaScript
Browser Support
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-carditems marked with specificdata-*attributes (data-gender,data-sport,data-collection). - CSS (The Skin): Hides the native input interfaces to render custom visual checkboxes. It relies on
position: stickyto 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.


