Skip to content

Slider Brightness

Use the indexed thumb-1 slot and shared tooltip slot with part styling.

Code

The following example assumes that you have imported the component and set up the theme.

Brightness Slider
<div class="slider-wrapper">
<!-- Brightness slider component -->
<sv-slider class="brightness-slider" aria-label="Brightness" value="50">
<!-- Tooltip with glass effect -->
<div class="tooltip glass" aria-hidden="true" slot="tooltip">
<strong>
<sv-text-flow data-value></sv-text-flow>
</strong>
</div>
<!-- Custom thumb with glass effect -->
<div class="custom-thumb glass" aria-hidden="true" slot="thumb-1">
14 collapsed lines
<svg class="sun-icon" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
<g class="sun-rays" stroke="currentcolor" stroke-linecap="round" stroke-width="4">
<line x1="60" x2="60" y1="10" y2="30"></line>
<line x1="60" x2="60" y1="90" y2="110"></line>
<line x1="10" x2="30" y1="60" y2="60"></line>
<line x1="90" x2="110" y1="60" y2="60"></line>
<line x1="25" x2="38" y1="25" y2="38"></line>
<line x1="95" x2="82" y1="25" y2="38"></line>
<line x1="25" x2="38" y1="95" y2="82"></line>
<line x1="95" x2="82" y1="95" y2="82"></line>
</g>
<circle cx="60" cy="60" fill="currentcolor" r="18"></circle>
</svg>
</div>
</sv-slider>
</div>
<!-- Animate thumb's icon on value change -->
<script type="module">
23 collapsed lines
/** @type {Slider} */
const slider = document.querySelector(".brightness-slider");
/** @type {SVGElement} */
const sunRays = document.querySelector(".sun-rays");
const initialValue = slider.value;
if (!Array.isArray(initialValue)) {
setRayScale(initialValue);
}
slider.addEventListener("valuechange", event => {
setRayScale(event.detail.value);
});
/** @param {number} value */
function setRayScale(value) {
const min = 0.4;
const max = 1;
const scale = min + (value / 100) * (max - min);
sunRays.style.scale = String(scale);
}
</script>
<style>
.slider-wrapper {
6 collapsed lines
display: flex;
gap: 1em;
align-items: center;
padding: 4em 3em;
background: linear-gradient(90deg, #313636, #807058);
border-radius: 4px;
}
.custom-thumb {
20 collapsed lines
inline-size: var(--sv-thumb-size);
block-size: var(--sv-thumb-size);
border-radius: 50%;
scale: 1;
transition: scale var(--sv-dur) var(--sv-ease);
.sun-rays {
transform-origin: center;
}
.sun-icon {
display: block;
margin: auto;
color: #fffcf9;
filter: drop-shadow(0 0 3px rgb(0 0 0 / 40%));
}
@media (prefers-reduced-motion: reduce) {
transition-duration: 0s;
}
}
.tooltip {
7 collapsed lines
display: grid;
place-items: center;
inline-size: 2.2em;
block-size: 2.2em;
color: #fffcf9;
white-space: nowrap;
border-radius: 50%;
}
.brightness-slider {
--sv-thickness: 2em;
--sv-thumb-size: 2.8em;
--sv-bdr-rad-md: 2em;
--sv-tooltip-offset: 2em;
--sv-ease: cubic-bezier(0.25, 1, 0.5, 1);
flex: 1;
cursor: grab;
&::part(slider) {
box-shadow: 0 0 10px #00000060;
}
&::part(track) {
background-color: #242623;
border: none;
}
&::part(fill) {
background-color: #ffe6d4;
}
&::part(tooltip) {
background-color: transparent;
border: none;
}
&::part(tooltip-arrow) {
display: none;
}
&:state(--active) {
cursor: grabbing;
.custom-thumb {
scale: 1.214;
}
}
}
.glass {
31 collapsed lines
position: relative;
overflow: clip;
background: #ffffff1a;
box-shadow:
0 6px 16px #00000045,
inset 0 1px 1px #ffffff8c;
backdrop-filter: blur(1px);
/* Refraction: bends what sits behind the thumb through the lens map, clear center. */
&::before {
position: absolute;
inset: 0;
content: "";
border-radius: inherit;
backdrop-filter: blur(0.4px);
}
/* Edge ring that reflects the colors behind it, glinting along the light diagonals */
&::after {
position: absolute;
inset: 0;
padding: 1px;
content: "";
border-radius: inherit;
backdrop-filter: blur(4px) brightness(180%) saturate(190%);
mask:
conic-gradient(#00000040 0deg, #000 110deg, #000 170deg, #00000026 250deg, #000 290deg, #000 340deg, #00000040 360deg),
linear-gradient(#000 0 0) content-box,
linear-gradient(#000 0 0);
mask-composite: intersect, exclude, add;
}
}
</style>