必须用而非+flex,因其提供语义化导航结构,支持屏幕阅读器读出层级顺序,天然兼容first:hidden、last:font-medium等伪类;分隔符须为独立并加sm:hidden flex-shrink-0,避免焦点错乱与折行。

直接用 <ol></ol> + Tailwind 工具类就能实现,无需 JS、不依赖路由库,语义正确且屏幕阅读器可读。
为什么必须用 <ol></ol> 而不是 <div> + <code>flex
用 <div> 模拟列表会丢失导航层级语义:键盘 Tab 焦点顺序错乱,屏幕阅读器无法识别“第 1 项 / 第 2 项 / 当前页”这样的路径逻辑。而 <code><ol></ol> 天然支持 first:hidden、last:font-medium 等伪类,还能配合 list-none 干净抹掉默认序号。
常见错误现象:
- 给
<div class="flex"> 套一堆 <code>aria-*属性试图补语义——徒劳,浏览器根本不认 - 用
::before在链接内部加/—— 小屏隐藏后焦点跳过失效,SR 读不出分隔关系
<ol></ol> 结构与分隔符的写法要点
分隔符必须是独立的 <li> 元素,和文字项同级、同父容器,不能嵌在 <a></a> 或 <span></span> 里。
正确结构示例:
<nav aria-label="面包屑导航"><ol class="flex flex-wrap items-center gap-1 sm:gap-2 list-none">
<li><a href="/">首页</a></li>
<li class="sm:hidden text-gray-400 flex-shrink-0">/</li>
<li><a href="/docs">文档</a></li>
<li class="sm:hidden text-gray-400 flex-shrink-0">/</li>
<li class="font-medium text-gray-900">配置指南</li>
</ol></nav>
关键点:
- 每个分隔符都要加
flex-shrink-0,否则窄屏下可能被挤到下一行 -
sm:hidden控制桌面显示、移动端隐藏;若想小屏改用 →,可用max-sm:before:content-['→'] max-sm:pl-1 - 所有分隔符统一用纯文本
/,后续换 SVG 图标只需改内容,不影响 flex 流
中文路径截断与防折行控制
中文无天然空格,truncate 在 flex 容器里容易失效,尤其父容器没设宽度限制时。
解决方案是显式约束中间项:
- 中间链接项统一加
max-w-[120px] truncate inline-block(强制单行+省略) - 首项(如“首页”)和末项(当前页)不加
truncate,避免误截关键信息 - 整个
<ol></ol>必须加flex-wrap,配合gap-1 sm:gap-2控制不同断点间距 - 绝对不要对整行加
whitespace-nowrap——会导致移动端整行溢出不可见
Tailwind 中容易被忽略的兼容性细节
最易踩的坑不在结构,而在渲染链末端:所有分隔符必须和内容项同级、同父容器。一旦嵌套进链接内部,语义就断裂了,first:hidden 和 last:font-medium 会完全失效,而且 flex 缩放行为不可预测。
另一个隐形雷区是颜色变量加载顺序:如果你用自定义主题色(比如 --color-secondary),确保它在 Tailwind 的 theme.extend.colors 中正确定义,且 CSS 加载时机早于组件渲染——否则某些博客页面会出现颜色不生效,只在部分断点下可见。











