语义正确优先选 <ol>,因其准确表达面包屑从根到当前页的不可互换层级序列;外层用 <nav aria-label="Breadcrumb"> 包裹,内部 <li> 中当前页须用 <span aria-current="page"> 标注。

面包屑导航用 <nav> 还是 <ol>?
语义正确优先选 <ol>,不是因为“有顺序”,而是因为面包屑本质是层级路径的线性序列——从根到当前页,每级不可互换。<nav> 适合主导航、侧边栏等跳转集合,放面包屑反而弱化了结构含义。W3C 示例和主流 CMS(如 WordPress 的 Yoast SEO)默认都用 <ol>。
实操建议:
- 外层用
<nav aria-label="Breadcrumb">包裹,提供辅助技术可读性 - 内部用
<ol>,每个<li>放一个链接或当前页(当前页不用<a>) - 避免套用
<ul>或<div>,否则屏幕阅读器可能读作“列表项,共 N 项”,但丢失“第1项→第2项→第N项”的路径感
aria-current="page" 必须加在当前页节点上
不加这个属性,视障用户无法区分“这是终点”还是“又一个可点击的中间节点”。很多开发者只写 HTML 结构,漏掉这个 ARIA 标记,导致导航逻辑断裂。
常见错误现象:
立即学习“前端免费学习笔记(深入)”;
- 屏幕阅读器把当前页读成“首页 / 产品 / 详情”,全部带“链接”提示音
- 键盘 Tab 焦点仍能落到当前页文字上(因它被误当
<a>)
正确写法示例:
<nav aria-label="Breadcrumb">
<ol>
<li><a href="/">首页</a></li>
<li><a href="/products">产品</a></li>
<li><span aria-current="page">无线耳机</span></li>
</ol>
</nav>
CSS 布局:用 display: flex 而非浮动或 inline-block
旧式写法用 float: left 或 display: inline-block 加负 margin 拼分隔符,容易塌陷、换行错乱,且响应式下难以控制间距一致性。
现代推荐方案:
- 给
<ol>设display: flex; flex-wrap: wrap; - 每个
<li>设margin-right: 0.75rem;,再用::after伪元素在非末项后加/ - 当前页节点(
aria-current="page")加font-weight: bold;或color: #333;视觉强化 - 移动端可设
flex-direction: column配合媒体查询,避免过长折行
动态生成时注意 URL 和文本的同步更新
服务端渲染(如 PHP/Node.js)或前端 JS(React/Vue)生成面包屑时,最容易出问题的是路径与文案不一致。例如 URL 是 /blog/react-props,但显示为“技术文章 > React 入门”,中间缺了一级“Props 概念”。
关键检查点:
- 每级
<a href>的路径必须真实可访问,不能是占位符(如#或javascript:void(0)) - 当前页节点的文本必须与页面
<h1>或<title>严格一致,否则 SEO 和可访问性双输 - 若使用 JavaScript 动态注入,确保 DOM 更新后触发
aria-live区域通知(尤其单页应用)
层级深、路径含参数或国际化站点要格外小心——比如 /en/products?id=123 和 /zh/产品?id=123 必须各自维护对应语言的面包屑文案,不能靠 URL 截取硬翻译。










