本文详解 star rating 组件中“点击第 n 颗星却从右侧开始填充”的根本原因,并提供 css 与 html 结构协同修正方案,确保点击左侧星星时,左侧连续 n 颗星正确高亮。
星级评分系统在前端开发中十分常见,但一个容易被忽视的细节是:视觉顺序(左→右)与 DOM 顺序、CSS 排列逻辑必须保持一致。你当前的问题——点击第 4 颗星却高亮最右侧的 4 颗星——并非 JavaScript 逻辑错误,而是由 CSS 中 flex-direction: row-reverse(虽未显式写出,但实际隐含或已被误设)与相邻选择器 ~ 的工作原理共同导致的。
关键在于:你的 CSS 使用了 input:checked ~ label::before 这一选择器。它只会匹配 已选中单选框之后的所有 label(即 DOM 中位于该 元素后面的
这意味着:当 #star4 被选中时,#star4 ~ label 只会匹配 #star5 对应的 label(即最后一个),而不会影响 #star1–#star3 对应的 label —— 因为它们在 DOM 中位于 #star4 之前,不满足 ~(后续兄弟)选择器条件。
因此,标准解法不是修改 JS,而是反转容器的视觉流向,同时保持 DOM 顺序不变:将 .rating 的 flex-direction 设为 row-reverse,并同步反转 HTML 中 input + label 的排列顺序(让 star5 在前,star1 在后),从而让 :checked ~ label 能自然覆盖左侧所有星星。
✅ 正确做法如下: