In the previous article, we built a CSS-only star rating component leveraging CSS masks, border-image
, and the enhanced attr()
function. The resulting code offered adaptability for creating variations, such as heart ratings and volume controls.
This follow-up explores a more versatile approach using scroll-driven animations. Instead of the border-image
method, we'll harness the power of scroll-based animation.
Here's the same star rating component, implemented with this new technique. Due to its experimental nature, optimal viewing requires Chrome 115 (Safari and Firefox support pending).
Notice the key difference: star color dynamically reflects the selection count—a feat impossible with the border-image
method.
For a complete understanding, reviewing the first article is highly recommended, as this part builds upon its concepts and techniques.
Important Note: At the time of writing, only Chrome 115 and Edge 115 fully support the features used here. Please use one of these browsers while following along.
The application of scroll-driven animations to a static star rating component might seem counterintuitive. The MDN explanation for scroll-driven animations initially adds to the confusion:
It allows you to animate property values based on a progression along a scroll-based timeline instead of the default time-based document timeline. This means that you can animate an element by scrolling a scrollable element, rather than just by the passing of time.
However, MDN clarifies that two types of scroll-based timelines exist: scroll progress timelines and view progress timelines. We'll utilize the latter:
You progress this timeline based on the change in visibility of an element (known as the subject) inside a scroller. The visibility of the subject inside the scroller is tracked as a percentage of progress — by default, the timeline is at 0% when the subject is first visible at one edge of the scroller, and 100% when it reaches the opposite edge.
The CSS-Tricks almanac provides another helpful definition of view-timeline-name
.
The concept becomes clearer by considering the thumb element as the subject and the input element as the scroller. The thumb's movement within the input area alters its visibility, creating a percentage-based progress that we can use to style the input. Essentially, we're replicating document.querySelector("input").value
in JavaScript, but purely with CSS!
Implementation Details
Let's examine the code:
@property --val { syntax: "<number>"; inherits: true; initial-value: 0; } input[type="range"] { --min: attr(min type(<number>)); --max: attr(max type(<number>)); timeline-scope: --val; animation: --val linear both; animation-timeline: --val; animation-range: entry 100% exit 0%; overflow: hidden; } @keyframes --val { 0% { --val: var(--max) } 100% { --val: var(--min) } } input[type="range"]::thumb { view-timeline: --val inline; }</number></number></number>
This might appear complex, but a line-by-line breakdown simplifies it.
Subject and Scroller
We define the subject (the thumb) using the view-timeline
shorthand:
The
view-timeline
CSS shorthand property defines a named view progress timeline, progressed based on the visibility change of an element (the subject) within a scrollable element (scroller).view-timeline
is set on the subject.
The timeline name is --val
, and the axis is inline
(horizontal).
Next, we define the scroller (the input) with overflow: hidden
(or overflow: auto
). Crucially, don't forget overflow
on the scroller! Without it, the browser will define the scroller, potentially leading to unexpected results.
Animation
An animation modifies the --val
variable between the input's min
and max
values, using the enhanced attr()
function. This animation is linked to the view timeline using animation-timeline
. The @property
rule registers the variable for animation.
timeline-scope
is also vital. Named view timelines are typically scoped to the element and its descendants. Since the input is the thumb's parent, we broaden the scope using timeline-scope
.
The keyframe values are inverted (min
at 100%, max
at 0%) because the animation starts when the thumb is at the right (max value) and ends at the left (min value). This mirrors the behavior of a horizontally scrolling element where the subject appears from the right and disappears to the left.
Animation Range
animation-range: entry 100% exit 0%;
is crucial. By default, the animation starts when the subject enters the scroller from the right and ends when it exits from the left. Since the thumb doesn't overflow, we adjust the range so the animation starts when the thumb is fully within the scroller and ends when it begins to leave.
The repeated use of --val
refers to the animated variable, the named view timeline, and the keyframes, all sharing the same name for clarity. Using distinct names would enhance readability.
The Star Rating Component
The core work involves obtaining the input's value. The remaining code styles the component, drawing from the first article:
input[type="range"] { background: linear-gradient(90deg, hsl(calc(30 4 * var(--val)) 100% 56%) calc(var(--val) * 100% / var(--max)), #7b7b7b 0 ); } input[type="range"]::thumb { opacity: 0; }
The thumb is hidden, and a gradient colors the stars based on the --val
variable. The gradient's color also dynamically changes using hsl()
.
The complete demo (Chrome 115 recommended) showcases the functionality, including half-star support by adjusting the input's attributes.
Border-Image vs. Scroll-Driven Animations
Beyond browser compatibility, the scroll-driven animation approach surpasses the border-image
method. While border-image
is simpler, it lacks flexibility. Scroll-driven animations provide greater control, as the input value is obtained and then used for styling. This value-retrieval technique is reusable even without direct input styling.
Examples showcasing tooltips and multiple range sliders controlling different page elements demonstrate the versatility of this approach. Even a wavy range slider illustrates the extensive styling possibilities.
Conclusion
This two-part series demonstrates a minimal-code star rating component while exploring attr()
, CSS masks, and scroll-driven animations. While browser support limits immediate production use, exploring these features provides valuable insights into future CSS capabilities.
Article Series
- A CSS-Only Star Rating Component and More! (Part 1)
- A CSS-Only Star Rating Component and More! (Part 2)
The above is the detailed content of A CSS-Only Star Rating Component and More! (Part 2). For more information, please follow other related articles on the PHP Chinese website!

@keyframesandCSSTransitionsdifferincomplexity:@keyframesallowsfordetailedanimationsequences,whileCSSTransitionshandlesimplestatechanges.UseCSSTransitionsforhovereffectslikebuttoncolorchanges,and@keyframesforintricateanimationslikerotatingspinners.

I know, I know: there are a ton of content management system options available, and while I've tested several, none have really been the one, y'know? Weird pricing models, difficult customization, some even end up becoming a whole &

Linking CSS files to HTML can be achieved by using elements in part of HTML. 1) Use tags to link local CSS files. 2) Multiple CSS files can be implemented by adding multiple tags. 3) External CSS files use absolute URL links, such as. 4) Ensure the correct use of file paths and CSS file loading order, and optimize performance can use CSS preprocessor to merge files.

Choosing Flexbox or Grid depends on the layout requirements: 1) Flexbox is suitable for one-dimensional layouts, such as navigation bar; 2) Grid is suitable for two-dimensional layouts, such as magazine layouts. The two can be used in the project to improve the layout effect.

The best way to include CSS files is to use tags to introduce external CSS files in the HTML part. 1. Use tags to introduce external CSS files, such as. 2. For small adjustments, inline CSS can be used, but should be used with caution. 3. Large projects can use CSS preprocessors such as Sass or Less to import other CSS files through @import. 4. For performance, CSS files should be merged and CDN should be used, and compressed using tools such as CSSNano.

Yes,youshouldlearnbothFlexboxandGrid.1)Flexboxisidealforone-dimensional,flexiblelayoutslikenavigationmenus.2)Gridexcelsintwo-dimensional,complexdesignssuchasmagazinelayouts.3)Combiningbothenhanceslayoutflexibilityandresponsiveness,allowingforstructur

What does it look like to refactor your own code? John Rhea picks apart an old CSS animation he wrote and walks through the thought process of optimizing it.

CSSanimationsarenotinherentlyhardbutrequirepracticeandunderstandingofCSSpropertiesandtimingfunctions.1)Startwithsimpleanimationslikescalingabuttononhoverusingkeyframes.2)Useeasingfunctionslikecubic-bezierfornaturaleffects,suchasabounceanimation.3)For


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

SublimeText3 Chinese version
Chinese version, very easy to use
