本文介绍一种基于 CSS 自定义属性与 background-clip: text 的纯前端方案,无需 SVG 或额外 DOM 元素,即可精准按百分比(如 4.27 星)为五角星图标实现颜色渐变填充,且填充区域严格限定在星形轮廓内。
本文介绍一种基于 css 自定义属性与 `background-clip: text` 的纯前端方案,无需 svg 或额外 dom 元素,即可精准按百分比(如 4.27 星)为五角星图标实现颜色渐变填充,且填充区域严格限定在星形轮廓内。
实现星形评分的部分填充,关键在于将“填充色”精确映射到星形字符(★)的视觉轮廓中,而非简单裁剪容器或覆盖背景。原始方案中使用 clip-path: polygon() 试图对 元素做几何裁剪,但存在两大根本性问题:一是 FontAwesome 图标本质是字体图标,其渲染依赖文本路径,clip-path 作用于块级容器时无法智能识别字形轮廓;二是 CSS 变量 --half-star-percentage 在 :root 中被静态声明为字符串 percentageFilled * 100%,未通过 JS 动态注入,导致无效。
✅ 推荐方案采用 CSS 自定义属性 + background-clip: text + 纯文本 ★ 字符,原理清晰、兼容性好(Chrome/Firefox/Safari 均支持)、且完全响应式:
<div class="stars-landing" id="stars-box" style="--rating: 4.27;" aria-label="Rating: 4.27 out of 5"> ★★★★★ </div>
:root {
--star-size: 24px;
--star-color: #ffd700; /* 填充色(亮金色) */
--star-background: #e0e0e0; /* 未填充背景色(浅灰) */
}
.stars-landing {
--percent: calc(var(--rating) / 5 * 100%);
font-size: var(--star-size);
font-family: "Times New Roman", Times, serif; /* 确保 ★ 渲染一致 */
line-height: 1;
letter-spacing: -3px; /* 消除星号间默认间距 */
color: var(--star-background); /* 默认显示为背景色 */
position: relative;
}
.stars-landing::before {
content: attr(data-stars, "★★★★★"); /* 兜底内容 */
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
background: linear-gradient(90deg,
var(--star-color) 0%,
var(--star-color) var(--percent),
var(--star-background) var(--percent),
var(--star-background) 100%
);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
z-index: 1;
}
? 核心要点说明:
- 使用 ::before 伪元素叠加一层与原星号完全重合的文本层,并通过 background-clip: text 将线性渐变背景“裁剪”至文字轮廓内,实现真正意义上的“星形内着色”。
- --percent 计算逻辑为 rating / 5 * 100%,完美支持任意小数(如 4.27 → 85.4%),无需手动区分 full-star/half-star 类名。
- letter-spacing: -3px 是关键微调项,避免字体渲染间隙导致填充断层;若使用 FontAwesome,建议改用 SVG 图标并配合 mask,但本方案更轻量通用。
? JS 动态更新示例:
const starsEl = document.getElementById('stars-box');
const ratingValue = 4.27;
starsEl.style.setProperty('--rating', ratingValue.toFixed(2));
// 同时可同步更新 aria-label 提升可访问性
starsEl.setAttribute('aria-label', `Rating: ${ratingValue} out of 5`);
? 注意事项:
- 必须设置 color: transparent + background-clip: text,仅靠 color 无法实现渐变填充;
- font-family 建议指定衬线字体(如 Times),确保 ★ 符号轮廓稳定;无衬线字体下 ★ 可能变形;
- 若需深色模式适配,可结合 @media (prefers-color-scheme: dark) 覆盖 --star-color 和 --star-background;
- Safari 旧版本需添加 -webkit-background-clip: text 前缀(已包含在示例中)。
该方案摒弃了复杂 DOM 操作与脆弱的几何裁剪,以声明式 CSS 驱动视觉表现,兼顾性能、可维护性与设计精度,是现代星级评分组件的理想实践。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











