tooltip块名必须为小写连字符形式tooltip,不加前缀、不用pascalcase;方向修饰符仅用--top/--right/--bottom/--left,每个须同时控制容器定位与.tooltip__arrow的伪元素箭头样式,箭头必须作为独立元素且统一border-width,无箭头用--no-arrow整体控制。

tooltip 块名必须扁平,不加前缀也不用 PascalCase
项目里常见错误是写成 ui-tooltip 或 Tooltip,这会破坏 BEM 的语义一致性。BEM 要求块名直接表达组件意图,tooltip 就是它本来的名字——不是“UI 工具提示”,也不是“弹窗提示”。只有当项目存在多个独立 UI 系统(比如 legacy 和新设计系统共存),且需要 CSS 作用域隔离时,才考虑加前缀,如 legacy-tooltip。
更隐蔽的问题是拼写不统一:tool-tip、toolTip、tooltip 混用,会导致 JS 切换 class 时漏匹配、CSS 规则失效。所有地方必须严格使用小写连字符形式 tooltip。
方向修饰符只用 --top/--right/--bottom/--left,且必须同时控制容器和箭头
写 tooltip--up 或 tooltip--nort 是无效的——前者语义模糊(“up”指位置?还是箭头朝向?),后者拼写错误,浏览器不会报错但 JS 无法识别。BEM 修饰符要能被程序逻辑直接映射,所以只接受四个标准值。
每个修饰符必须承担双重职责:
-
tooltip--top:容器设bottom: 100%+transform: translateY(-8px),箭头用::before设border-bottom: 6px solid currentColor+bottom: -6px -
tooltip--right:容器设left: 100%+transform: translateX(8px),箭头用border-left: 6px solid currentColor+left: -6px - 禁止把定位写死成
top: -120px这类绝对值——父容器一旦有transform或overflow: hidden,就会偏移失效
箭头必须作为独立 Element(.tooltip__arrow),不能塞进 .tooltip__content
把箭头样式直接写在 .tooltip__content::after 看似省事,但一旦要换颜色、改大小或加描边,就得动内容区域的 CSS,违反“职责分离”。BEM 要求结构清晰可复用,所以必须抽成 .tooltip__arrow 元素。
.tooltip__arrow 的关键约束:
- 必须设
content: "",否则伪元素不渲染 - 依赖
.tooltip设position: relative,否则absolute定位会脱出上下文 - 三角尺寸靠
border-width控制,所有方向必须统一值(如6px),否则和气泡的border-radius: 6px对不齐 - 为抗锯齿,需双伪元素:外层
::before画描边色,内层::after画填充色,border-width内层比外层小1px
无箭头模式用 --no-arrow,不操作 __arrow 子元素
有人写 .tooltip__arrow--hidden 或 .tooltip__arrow[hidden],这是反模式。箭头不是独立状态,而是 tooltip 整体方向状态的一部分。加 --no-arrow 修饰符后,应直接隐藏整个 ::before 和 ::after,而不是给子元素加 class。
正确做法是:
- HTML 中仍保留
<span class="tooltip__arrow"></span>结构(保持 DOM 稳定) - CSS 中写
.tooltip--no-arrow .tooltip__arrow::before, .tooltip--no-arrow .tooltip__arrow::after { display: none; } - JS 切换时只操作
.tooltip的 class,不碰.tooltip__arrow
真实场景中容易忽略的是滚动容器和缩放适配——BEM 命名本身不解决这些问题,但命名方式决定了你能否在 JS 层干净地响应 scroll 或 resize 事件来动态切换 --top/--bottom;如果方向逻辑散落在多个 class 里,维护成本会指数级上升。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











