普通视图

发现新文章,点击刷新页面。
昨天 — 2026年1月31日首页

构建无障碍组件之Breadcrumb Pattern

作者 anOnion
2026年1月31日 16:32

Breadcrumb Pattern 详解:构建无障碍面包屑导航

面包屑导航是 Web 页面中不可或缺的导航组件,它以层级链接的形式展示当前页面在网站结构中的位置,帮助用户快速了解自己所处的位置并轻松返回上级页面。根据 W3C WAI-ARIA Breadcrumb Pattern 规范,正确实现的面包屑导航不仅要提供清晰的层级导航路径,更要确保所有用户都能顺利使用,包括依赖屏幕阅读器等辅助技术的用户。本文将深入探讨 Breadcrumb Pattern 的核心概念、实现要点以及最佳实践。

一、面包屑导航的定义与核心功能

面包屑导航(Breadcrumb Trail)是由一系列指向父级页面的链接组成的导航路径,按照层级顺序展示当前页面在网站架构中的位置。它的主要功能是帮助用户了解自己在网站中的位置,并在需要时快速返回上级页面。面包屑导航通常水平放置在页面主体内容之前,为用户提供清晰的导航参考。

在实际应用中,面包屑导航广泛应用于内容层级较深的网站,例如电商平台的产品分类页、博客文章的分类归档页、企业官网的产品介绍页等。一个设计良好的面包屑导航能够显著提升用户体验,降低用户的迷失感,同时也有利于搜索引擎更好地理解网站的结构层次。

二、键盘交互规范

面包屑导航的键盘交互具有特殊性。由于面包屑导航仅由静态链接组成,用户不需要进行任何特殊的键盘操作来与之交互。链接本身已经支持标准的键盘导航行为,用户可以通过 Tab 键在各个链接之间切换,通过 Enter 键激活链接进行页面跳转。这种标准的行为已经满足了键盘可访问性的要求,无需额外的键盘事件处理。

因此,Breadcrumb Pattern 规范明确指出,面包屑导航不需要特殊的键盘交互支持。开发者只需要确保链接元素是标准的 HTML 元素,即可获得完整的键盘可访问性支持。这一特点使得面包屑导航的实现相对简单,重点应放在正确的语义标记和 ARIA 属性使用上。

三、WAI-ARIA 角色、状态和属性

正确使用 WAI-ARIA 属性是构建无障碍面包屑导航的技术基础。虽然面包屑导航不涉及复杂的交互逻辑,但正确的语义标记对于屏幕阅读器用户理解导航结构至关重要。

3.1 导航容器标记

面包屑导航必须放置在导航地标区域(Navigation Landmark)内。这可以通过使用 nav 元素或为其他元素添加 role="navigation" 来实现。导航地标区域需要通过 aria-labelaria-labelledby 进行标记,以便屏幕阅读器向用户描述这个导航区域的用途。

示例:使用 nav 元素包裹面包屑导航:

<nav aria-label="面包屑导航">
  <ol>
    <li><a href="/">首页</a></li>
    <li><a href="/products/">产品</a></li>
    <li><a href="/products/electronics/">电子产品</a></li>
    <li aria-current="page">笔记本电脑</li>
  </ol>
</nav>

示例:使用 role 属性定义导航地标:

<div
  role="navigation"
  aria-label="面包屑导航">
  <ul>
    <li><a href="/">首页</a></li>
    <li><a href="/blog/">博客</a></li>
    <li aria-current="page">2025 年技术趋势</li>
  </ul>
</div>

3.2 当前页面状态标记

面包屑导航中的当前页面链接需要使用 aria-current 属性来标识。aria-current="page" 明确告诉辅助技术当前元素代表的是用户正在浏览的页面。这一属性对于屏幕阅读器用户理解面包屑导航的结构非常重要,使他们能够区分可导航的父级页面和当前所在页面。

值得注意的是,如果代表当前页面的元素不是链接(例如使用 span 或其他元素呈现),那么 aria-current 属性是可选的。但为了保持一致性,建议始终为当前页面元素添加 aria-current="page"。

示例:当前页面为链接时的标记:

<nav aria-label="面包屑导航">
  <ol>
    <li><a href="/">首页</a></li>
    <li><a href="/docs/">文档</a></li>
    <li><a href="/docs/guides/">指南</a></li>
    <li>
      <a
        href="/docs/guides/getting-started/"
        aria-current="page"
        >快速入门</a
      >
    </li>
  </ol>
</nav>

示例:当前页面为非链接元素时的标记:

<nav aria-label="面包屑导航">
  <ol>
    <li><a href="/">首页</a></li>
    <li><a href="/shop/">商店</a></li>
    <li><a href="/shop/clothing/">服装</a></li>
    <li aria-current="page">春季新品</li>
  </ol>
</nav>

四、完整示例

以下是使用不同方式实现面包屑导航的完整示例,展示了标准的 HTML 结构、ARIA 属性应用以及样式设计:

4.1 基础面包屑导航实现

<nav aria-label="面包屑导航">
  <ol class="breadcrumb">
    <li><a href="/">首页</a></li>
    <li><a href="/products/">所有产品</a></li>
    <li><a href="/products/electronics/">电子产品</a></li>
    <li aria-current="page">智能手表</li>
  </ol>
</nav>

4.2 带分隔符的面包屑导航

<nav
  aria-label="面包屑导航"
  class="breadcrumb-nav">
  <ol class="breadcrumb-list">
    <li class="breadcrumb-item">
      <a
        href="/"
        class="breadcrumb-link"
        >首页</a
      >
    </li>
    <li
      class="breadcrumb-separator"
      aria-hidden="true">
      /
    </li>
    <li class="breadcrumb-item">
      <a
        href="/categories/"
        class="breadcrumb-link"
        >分类</a
      >
    </li>
    <li
      class="breadcrumb-separator"
      aria-hidden="true">
      /
    </li>
    <li class="breadcrumb-item">
      <a
        href="/categories/books/"
        class="breadcrumb-link"
        >图书</a
      >
    </li>
    <li
      class="breadcrumb-separator"
      aria-hidden="true">
      /
    </li>
    <li
      class="breadcrumb-item"
      aria-current="page">
      <span class="breadcrumb-current">编程指南</span>
    </li>
  </ol>
</nav>

4.3 电商网站产品页面包屑导航

<nav
  aria-label="商品位置"
  class="product-breadcrumb">
  <ol>
    <li><a href="https://www.example.com/">首页</a></li>
    <li><a href="https://www.example.com/electronics/">家用电器</a></li>
    <li><a href="https://www.example.com/electronics/kitchen/">厨房电器</a></li>
    <li>
      <a href="https://www.example.com/electronics/kitchen/coffee/">咖啡机</a>
    </li>
    <li aria-current="page">全自动咖啡机 X2000</li>
  </ol>
</nav>

五、最佳实践

5.1 语义化 HTML 结构

面包屑导航应使用语义化的 HTML 元素构建。使用 nav 元素定义导航区域,使用 ol 或 ul 元素创建有序或无序列表,使用 li 元素包含各个导航项。这种结构不仅对搜索引擎友好,也便于屏幕阅读器向用户传达导航的层级关系。

在列表的选择上,ol 元素更适合面包屑导航,因为它能够传达各个项之间的顺序关系。但如果网站没有强制的层级顺序要求,ul 元素同样可以接受。无论选择哪种列表元素,都要确保列表项之间的逻辑顺序与面包屑导航的层级结构保持一致。

<!-- 推荐做法:使用语义化元素 -->
<nav aria-label="面包屑导航">
  <ol>
    <li><a href="/">首页</a></li>
    <li><a href="/docs/">文档</a></li>
    <li aria-current="page">当前页面</li>
  </ol>
</nav>

5.2 正确使用 ARIA 属性

面包屑导航的 ARIA 属性使用相对简单,但有几个关键点需要注意。首先,导航容器必须使用 aria-labelaria-labelledby 进行标记,以便用户了解这个导航区域的用途。其次,当前页面项必须使用 aria-current="page" 进行标记。最后,确保分隔符元素使用 aria-hidden="true",以避免辅助技术用户听到不必要的标点符号朗读。

<!-- ARIA 属性使用规范 -->
<nav aria-label="面包屑导航">
  <ol>
    <li><a href="/">首页</a></li>
    <li aria-hidden="true">/</li>
    <li><a href="/blog/">博客</a></li>
    <li aria-hidden="true">/</li>
    <li aria-current="page">文章标题</li>
  </ol>
</nav>

5.3 响应式设计考虑

面包屑导航在移动设备上可能面临空间受限的挑战。对于层级较深的导航,可以考虑以下策略:一是使用省略号隐藏中间层级,只保留首页和最后几级;二是允许用户展开查看完整路径;三是将面包屑导航改为垂直布局。无论采用哪种策略,都要确保用户能够访问完整的导航信息。

/* 响应式面包屑导航 */
@media (max-width: 768px) {
  .breadcrumb-list {
    flex-direction: column;
    gap: 4px;
  }

  .breadcrumb-separator {
    transform: rotate(90deg);
  }
}

六、面包屑导航与主导航的区别

面包屑导航和主导航栏虽然都是网站导航的重要组成部分,但它们服务于不同的目的,理解这种区别对于正确使用这两种导航组件至关重要。

面包屑导航的主要作用是展示用户在网站层级结构中的当前位置,它反映的是网站的逻辑结构,而非用户的浏览历史。面包屑导航通常只出现在层级较深的页面中,帮助用户理解当前位置与网站整体结构的关系。相比之下,主导航栏提供的是网站的整体架构概览,允许用户直接跳转到任何主要版块,而不考虑当前的层级位置。

从实现角度来看,面包屑导航强调的是层级关系,因此通常使用有序列表(ol)来体现这种顺序性。而主导航栏更强调功能分区的划分,可能使用无序列表(ul)或更复杂的布局结构。两者在 ARIA 属性使用上也不同:面包屑导航需要明确标记当前页面(aria-current="page"),而主导航栏通常不需要这种标记。

七、总结

构建无障碍的面包屑导航需要关注语义化结构、ARIA 属性应用和视觉样式三个层面的细节。从语义化角度,应使用 nav 元素定义导航区域,使用 ol 或 ul 元素创建列表结构。从 ARIA 属性角度,需要使用 aria-label 为导航区域提供标签,使用 aria-current="page" 标记当前页面。从视觉样式角度,应确保链接易于识别,分隔符清晰,当前页面状态明确。

WAI-ARIA Breadcrumb Pattern 为我们提供了清晰的指导方针,遵循这些规范能够帮助我们创建更加包容和易用的 Web 应用。每一个正确实现的面包屑导航组件,都是提升用户体验和网站可访问性的重要一步。

昨天以前首页

HTML代码规范

作者 hypnos_xy
2026年1月30日 11:39

HTML代码规范

缩进

建议缩进4个字符,在现代前端工程化,缩进4个字符比2字符更好的可读性。也不影响最终的结果

DOCTYPE 声明

统一使用HTML5声明<!DOCTYPE html>

meta 标签

  • 编码格式
<meta charset="utf-8"/>
  • SEO优化
<!-- 网页标题 -->
<title>网页标题</title>
<!-- 页面关键词 -->
<meta name ="keywords" content =""/>
<!-- 页面描述 -->
<meta name ="description" content =""/>
<!-- 网页作者 -->
<meta name ="author" content =""/>
  • 优先使用 IE 最新版本和 Chrome
<meta http-equiv="X-UA-Compatible" content="IE = edge,chrome = 1"/>
  • 为移动设备添加视口
<!-- device-width 是指这个设备最理想的 viewport 宽度 -->
<!-- initial-scale=1.0 是指初始化的时候缩放大小是1,也就是不缩放 -->
<!-- user-scalable=no 是指禁止用户进行缩放 yes 允许缩放-->
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
  • 禁止自动识别页面中有可能是电话格式的数字
<meta name="format-detection" content="telephone=no"/>

pc端建议

<title>网页标题</title>
<meta charset="utf-8"/>
<meta name="keywords" content="your keywords"/>
<meta name="description" content="your description"/>
<meta name="author" content="author,email address"/>
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"/>

移动端建议

<title>网页标题</title>
<meta charset="utf-8"/>
<meta name="keywords" content="your keywords"/>
<meta name="description" content="your description"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<meta name="format-detection" content="telephone=no"/>

标签

  • 所有标签都统一使用小写字母
  • 自闭合标签:写法<br/>后面的/不要省略,常用的自闭合标签:
<br/>
<img/>
<input/>
<link/>
<meta/>
<base/>
<source/>
  • 非自闭合标签必须有结束标签,且不要省略:
<html></html>
<body></body>
<head></head>
<script></script>
<style></style>
<iframe></iframe>
<noscript></noscript>
<title></title>
<!-- 普通标签 -->
<h1></h1>
<p></p>
<ul></ul>
<ol></ol>
<li></li>
<option></option>
<div></div>
<span></span>
<a></a>
<form></form>
<label></label>
<button></button>
<textarea></textarea>
<select></select>
<canvas></canvas>
<audio></audio>
<video></video>
<!-- 语义化标签 -->
<header></header>
<footer></footer>
<nav></nav>
<menu></menu>
<main></main>
<article></article>
<section></section>
<aside></aside>
<figure></figure>
<figcatption></figcaption>
<time></time>
<address></address>
  • 尽量减少标签数量:如果设计到div装饰的小物件,尽量使用伪元素实现,而不是先建立一个元素实现
  • vue组件自定义标签: 如果设计到多个单词便签不要使用驼峰法,而是使用-分割。且需要闭合标签
  • 对于<span><a>、等行内元素不要在嵌套其他块级元素。
  • 块元素不要和行内元素并列

转移字符

  1. &nbsp;空格
  2. &lt;小于
  3. &gt;大于
  4. &amp;
  5. &quot;引号

元素属性

  • 元素属性值使用双引号语法
  • 自定义数据属性data-*,使用小写字符,避免使用特殊字符,多单词使用-分割

js 使用

// 获取属性data-user-id="123"
let userId = userDiv.dataset.userId
userId = userDiv.getAttribute('data-user-id');
// 修改
userDiv.dataset.userId = "456";
userDiv.setAttribute('data-user-id', '789');
// 删除属性
delete userDiv.dataset.userRole;
userDiv.removeAttribute('data-user-id');
//访问所有data
const allData = element.dataset; // 返回一个 DOMStringMap 对象

css 使用

[data-role="admin"] {
  background-color: #ffebee;
}
.tooltip::before {
  content: attr(data-tooltip);
  /* 其他样式 */
}

其他规范

  1. img必须(尽量)要使用alt属性
  2. 多个表单组合应该放入form表单内
  3. html 注释必须要单独一行,不能和任何标签同行
<!-- Comment Text -->
<div>...</div>
  1. 单行字数限制120字符比较合适
  2. 多属性建议分行写(属性超过3个建议分行)
<input type="text"
       class="form-control"
       id="exampleInputEmail1"
       placeholder="Enter email"
       data-attribute1="value1"
       data-attribute2="value2"/>
❌
❌