最可靠方式是用5个同name的radio配合label实现星级评分,原生支持、无障碍友好、无需js;字符★轻量兼容好但缩放模糊,svg灵活可着色;meter/progress仅适用于只读展示,不可交互。

用 <input type="radio"> 实现可交互星级评分
纯 HTML 实现星级评分,最可靠的方式是用一组带 name 的 <input type="radio"> 配合 <label></label>,靠 CSS 控制视觉反馈。浏览器原生支持、无障碍友好、无需 JS 就能提交值。
常见错误是直接用 <div> + 点击事件模拟,结果表单不提交、键盘无法操作、屏幕阅读器读不出当前选中值。
<ul>
<li>5 个 <code><input type="radio"> 共享同一个 name(如 name="rating"),value 依次为 1 到 5
<input> 后紧跟一个 <label></label>,用 for 或嵌套方式绑定(推荐嵌套,更健壮):checked + label 和兄弟选择器控制星星颜色,避免依赖 JS 状态<input>(position: absolute; opacity: 0),用 <label></label> 承载图标或文字CSS 星星图标用 ★ 字符还是 SVG?
字符 ★ 和 ☆ 最轻量,兼容性好(IE9+),但缩放易模糊、颜色控制受限;SVG 更灵活,可精确着色、响应式缩放,但需额外代码或内联定义。
如果只支持现代浏览器且需要深色模式适配或动画,选 SVG;如果追求极简、要塞进邮件模板或兼容老旧系统,用字符更稳妥。
- 字符方案:直接写
<label>★</label>,用color控制亮星,opacity或color: #ccc控制空星 - SVG 方案:每个星星用
<svg><path></path></svg>,通过fill属性切换,配合:checked ~ label svg选择器 - 注意:字符在 Windows 上某些字体下显示偏小,建议加
font-size和line-height对齐
<meter></meter> 或 <progress></progress> 能不能当星级展示用?
不能。这两个标签语义是「已达成进度」或「任务完成比例」,不是「用户主观评分」。<meter></meter> 的 min/max 表示标尺范围,但不支持点击交互,也无法表达离散的 1–5 分含义。
用它们做星级展示,会误导辅助技术、破坏表单语义、且无法被用户修改——本质上是把“展示”和“输入”混为一谈。
- 适合场景:
<meter value="4" min="1" max="5"></meter>仅用于只读展示(比如商品详情页已有评分) - 不适合场景:任何需要用户点选、提交、校验的评分表单
- 替代方案:只读时用
<span class="stars">★★★★☆</span>+ ARIAaria-label="4 out of 5 stars"
移动端点击区域太小,怎么让星星更好点?
默认字符或 SVG 星星尺寸小,手指点不准。核心不是放大图标,而是扩大可点击区域——用 <label></label> 的 padding 或伪元素撑开热区,同时保持视觉紧凑。
- 给
label设置display: inline-block+padding: 8px,比单纯调大font-size更有效 - 避免用
transform: scale()放大,会导致点击坐标偏移,尤其在 iOS Safari 中 - 在触摸设备上,确保相邻星星之间有至少
4px间隙,防止误触 - 测试真机:模拟器容易误判,务必在 iPhone / Android 实机上验证点击响应是否跟手
tabindex 和键盘导航支持——即使用了 radio,若没给 label 设置合适的 display 和 cursor,键盘用户按 Tab 进入后可能看不到焦点框,或者按空格无法选中。











