bem 中面包屑根元素应为单数 breadcrumb,因其代表独立导航控件;__item 与 __link 必须分离以解耦布局与交互样式;分隔符宜用伪元素实现;折叠逻辑由 js 控制类名,css 仅响应。

面包屑的BEM根元素该叫 breadcrumb 还是 breadcrumbs?
用单数 breadcrumb。BEM 命名中,块(block)代表一个独立、可复用的功能单元,不是数据集合的语义复数。即使它显示多个链接,它本身是一个导航控件,就像 button 不叫 buttons 一样。CSS 类名 .breadcrumb 更符合语义和 BEM 社区惯例(参考官方示例及主流 UI 库如 ATOM、Yandex Search)。
常见错误是看到 DOM 里有多个 <a></a> 就误以为该用复数,结果导致后续元素命名断裂,比如 .breadcrumbs__item 看似合理,但块名本身已失焦——一旦组件需要嵌套(如侧边栏里再塞一个面包屑),.sidebar__breadcrumbs 就变成“块里的块”,违背 BEM 块应自治的原则。
breadcrumb__item 里要不要再加 breadcrumb__link?
要,且必须分离。因为 __item 是容器,__link 是其内部可交互元素——二者职责不同:容器负责布局间距、分隔符位置;链接负责颜色、hover、focus 状态、访问性属性(如 aria-current)。混在一起会导致样式耦合,比如想给当前项换背景色,却不得不覆盖链接的文本色。
-
breadcrumb__item应设display: flex或仅含内边距,不设颜色/文字样式 -
breadcrumb__link承担所有文本、伪类、焦点环样式 - 当前项用
breadcrumb__item--current > .breadcrumb__link单独控制,而非直接在__item上写背景色 - 若某环节是纯文本(如最后的页面标题),可用
<span class="breadcrumb__link breadcrumb__link--current"></span>,保持结构一致性
分隔符(slash / arrow)该作为元素还是修饰符?
作为伪元素或绝对定位的修饰符更稳妥,别单独建 __separator 元素。理由很实际:分隔符不是语义节点,没有内容、不参与 tab 键序、不该被屏幕阅读器读出;硬塞一个 <span class="breadcrumb__separator">/</span> 会污染 DOM、增加无障碍负担,还容易在响应式断行时错位。
推荐做法是:
- 在
breadcrumb__item:not(:last-child)::after里用content: "/";或 SVG 背景 - 用
breadcrumb--arrow这类修饰符统一切换分隔符类型(→、›、chevron-right icon) - 若需支持 RTL,用
direction: rtl配合transform: scaleX(-1)比重写 HTML 更可靠 - 避免用
margin-left给分隔符留空——它属于视觉装饰,应脱离文档流
如何处理长文本截断与响应式折叠?
不要在 breadcrumb__link 上直接写 text-overflow: ellipsis。面包屑的折叠逻辑依赖上下文:是整条裁剪(如移动端只留首尾),还是逐项隐藏(保留首页 + 当前页,中间用 …)?这属于行为层,应由 JS 控制类名(如 breadcrumb--collapsed),CSS 只响应。
实操建议:
- 默认状态保持完整渲染,确保 SEO 和无障碍可读性
- 折叠逻辑交由 JS 判断容器宽度与子项总宽,动态添加
breadcrumb__item--hidden类 - CSS 中用
.breadcrumb--collapsed .breadcrumb__item--hidden { display: none; },而非依赖white-space: nowrap强撑 - 如果用 CSS 容器查询(
@container),注意目前 Safari 支持需加contain: layout style到.breadcrumb,否则查询无效
最易被忽略的是:分隔符在折叠后仍可能残留(比如隐藏了中间项,但前一项的 ::after 还在)。得配合 JS 清除对应伪元素,或改用更健壮的“仅对非末尾可见项渲染分隔符”的逻辑。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











