<div>
<label for="satisfaction">Rate your experience</label>
<input type="range" id="satisfaction" class="satisfaction" style="--val:1" value="1" min="1" max="5" oninput="this.style='--val:'+this.value">
</div>
body {
margin: 0;
min-height: 100vh;
min-height: 100svh;
display: flex;
align-items: center;
justify-content: center;
font-size: 5vmin;
}
label {
display: block;
font-family: Helvetica, Arial, sysmte-ui, 'System UI', sans-serif;
font-size: 0.875em;
margin-bottom: 0.5em;
}
@property --satisfaction-pct {
syntax: '<percentage>';
initial-value: 0%;
inherits: true;
}
@property --satisfaction-col {
syntax: '<color>';
initial-value: red;
inherits: true;
}
@property --satisfaction-deg {
syntax: '<angle>';
initial-value: 180deg;
inherits: true;
}
@keyframes animationSatisfaction1 {
from { --satisfaction-pct: 0%; --satisfaction-col: #f000; }
to { --satisfaction-pct: 99%; --satisfaction-col: #f008; }
}
@keyframes animationSatisfaction2 {
from { --satisfaction-pct: 10%; --satisfaction-col: #f000; }
to { --satisfaction-pct: 15%; --satisfaction-col: #f004; }
}
@keyframes animationSatisfaction3 {
0%, 100% { --satisfaction-deg: 180deg; }
25% { --satisfaction-deg: 175deg; }
75% { --satisfaction-deg: 185deg; }
}
@keyframes animationSatisfaction4 {
0% { --satisfaction-pct: 0%; }
80% { --satisfaction-pct: 66%; }
100% { --satisfaction-pct: 50%; }
}
@keyframes animationSatisfaction5 {
0% { --satisfaction-pct: 0%; --satisfaction-col: #fff0; }
70% { --satisfaction-pct: 80%; }
100% { --satisfaction-pct: 65%; --satisfaction-col: #fff6; }
}
.satisfaction {
--size: 3em;
--bg: #ddd;
--line: #3213;
--base: #fc0;
--satisfaction-pct: 0%;
--satisfaction-col: #0000;
/* this will be used in two descendants, moving it up */
--active-eyes:
radial-gradient(closest-side circle at 33.5% 48.5%, #fff calc(6% - 1px), #0000 6%) 0 0 / 3em 3em,
radial-gradient(closest-side circle at 63.5% 48.5%, #fff calc(6% - 1px), #0000 6%) 0 0 / 3em 3em,
radial-gradient(closest-side circle at 35% 50%, #000 calc(13% - 1px), #0000 13%) 0 0 / 3em 3em,
radial-gradient(closest-side circle at 65% 50%, #000 calc(13% - 1px), #0000 13%) 0 0 / 3em 3em;
font-size: 1em;
appearance: none;
container-type: inline-size;
height: var(--size);
width: calc(var(--size) * 5);
border: none; /* Firefox adds a default border */
position: relative;
background:
/* mouths */
radial-gradient(50% 100% at 50% 105%, #0000 calc(85% - 1px), var(--line) 85% calc(100% - 1px), #0000) 0.9em 70% / 1.2em 0.5em no-repeat,
radial-gradient(45% 75% at 50% 110%, #0000 calc(75% - 1px), var(--line) 75% calc(100% - 1px), #0000) 4em 65% / 1em 0.35em no-repeat,
linear-gradient(#0000 33.33%, var(--line) 0 66.66%, #0000 0) 6.9em 69% / 1.2em 0.3em no-repeat, radial-gradient(35% 70% at 50% -10%, #0000 calc(72% - 1px), var(--line) 72% calc(100% - 1px), #0000) 9.9em 75% / 1.2em 0.35em no-repeat,
radial-gradient(45% 100% at 50% -5%, #0000 calc(85% - 1px), var(--line) 85% calc(100% - 1px), #0000) 12.8em 75% / 1.4em 0.5em no-repeat,
/* face + eyes */
radial-gradient(closest-side circle at 35% 50%, var(--line) calc(13% - 1px), #0000 13%) 0 0 / 3em 3em,
radial-gradient(closest-side circle at 65% 50%, var(--line) calc(13% - 1px), #0000 13%) 0 0 / 3em 3em,
radial-gradient(closest-side circle, #ddd calc(90% - 1px), #0000 90%) 0 0 / 3em 3em;;
border: 0;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
color: inherit;
outline-offset: 5px;
}
.satisfaction::before {
content: "";
position: absolute;
top: 0;
left: calc(3em * (var(--val) - 1));
width: 3em;
height: 3em;
border-radius: 50%;
border: 0.1em dashed currentcolor;
box-sizing: border-box;
}
.satisfaction[style*="1"] {
animation: animationSatisfaction1 0.2s forwards;
--face:
radial-gradient(50% 100% at 50% 105%, #0000 calc(85% - 1px), #000 85% calc(100% - 1px), #0000) 0.9em 70% / 1.2em 0.5em no-repeat,
radial-gradient(90% 90% at 50% 10%, var(--satisfaction-col), #f000 var(--satisfaction-pct)) 0 0 / 3em 3em;
}
.satisfaction[style*="2"] {
animation: animationSatisfaction2 0.4s forwards;
--face:
radial-gradient(45% 75% at 50% 110%, #0000 calc(75% - 1px), #000 75% calc(100% - 1px), #0000) 1em 65% / 1em var(--satisfaction-pct) no-repeat,
radial-gradient(90% 90% at 50% 10%, var(--satisfaction-col), #f000 70%) 0 var(--satisfaction-pct) / 3em 3em;
}
.satisfaction[style*="3"] {
animation: animationSatisfaction3 0.55s forwards;
--face:
linear-gradient(var(--satisfaction-deg), #0000 33.33%, #000 0 66.66%, #0000 0) 0.9em 69% / 1.2em 0.3em no-repeat;
}
.satisfaction[style*="4"] {
animation: animationSatisfaction4 0.35s forwards;
--face:
radial-gradient(35% 70% at 50% -10%, #0000 calc(72% - 1px), #000 72% calc(100% - 1px), #0000) 0.9em 75% / 1.2em 0.35em no-repeat,
radial-gradient(farthest-side, #f004 calc(var(--satisfaction-pct) - 1px), #0000 var(--satisfaction-pct)) 0.3em 57% / 1.1em 0.6em,
radial-gradient(farthest-side, #f004 calc(var(--satisfaction-pct) - 1px), #0000 var(--satisfaction-pct)) 1.6em 57% / 1.1em 0.6em
;
}
.satisfaction[style*="5"] {
animation: animationSatisfaction5 0.25s forwards;
--face:
radial-gradient(45% 100% at 50% -5%, #0000 calc(85% - 1px), #000 85% calc(100% - 1px), #0000) 0.8em 75% / 1.4em 0.5em no-repeat,
radial-gradient(farthest-side, #f006 calc(var(--satisfaction-pct) - 1px), #0000 var(--satisfaction-pct)) 0.25em 57% / 1em 0.65em,
radial-gradient(farthest-side, #f006 calc(var(--satisfaction-pct) - 1px), #0000 var(--satisfaction-pct)) 1.75em 57% / 1em 0.65em,
radial-gradient(farthest-side circle at 50% 20%, var(--satisfaction-col), #0000 60%) 0 0% / 3em 3em
;
}
/* Thumb for Chrome and Safari */
.satisfaction::-webkit-slider-thumb {
-webkit-appearance: none; /* Override default look */
appearance: none;
width: 3em;
aspect-ratio: 1;
pointer-events: none;
mask: radial-gradient(closest-side circle, #fc0 calc(90% - 1px), #0000 90%) 0 0 / 3em 3em;
background:
/* eyes */
var(--active-eyes),
/* mouths */
var(--face),
/* base color*/
var(--base);
;
background-repeat: no-repeat;
box-shadow: none; /* Safari adds a box-shadow when using drop-shadow on iOS, remove manually */
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
/* Thumb for Firefox */
.satisfaction::-moz-range-thumb {
--bg: #fc0;
--line: #000;
-webkit-appearance: none; /* Override default look */
appearance: none;
width: 3em;
height: 3em;
pointer-events: none;
border: none;
mask: radial-gradient(closest-side circle, #fc0 calc(90% - 1px), #0000 90%) 0 0 / 3em 3em;
background:
/* eyes */
var(--active-eyes),
/* mouths */
var(--face),
/* base color*/
var(--base);
;
background-repeat: no-repeat;
box-shadow: none; /* Safari adds a box-shadow when using drop-shadow on iOS, remove manually */
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
/* if the user selected reduction motion, remove the animations */
@media (prefers-reduced-motion) {
.satisfaction {
animation-duration: 0s !important;
}
}
/* preserve styles when printing */
@media print {
.satisfaction, .satisfaction::before, .satisfaction::after {
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
}
@media (prefers-contrast: more) {
.satisfaction {
/* WIP */
}
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.