用--fill-ratio控制星星填充比例,通过mask+linear-gradient实现平滑半星过渡,数值映射为0–5并经CSS计算裁切,解耦颜色与填充,配合防抖、边界校验和移动端适配确保高性能与兼容性。

用 --fill-ratio 控制星星填充比例,而不是写死颜色或遮罩
直接用 CSS 变量控制填充比例,核心是把“点亮几颗星”转化为一个 0–5 的数值,并映射为百分比。不能靠 JS 拼 class 或改内联 style 去切换预设类(比如 .star-3),那样维护成本高、无法做过渡动画。真正该做的,是让每颗星的 ::before 或 mask 根据 --fill-ratio 动态裁切。
关键点在于:变量值本身不决定颜色,只决定“填到哪”,颜色由 color 或 background-color 单独控制,解耦更灵活。
-
--fill-ratio值建议设为小数(如2.7),方便后续计算百分比和半星处理 - 每颗星的显示逻辑 =
当前星序号 ≤ floor(--fill-ratio)→ 全亮;当前星序号 === ceil(--fill-ratio) 且 --fill-ratio 不是整数→ 半亮;否则空 - 避免用
clip-path: polygon()做半星——兼容性差、缩放易错位;推荐用线性渐变 +background-clip: text或mask配合linear-gradient
用 mask + linear-gradient 实现平滑半星过渡
比 clip-path 更稳,也比两个重叠元素(全星+半星图层)更轻量。原理是:用 mask 把一颗星的 SVG 或伪元素“从左往右”逐步显出,显出宽度由 --fill-ratio 决定。
示例中,假设单颗星宽 24px,5 颗星总宽 120px,则填充宽度 = calc(var(--fill-ratio) * 24px)。mask 图像用 linear-gradient(to right, black var(--mask-width), transparent var(--mask-width)),再通过 --mask-width 绑定计算值。
- 必须给容器设
mask-type: luminance(如果 mask 是灰度图)或确保 mask 图像是纯黑/透明 - Firefox 对
mask的 CSS 变量支持较晚(v110+),若需兼容旧版,可降级为background+background-size水平拉伸 - 动画需加在
--fill-ratio上,而非--mask-width,否则无法触发 transition(CSS 变量本身不可直接动画,但可用于calc()中被动画属性间接驱动)
JS 更新 --fill-ratio 时注意防抖和边界处理
用户鼠标划过评分组件时,频繁触发 mousemove 会导致大量 style.setProperty('--fill-ratio', ...) 调用,可能卡顿。不是所有场景都需要实时响应——人眼分辨不出毫秒级变化,只需保证“停稳后立刻生效”。
- 用
requestAnimationFrame批量合并更新,避免 layout thrashing - 输入值必须 clamp 到
[0, 5]区间,尤其防止负数或超 5 导致 mask 错位或溢出 - 半星判定别用
Math.round()——它会把 2.5 变成 3,导致“刚过半就跳一整颗”,应改用Math.floor(value) + (value % 1 > 0 ? 0.5 : 0)或直接交由 CSS 计算 - 不要在 JS 里算好“第几颗星要半亮”,交给 CSS 的
calc()和clamp()更可靠(例如:mask-position: calc((var(--fill-ratio) - var(--star-index)) * 100%) 0)
移动端点击不准?补上 touch-action: none 和 cursor 适配
手指划过时,浏览器可能触发默认滚动或缩放,导致 touchmove 事件丢失;同时,cursor: pointer 在 iOS 上无效,用户看不出可交互。
- 评分容器加
touch-action: none,禁用原生手势干扰 - 伪元素星星加
cursor: default(避免 Safari 自动加手型导致文字选中异常) - 真机测试时,检查
pointer-events: none是否误加在 mask 层上——它会让底层事件穿透,导致点击无响应 - 如果用了 SVG
引用符号,确保pointer-events: auto设在实例上,而非定义里
半星边缘的抗锯齿、不同缩放比例下 mask 偏移、以及 Safari 对 mask 动画的渲染延迟——这些细节不会报错,但会让效果看起来“卡”或“毛边”,得靠实际设备反复调 mask-size 和 mask-position 的小数精度。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











