导航
当前位置一律用 aria-current 表达,样式从属性上取——
视觉状态与无障碍树是同一个事实。
菜单
下拉菜单
原生 <details>,零 JS。键盘可开合;Esc 关闭和与其他菜单的状态协调并非原生保证,采用者若需要,必须明确实现。
操作
查看代码 · Source
<details class="wx-dropdown">
<summary>操作</summary>
<ul class="wx-dropdown__menu">
<li><button class="wx-dropdown__item" type="button">编辑</button></li>
<li><button class="wx-dropdown__item" type="button">复制链接</button></li>
<li><hr class="wx-dropdown__sep"></li>
<li><button class="wx-dropdown__item wx-dropdown__item--danger" type="button">删除</button></li>
</ul>
</details>标签页
需要 tabs.js 提供 roving tabindex——只有选中的标签在 tab 序列里,
这是标签页与一排链接对键盘用户的根本区别。
方向键切换,Home / End 跳到首尾。
面板用 hidden 属性隐藏,不是 class。
状态全部在 aria-selected 上。
查看代码 · Source
<div class="wx-tabs" role="tablist" aria-label="示例">
<button role="tab" type="button" id="t1" aria-controls="p1" aria-selected="true">概览</button>
<button role="tab" type="button" id="t2" aria-controls="p2" aria-selected="false">用法</button>
<button role="tab" type="button" id="t3" aria-controls="p3" aria-selected="false">无障碍</button>
</div>
<div role="tabpanel" id="p1" aria-labelledby="t1"><p>方向键切换,Home / End 跳到首尾。</p></div>
<div role="tabpanel" id="p2" aria-labelledby="t2" hidden><p>面板用 <code>hidden</code> 属性隐藏,不是 class。</p></div>
<div role="tabpanel" id="p3" aria-labelledby="t3" hidden><p>状态全部在 <code>aria-selected</code> 上。</p></div>面包屑与翻页
查看代码 · Source
<nav class="wx-crumbs" aria-label="面包屑">
<ol><li><a href="./index.html">首页</a></li><li><a href="./components.html">组件</a></li><li>导航</li></ol>
</nav>
<nav class="wx-pager" style="margin-block-start:var(--space-6)">
<a href="./c-layout.html"><span class="wx-pager__label">上一页</span>布局</a>
<a href="./c-entry.html" style="text-align:end"><span class="wx-pager__label">下一页</span>数据录入</a>
</nav>分页
下面只展示“第 2 页”的静态状态;接入时每个页码必须指向真实的离散结果页,或由应用状态明确接管。
查看代码 · Source
<nav class="wx-pagination" aria-label="分页">
<ul class="wx-pagination__list">
<li><span class="wx-pagination__link" aria-disabled="true" aria-label="上一页">←</span></li>
<li><a class="wx-pagination__link" href="#">1</a></li>
<li><a class="wx-pagination__link" href="#" aria-current="page">2</a></li>
<li><a class="wx-pagination__link" href="#">3</a></li>
<li><span class="wx-pagination__ellipsis">…</span></li>
<li><a class="wx-pagination__link" href="#">9</a></li>
<li><a class="wx-pagination__link" href="#">→</a></li>
</ul>
</nav>步骤
- 填写信息已完成
- 确认内容当前步骤
- 提交尚未开始
页内锚点
本页右侧是文档站私有的 wx-anchor 实例(宽屏可见)。它配合 wx-affix 吸顶,
由页面脚本按标题顺序和当前滚动位置更新唯一的 aria-current,避免相邻标题同时高亮。wx-anchor 本身不捆绑滚动脚本。
查看代码 · Source
<nav class="wx-nav" aria-label="作品集主导航"><a class="wx-nav__brand" href="./index.html">文心</a><ul class="wx-nav__list"><li><a class="wx-nav__link" aria-current="page" href="./pattern-detail.html">文章</a></li><li><a class="wx-nav__link" href="./brand.html">关于</a></li></ul></nav>
<div class="wx-cols wx-cols--2" style="margin-block-start:var(--space-6)"><aside class="wx-sidebar"><p class="wx-sidebar__heading">文档</p><ul class="wx-sidebar__list"><li><a class="wx-sidebar__link" aria-current="page" href="./c-navigation.html">导航</a></li><li><a class="wx-sidebar__link" href="#api">API</a></li></ul></aside><nav class="wx-anchor" aria-label="示例文章目录"><ul class="wx-anchor__list"><li><a class="wx-anchor__link" aria-current="location" href="#anchor">当前章节</a></li><li><a class="wx-anchor__link" href="#skip">跳过链接</a></li></ul></nav></div>何时使用、何时不用与 API
| 组件 | 何时使用 · 不用 | 契约(ARIA / 脚本) |
|---|---|---|
wx-nav | 站点一级导航;局部操作改用 toolbar。 | nav aria-label;当前链接用 aria-current。 |
wx-menu | 静态层级菜单;可选择命令集改用原生 select。 | ul + 可导航的 a;不可导航项用无 href 的 span aria-disabled="true"。 |
wx-dropdown | 少量二级动作;复杂可交互表单改用 popover。 | 原生 details/summary,无脚本。 |
wx-sidebar | 知识库目录;短页不制造侧栏。 | aside/nav;窄屏抽屉由 disclosure.js 同步 data-wx-disclosure-ready/data-open/aria-expanded,无 JS 仍留在文档流。 |
wx-toc | 长文页内定位;标题少于两项不显示。 | nav aria-label;可选 toc.js 更新 aria-current="location"。 |
wx-anchor / wx-affix | 页面自有目录与吸附定位;标题少于两项不显示。 | nav aria-label;wx-affix 只负责 sticky,采用者或页面脚本更新 aria-current。 |
wx-crumbs / wx-pager / wx-pagination | 层级返回、前后内容、离散分页;无限流不伪装分页。 | 外层 nav aria-label;当前页用 aria-current="page";不可用方向不是带 href 的假禁用链接。 |
wx-tabs | 同一上下文的少量面板;跨页面导航用链接。 | tablist/tab/tabpanel、aria-selected、aria-controls;需 tabs.js。 |
wx-steps | 线性流程进度;可任意跳转的导航用 tabs。 | 当前项 aria-current="step",完成项 data-complete。 |
wx-skip | 每个页面第一可聚焦元素;绝不因“页面短”删除。 | href="#main" 指向唯一 main,无脚本。 |
目录
wx-toc 是长文的页内目录,当前位置用 aria-current 标记——
不是 .is-active 类。下面这个示例加载 kit 的可选 toc.js;
本站每页右侧则是由文档站私有脚本驱动的 wx-anchor。
查看代码 · Source
<nav class="wx-toc" aria-label="示例目录">
<p class="wx-toc__heading">本页</p>
<ul class="wx-toc__list">
<li><a class="wx-toc__link" href="#toc" aria-current="location">目录</a></li>
<li><a class="wx-toc__link" href="#affix">吸附</a></li>
<li><a class="wx-toc__link" href="#skip">跳过链接</a></li>
</ul>
</nav>状态绑定到无障碍树的理由在这里最直白:aria-current 既驱动那条朱砂竖线,
也让读屏器知道读者在哪一节。一个类做不到第二件事,于是"看得见但读不到"的状态在结构上不可能出现。
高亮由 toc.js 的 IntersectionObserver 更新。
吸附
wx-affix 让一个导航容器在滚动时停靠。它是纯 CSS position: sticky,没有脚本、
没有滚动监听、没有布局抖动。
<nav class="wx-toc wx-affix" aria-label="本页目录">…</nav>它只负责停靠位置,不负责内容——所以它总是和别的东西一起用(本站是 wx-anchor wx-affix)。
吸附的东西必须能滚动:目录比视口高时要有自己的 overflow-y,
否则底部条目永远够不到。
跳过链接
wx-skip 平时不可见,获得焦点时出现在页面左上角。键盘用户按下第一个 Tab 就能跳过整个页头。
<body class="wx-page">
<a class="wx-skip" href="#main">跳到主要内容</a>
…
<main id="main">…</main>点一下页面空白处,按 Tab——本站的跳过链接会出现在左上角。 它是第一层全局底线的一部分:键盘可达不参与哲学取舍,两条轨道都必须有。