必须用伪元素(::before/::after)插入分隔符,禁用HTML内联字符;当前页语义须由无链接的<li class="breadcrumb__item--current">承载,不可套在上;BEM命名须严格以breadcrumb开头,不得简化或混用。

separator 必须用伪元素,不能塞进 HTML 文本里
直接在 <li> 里写 / 或 > 是最常见错误。这类字符会参与文本流、被复制粘贴、被屏幕阅读器朗读为“斜杠”,还可能因字体加载失败变成方块。
正确做法是用 ::before 或 ::after 插入分隔符:
.breadcrumb__item:not(:last-child)::after {
content: ">";
margin: 0 8px;
color: #999;
}
-
:not(:last-child)比手动加breadcrumb__separator类更可靠,动态渲染时不会漏或错位 - 避免用
content: "/\00a0"——\00a0是不间断空格,属于可读文本,辅助技术会把它一起读出来 - 如果设计稿要求 SVG 箭头,必须内联
<svg class="breadcrumb__separator">,并显式设width/height;不能依赖父容器缩放
link 和 current 语义必须分离,不能混在同一个标签上
当前页不是链接,这是硬性语义约束。把 breadcrumb__item--current 加在 <a> 上,会导致两个问题:一是 aria-current="page" 失效(屏幕阅读器读不出“当前位置”),二是 CSS 无法精准控制样式(比如 hover 只该作用于可跳转项)。
正确结构只有一种:
立即学习“前端免费学习笔记(深入)”;
<li class="breadcrumb__item"><a href="/">首页</a></li> <li class="breadcrumb__item"><a href="/products">商品</a></li> <li class="breadcrumb__item breadcrumb__item--current">详情页</li>
-
breadcrumb__item--current必须作用于<li>,不是<a>,也不是<span> - 当前页节点里不能有
<a>,否则语义冲突,且破坏焦点顺序 - 不要用
breadcrumb__link--disabled模拟当前页 ——disabled是表单控件状态,不适用于导航
separator 的视觉归属必须和 link 对齐,不能靠 font-family 实现
用 font-family: "iconfont" 渲染分隔符,在后台系统中极不稳定:字体加载延迟或失败时,/ 会直接变为空白或方块,且无法 fallback。
替代方案只有三个,按优先级排序:
- 伪元素 + 字符(如
content: ">")—— 兼容性最好,零依赖 - 内联 SVG(带
class="breadcrumb__separator")—— 支持颜色/尺寸控制,需设宽高 - CSS
background-image(仅当需要复杂图标时)—— 需配padding-left预留空间
所有方案都绕开字体,确保分隔符在任何网络或加载条件下都能稳定呈现。
BEM 命名必须从 block 起手,不能省略或替换
写成 crumb-item 或 nav__item 看似省事,实则破坏 BEM 的作用域契约。前者脱离 breadcrumb 块,后者和通用导航组件冲突,CSS 选择器会误命中侧边栏菜单等其他区域。
关键规则就一条:
- 所有类名必须以
breadcrumb开头,严格遵循breadcrumb__item、breadcrumb__item--current这种格式 -
breadcrumb__item只能出现在<ol class="breadcrumb">的直接子<li>中,不能嵌套在breadcrumb__link内部 - 修饰符(如
--current)只能修饰 block 或 element,不能跨层,比如禁止breadcrumb__item__link--current
一旦命名脱钩,后续加暗色主题(breadcrumb--dark)或响应式断点逻辑时,样式就会失控——这不是写法问题,是作用域声明失效。


















