bem 中 .rating--half 比 .rating-half 更可靠,因双连字符 -- 明确标识修饰符,避免被误认为新组件,防止层级混乱、权重失控和样式覆盖难排查。

用 BEM 命名时,为什么 .rating--half 比 .rating-half 更可靠
修饰符(Modifier)必须用双连字符 -- 隔开,这是 BEM 规范里防止语义污染的关键。如果写成 .rating-half,它看起来像一个新组件,而非 .rating 的变体;后续加 .rating-full 或 .rating-empty 会模糊层级关系,导致 CSS 选择器权重失控、样式覆盖难排查。
实际开发中常见错误:把交互状态(如 hover、disabled)直接塞进元素类名,比如 .rating-item-disabled —— 这违背了 BEM “状态应由修饰符表达”的原则,正确做法是保持结构类不变,仅切换修饰符:.rating-item + .rating-item--disabled。
-
.rating是块(Block),代表整个评分组件容器 -
.rating__item是元素(Element),不可脱离.rating单独存在 -
.rating--large、.rating--readonly是修饰符,描述块的整体状态或外观变体 -
.rating__item--active、.rating__item--hovered是元素级修饰符,只影响单个星星
评分组件里,星型图标用 SVG 还是 Unicode?关键看可访问性与动态着色
Unicode 星号(★ ☆)看似简单,但无法单独控制填充色、不支持半星过渡、屏幕阅读器常读作“star”而非“3.5 out of 5”,语义缺失严重。SVG 则能精确控制每个 <path></path> 的 fill 和 opacity,也方便用 aria-valuenow 配合 role="img" 提供准确数值反馈。
实操建议优先采用内联 SVG,避免 HTTP 请求延迟,同时规避字体加载失败导致的空白问题。不要用 CSS background-image 模拟星星 —— 那会让 :hover 和 :focus 响应变得脆弱,且无法做 SVG 级别的动画(如路径描边、缩放)。
- 半星实现靠两个重叠 SVG:一个全星 + 一个遮罩层(
clipPath或mask),比用linear-gradient裁剪更稳定 - 禁用状态下,用
.rating--disabled .rating__item统一设pointer-events: none,而非给每个<svg></svg>加disabled属性 - IE11 不支持
clipPath外部引用,若需兼容,改用transform: scaleX(0.5)+overflow: hidden模拟半星(精度略低但可用)
:focus-visible 在评分组件键盘操作中为何不能只靠默认行为
浏览器对 :focus-visible 的触发逻辑很保守:只有用户明确用键盘聚焦(如 Tab)才激活,鼠标点击后不会显示焦点环。但评分组件常需支持“按方向键切换选中星数”,这时若没手动管理 tabindex 和 focus(),键盘用户根本无法进入交互流。
典型错误是给每个 .rating__item 设 tabindex="0" —— 导致 Tab 键要按 5 次才能跳过整组星星,破坏导航效率。正确做法是整组只设一个可聚焦入口(.rating),内部用 ArrowLeft/ArrowRight 事件控制选中态,并用 aria-checked 和 aria-posinset 同步语义。
- 初始渲染时,确保已选中的
.rating__item有aria-current="true",未选中的设aria-hidden="true" - 用
document.activeElement+element.focus()主动聚焦当前高亮项,让:focus-visible样式生效 - 避免在
keydown中直接修改value,先更新 DOM 状态,再触发自定义change事件供外部监听
响应式评分组件中,em 和 rem 混用容易踩的尺寸陷阱
星号大小用 rem(相对于根字号)保证整体缩放一致性,但星间距、hover 扩展区域这类“交互友好性”参数必须用 em(相对于父元素字号)。否则当父容器文字变小(如移动端 font-size: 14px),rem 单位的 padding 仍按 16px 根字号计算,导致点击热区过小,触控失败率飙升。
另一个坑是用 vw 控制最大宽度后,忘了限制最小星号尺寸 —— 小屏下 1rem = 2px 会导致 SVG 图标渲染模糊甚至消失。BEM 修饰符此时就该介入:.rating--compact 应显式重置 font-size 和图标 width/height,而不是依赖媒体查询全局覆盖。
-
.rating的font-size用rem,作为所有子元素尺寸基准 -
.rating__item的margin、padding用em,跟随当前字号弹性缩放 - 半星遮罩层的
clip-path坐标值必须用px或unitless百分比,避免被em缩放错位 - 用
@supports (aspect-ratio: 1/1)检测原生宽高比支持,降级方案用padding-bottom: 100%+position: absolute
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











