必须用而非,因面包屑有明确层级顺序(首页→分类→当前页),语义表达先后关系并被屏幕阅读器识别序号,而表示无序集合,易误导辅助技术;lighthouse等工具会标记写法为“语义缺失”。

面包屑导航不是靠某个 HTML 标签自动实现的,它本质是语义化链接结构,<nav></nav> + <ol></ol> + <li> 是当前最稳妥、可访问性最好的写法。
为什么不用 <ul></ul> 而用 <ol></ol>
面包屑有明确的层级顺序:首页 → 分类 → 子分类 → 当前页。这个“先后”关系不是视觉样式决定的,而是语义本身。屏幕阅读器会把 <ol></ol> 的序号读出来,有助于理解路径深度;而 <ul></ul> 暗示无序,容易让辅助技术忽略层级逻辑。
常见错误现象:<ul class="breadcrumb"></ul> 写法在 Lighthouse 或 axe 插件中会被标记为“语义缺失”。
实操建议:
- 始终用
<ol></ol>包裹面包屑项,即使你用 CSS 隐藏了默认序号(list-style: none) - 每个
<li>里放一个<a></a>(除最后一项),最后一项用<span></span>或<strong></strong>表示当前页,避免可点击错觉 - 给外层
<nav></nav>加aria-label="Breadcrumb",方便屏幕阅读器识别用途
aria-current="page" 必须加在当前页节点上
这是让辅助技术知道“你现在在哪”的关键属性。只靠 CSS 灰色/加粗无法被读屏软件感知。
使用场景:用户从列表页点进详情页后,面包屑末尾的标题必须携带该属性。
实操建议:
- 不要只写
aria-current="true"—— 必须是"page"(还可选"step"或"location",但面包屑固定用page) - 服务端渲染时,动态判断当前 URL 是否匹配最后一级路径,再注入该属性
- 前端 JS 渲染时,避免漏掉这个属性 —— 它比 class 名
active更重要
示例片段:
<nav aria-label="Breadcrumb"><ol>
<li><a href="/">首页</a></li>
<li><a href="/blog/">博客</a></li>
<li><span aria-current="page">如何写好面包屑</span></li>
</ol></nav>
CSS 样式怎么不影响语义和可访问性
视觉上常用 “/” 或 “›” 分隔,但不能用纯文本字符硬写在 HTML 里,否则屏幕阅读器会连读成“首页斜杠博客斜杠当前页”,干扰理解。
性能 / 兼容性影响:伪元素 ::before 是唯一安全方式;IE11 支持 ::before,无需降级。
实操建议:
- 分隔符必须用
::before或::after生成,且设content为符号,同时加aria-hidden="true" - 禁用
user-select: none在分隔符上,否则键盘聚焦时可能跳过整个项 - 确保焦点顺序仍是自然的
<a></a>→<a></a>→<span></span>,不要用tabindex打乱
简短示例:
ol li + li::before {
content: "/";
margin: 0 0.5em;
color: #999;
aria-hidden: true;
}
真正难的不是写出结构,而是每次新增页面时都记得补全 aria-current、不手误把 <ol></ol> 写成 <ul></ul>、以及在多语言站点里确保分隔符符号不会被翻译工具提取 —— 这些细节一旦漏掉,对依赖读屏的用户就是断路。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











