Cute Bubble Sliders
Here’s a recipe with the style taken directly from one of my most popular CodePens.
Most of the work is using the CSS
variables to control the colors. With a little
bit of CSS
to control the rangeNub
, rsPip
, and rangeFloat
position.
Check out the CSS
tab, below, for the full CSS
code.
<script>
let sliderValues = [15, 35];
let max = 50;
</script>
<div id="cute-sliders">
<RangeSlider class="cute" range bind:values={sliderValues} pips pipstep={1} {max} float />
<div class="flex">
<RangeSlider class="cute" value={10} pips pipstep={1} max={30} vertical float range="min" />
<RangeSlider class="cute" value={15} pips pipstep={1} max={30} vertical float />
<RangeSlider class="cute" value={20} pips pipstep={1} max={30} vertical float range="max" />
</div>
</div>
#cute-sliders .rangeSlider {
/* start by declaring all the Colors we want to use */
--color-base-light: #b5c0c9;
--color-base-dark: #606d7b;
--color-1: #2fd4a3;
--color-1-dark: color-mix(in srgb, var(--color-1) 75%, black);
--color-1-light: color-mix(in srgb, var(--color-1) 75%, white);
--color-2: #f27793;
--color-2-dark: color-mix(in srgb, var(--color-2) 75%, black);
--color-2-light: color-mix(in srgb, var(--color-2) 75%, white);
--color-3: #bd77f2;
--color-3-dark: color-mix(in srgb, var(--color-3) 75%, black);
--color-3-light: color-mix(in srgb, var(--color-3) 75%, white);
--color-4: #67c3ec;
--color-4-dark: color-mix(in srgb, var(--color-4) 75%, black);
--color-4-light: color-mix(in srgb, var(--color-4) 75%, white);
/* now apply the colors to the RangeSlider variables */
--slider-base: var(--color-1-light); /* when non-focused, we use the light color */
--slider-fg: var(--slider-base);
--slider-bg: var(--color-base-light);
--slider-accent: var(--slider-base);
--slider-accent-100: var(--slider-base);
--range-pip: var(--slider-bg);
--float: transparent; /* we will put the float over the nub, so we don't need a background */
--float-inactive: transparent;
/* define the size and width of the pips */
--pip-size: 12px;
--pip-width: 2px;
/* when the slider is hovered or focused, apply the base colors */
&:hover, &.rsFocus {
--color-1-light: var(--color-1);
--color-2-light: var(--color-2);
--color-3-light: var(--color-3);
--color-4-light: var(--color-4);
}
/* the vertical slider will use different base colors */
&.rsVertical:nth-child(1) { --slider-base: var(--color-2-light); }
&.rsVertical:nth-child(2) { --slider-base: var(--color-3-light); }
&.rsVertical:nth-child(3) { --slider-base: var(--color-4-light); }
/* set a max width / height so the pips have a set spacing */
max-width: 400px;
margin-inline: auto;
&.rsVertical {
min-height: auto;
height: 150px;
}
/* rotate the nubs so they sit off the edge of the slider */
& .rangeNub {
border-radius: 10em 10em 10em 1.6em;
transform: translateX(-1.2em) rotate(-135deg);
box-shadow: -4px 4px 0 1px var(--bg);
}
&:not(.rsVertical) .rangeNub {
transform: translateY(-1.2em) rotate(-45deg);
}
& .rsPip {
width: var(--pip-width);
height: var(--pip-size);
transform-origin: top;
translate: -1px 0;
border-radius: 3px;
transition-duration: 0.6s;
}
&.rsVertical .rsPip {
width: var(--pip-size);
height: var(--pip-width);
transform-origin: left;
translate: 0 1px;
}
/* when the pip is selected, make it bigger and change the color */
& .rsPip.rsSelected {
height: var(--pip-size);
scale: 1 1.75;
transition-duration: 0.2s;
box-shadow: 0 0 0 1px var(--slider-fg);
}
&.rsVertical .rsPip.rsSelected {
width: var(--pip-size);
height: 2px;
scale: 1.75 1;
}
/* hide the handle hover-target effect */
& .rangeHandle::before {
display: none;
}
/* position the float label, and make it contrast */
& .rangeFloat {
opacity: 1;
color: color-mix(in hsl, var(--slider-base) 60%, var(--fg));
text-shadow: 0 1px 0px var(--bg);
font-weight: 700;
bottom: 1.2em;
translate: -50% 0;
}
/* the vertical floats need a little more work */
&.rsVertical .rangeFloat {
width: 3em;
top: 50%;
bottom: auto;
left: -30%;
translate: -50% -50%;
}
& .rangeBar {
transition: background-color 0.2s ease-in-out, opacity 0.2s ease-in-out;
}
}
/* dark theme colors */
.theme-dark #cute-sliders .rangeSlider {
--slider-bg: var(--color-base-dark);
--slider-base: var(--color-1-dark);
&:hover, &.rsFocus {
--color-1-dark: var(--color-1);
--color-2-dark: var(--color-2);
--color-3-dark: var(--color-3);
--color-4-dark: var(--color-4);
}
&.rsVertical:nth-child(1) { --slider-base: var(--color-2-dark); }
&.rsVertical:nth-child(2) { --slider-base: var(--color-3-dark); }
&.rsVertical:nth-child(3) { --slider-base: var(--color-4-dark); }
& .rangeFloat {
color: color-mix(in hsl, var(--slider-base) 40%, var(--bg));
text-shadow: none;
}
}