Geometric Custom Range Sliders
See the Pen Geometric Custom Range Sliders.
Tech & Dependencies
Features
- ✓ CSS Masks
- ✓ Mask Composition
- ✓ SCSS Math
- ✓ Gradient Fill
Browser Support
Core
These Geometric Custom Range Sliders push the boundaries of form styling by abandoning the standard “circle on a line” look. Created by CSS math wizard Ana Tudor, this set utilizes SCSS trigonometry to generate complex thumb shapes (like triangles and hollow pills) and CSS Mask Composition to carve out negative space. The result is a set of distinct, scalable inputs that rely on a single HTML <input> tag without any wrapper divs.
Core Technique
The visual complexity here is achieved through two advanced techniques: Gradient Tracking and Mask Composition.
- The Track Fill: Unlike standard inputs, the “filled” part of the bar isn’t a separate element. It’s a
linear-gradienton the track’s background. JavaScript updates a CSS variable--valwhenever the input changes, which calculates the gradient’s width. - The Thumb Shapes: The custom shapes (triangles, cut-outs) are created using
mask-imageandmask-composite: exclude. For example, to create a hollow circle, the code layers a solid gradient mask over a smaller circle mask and instructs the browser to “exclude” the overlapping area.
/* Example of creating a hollow shape using masks */
.thumb {
/* Define layers: A full gradient and a radial gradient circle */
mask:
linear-gradient(#fff, #fff), /* Layer 1 (Full) */
radial-gradient(circle at center, black 5px, transparent 6px); /* Layer 2 (Hole) */
/* Cut layer 2 out of layer 1 */
mask-composite: exclude;
}
Customization
The sliders are powered by CSS variables injected via the style attribute in HTML. To customize colors or values, you manipulate these variables directly.
<!--
--val: Initial value (0-100) /
--c0: Start color /
--c1: End color /
-->
<input type="range"
min="0" max="100"
style="--val: 50; --c0: #47b784; --c1: #4b569f">
The underlying math for dimensions is handled in the SCSS.
/* Size Configuration in SCSS */
$track-w: 20em; /* Width */
$track-h: 1.5em; /* Height */
$round-r: $track-h/3; /* Corner Radius */
Tips
1. Cross-Browser Styling:
Styling range inputs requires targeting browser-specific pseudo-elements separately. You cannot group selectors like ::-webkit-slider-thumb, ::-moz-range-thumb because if a browser doesn’t understand one part of the selector, it invalidates the entire rule.
/* DO THIS */
&::-webkit-slider-thumb { @include thumb-styles; }
&::-moz-range-thumb { @include thumb-styles; }
/* DON'T DO THIS */
&::-webkit-slider-thumb, &::-moz-range-thumb { ... }
2. JavaScript Sync: This effect requires JavaScript to update the visual “fill” of the bar. Ensure your JS listener is robust.
// Syncs the CSS variable with the input's actual value
addEventListener('input', e => {
let _t = e.target;
_t.style.setProperty('--val', +_t.value)
})
3. Mask Support:
While mask-composite is supported in modern browsers, older versions of Safari (Webkit) might behave differently or require the -webkit- prefix. Always test distinct shapes on an actual iOS device.


