How to Build a Pure CSS Star Rating with input type="range"
This article walks through creating a fully CSS‑based star rating component using the HTML input type="range", exploring its shadow‑DOM structure, applying CSS masks, handling cross‑browser quirks, and providing complete code snippets for a flexible, lightweight solution.
Why use CSS to implement a star rating?
Star rating is a common UI need. The author originally used JavaScript, but a colleague suggested that type="range" could achieve it, sparking further exploration.
How to use type="range" for star rating
Is input type="range" just a simple element?
It is a component that contains a shadow DOM . By enabling "Show user agent shadow DOM" in Chrome's settings, you can see the hidden shadow-root and its internal DOM nodes.
Inspecting the element reveals that the range input actually contains other elements that are normally hidden.
Customizing the style of input type="range"
Using the browser's inspector you can locate the internal DOM and modify its styles.
Two pseudo‑elements are key:
::-webkit-slider-runnable-track : styles the track (the area the thumb slides on).
::-webkit-slider-thumb : styles the thumb itself (effective in WebKit/Blink browsers).
To turn the track into stars, a CSS mask is applied. The mask uses an SVG star pattern that repeats across the track.
<code>input[type="range"] {
-webkit-appearance: none; /* remove default styling */
width: 100px;
margin: 0;
outline: 0;
}
input[type="range"]::-webkit-slider-runnable-track {
background: coral; /* star color */
height: 20px;
-webkit-mask: url("data:image/svg+xml,%3Csvg width='12' height='11' viewBox='0 0 12 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6 0l1.693 3.67 4.013.476L8.74 6.89l.788 3.964L6 8.88l-3.527 1.974.788-3.964L.294 4.146l4.013-.476L6 0z' fill='%23F67600'/%3E%3C/svg%3E");
-webkit-mask-size: 20px;
-webkit-mask-repeat: repeat-x;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 0;
height: 100%;
box-shadow: 999px 0 0 999px #E8EAED; /* hide thumb */
}
</code>This pure‑CSS solution produces a star rating where the star colors change with the background.
Compatibility considerations
The approach works in browsers that support input type="range" and CSS masks (WebKit/Blink). In Firefox the mask is not supported, so a fallback using ::-moz-range-track and ::-moz-range-progress is added.
<code>input[type=range] {
-webkit-mask: url("data:image/svg+xml,%3Csvg width='12' height='11' viewBox='0 0 12 11' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6 0l1.693 3.67 4.013.476L8.74 6.89l.788 3.964L6 8.88l-3.527 1.974.788-3.964L.294 4.146l4.013-.476L6 0z' fill='%23F67600'/%3E%3C/svg%3E");
-webkit-mask-size: 20px;
-webkit-mask-repeat: repeat-x;
height: 20px;
}
input[type=range]::-moz-range-track {
background: #E8EAED;
height: inherit;
}
input[type=range]::-moz-range-progress {
background: coral;
height: inherit;
}
input[type=range]::-moz-range-thumb {
width: 0;
opacity: 0;
}
</code>Testing shows the component fails in Firefox without the Mozilla‑specific rules.
Conclusion
The pure CSS star rating using input type="range" is lightweight, flexible, and can be extended for different star counts or rating ranges. The author plans to integrate it into the open‑source LuLu UI library.
References
张老师 – https://www.zhangxinxu.com/wordpress/
js 实现评分组件 – https://sunseekers.github.io/2020/12/12/star/
同事文彬 – https://github.com/XboxYan
在线 demo type=range 实现评星功能 – https://codepen.io/qingchuang/pen/jOMmQab
::-webkit-slider-runnable-track – https://developer.mozilla.org/zh-CN/docs/Web/CSS/::-webkit-slider-runnable-track
::-webkit-slider-thumb – https://developer.mozilla.org/zh-CN/docs/Web/CSS/::-webkit-slider-thumb
CSS遮罩 CSS3 mask/masks 详细介绍 – https://www.zhangxinxu.com/wordpress/2017/11/css-css3-mask-masks/
兼容火狐浏览器,谷歌下失效 – https://codepen.io/qingchuang/pen/VwKVJYL
LuLu UI – https://github.com/yued-fe/lulu
Yuewen Frontend Team
Click follow to learn the latest frontend insights in the cultural content industry. We welcome you to join us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.