先判断问题出现在哪里
如果你的网站只能用鼠标点击,或者只能用眼睛看,那么你将失去全球 15% 的残障用户(视障、运动障碍)。更严重的是,在欧美市场,不符合无障碍标准的网站面临着很高昂的法律诉讼风险(如 ADA 诉讼)。
核心逻辑是:机器可读(Machine Readable)与键盘可达(Keyboard Accessible)。
Shopify 官方 Theme Store 对可访问性(Accessibility, 简称 a11y)有着很严苛的审核标准。你必须通过语义化 HTML、ARIA 标签和焦点管理,让屏幕阅读器(Screen Readers)能“读”出网页内容,让只能使用键盘(Tab 键)的用户顺畅地完成购物流程。
实战步骤
步骤 1:语义化 HTML 与图片 Alt 属性
操作路径:检查所有模板和 Section 的 HTML 结构
-
标题层级:一个页面只能有一个
<h1>(通常是产品标题或集合标题)。后续必须严格按照<h2>,<h3>的顺序嵌套,绝对不能为了字体大一点就直接跳级使用<h4>。 -
按钮 vs 链接:如果点击后是跳转页面,使用
<a href="...">。如果点击后是触发动作(如加购、打开弹窗),必须使用<button type="button">。 -
图片 Alt:所有的
<img>必须有alt属性。<img src="{{ image | image_url }}" alt="{{ image.alt | escape }}">
步骤 2:部署 ARIA 标签 (Accessible Rich Internet Applications)
| ARIA 属性 | 使用场景 | 代码示例与作用 |
|---|---|---|
aria-label |
图标按钮(没有可见文字)。 |
<button aria-label="关闭弹窗">X</button>屏幕阅读器会读出“关闭弹窗”,而不是读出“X”。 |
aria-expanded |
折叠面板、下拉菜单、移动端汉堡菜单。 |
<button aria-expanded="false">菜单</button>用 JS 动态切换 true/false,告诉盲人用户菜单当前是展开还是收起。 |
aria-hidden |
纯装饰性的图标或重复的视觉元素。 |
<svg aria-hidden="true">...</svg>让屏幕阅读器直接跳过,减少噪音干扰。 |
步骤 3:实现完整的键盘导航 (Keyboard Navigation)
操作路径:拔掉鼠标,只用 Tab 键和 Enter 键浏览你的网站
-
可见的焦点状态 (Focus State):当用户按 Tab 键切换到某个链接或按钮时,必须有一个清晰的轮廓线(Outline)。绝对不要在 CSS 里写
outline: none;! -
跳过链接 (Skip to Content):在
theme.liquid的<body>最顶部,放置一个隐藏的链接。当用户按第一次 Tab 键时显示出来:“跳过导航,直接进入主要内容”。这能免去盲人用户每次都要听一遍长长的主导航菜单的折磨。
步骤 4:管理弹窗的“焦点陷阱” (Focus Trap)
操作路径:优化所有 Modal 和 Drawer 的 JS 逻辑
- 当购物车抽屉或快速查看弹窗打开时,用户的键盘焦点必须被“困”在弹窗内部。
- 如果用户按 Tab 键,焦点只能在弹窗里的“关闭”、“加购”等按钮之间循环。
- 绝对不能让焦点跑到弹窗背后的、被遮罩层挡住的主页面上去!一旦发生,盲人用户会彻底迷失方向。
- 当弹窗关闭时,焦点必须自动回到刚才触发打开弹窗的那个按钮上。
常见误区与处理方法
误区一:使用 <div> 或 <span> 模拟按钮,且未加键盘事件
规避方法:很多前端为了图省事,写了 <div class="btn" onclick="addToCart()">加购</div>。这在 a11y 审核中是绝对的零分!<div> 默认是无法被 Tab 键选中的(除非你加了 tabindex="0"),而且屏幕阅读器不知道它是个按钮。更致命的是,正常的 <button> 可以通过按键盘的 Enter 键或空格键触发点击,而 <div> 不行。必须使用原生的 <button> 标签。 如果非要用 <div>,你必须加上 role="button" tabindex="0",并且在 JS 里额外监听 keydown 事件来模拟回车键点击,这纯属自找麻烦。
误区二:表单输入框没有绑定 <label>
规避方法:为了设计极简,你把输入框外面的文字删了,只保留了里面的 placeholder="Email"。
<input type="email" name="contact[email]" placeholder="Email">。
屏幕阅读器在读取这个输入框时,可能根本读不出它到底是干嘛的(有些旧版阅读器不支持读取 placeholder)。每一个 <input> 必须有一个对应的 <label>。 如果你不想在视觉上显示标签,可以使用 CSS 的 sr-only(Screen Reader Only)类将其在视觉上隐藏,但保留在 DOM 树中供机器读取:
<label for="ContactEmail" class="sr-only">Email Address</label>
<input id="ContactEmail" type="email" ...>
误区三:颜色对比度不达标 (Color Contrast)
规避方法:设计师给了一个很“高级”的设计稿:浅灰色的背景上写着中灰色的文字。视力正常的人看都很费劲,对于视弱(Low Vision)用户来说,这块区域就是一片空白。Shopify 审核团队会使用自动化工具扫描全站的颜色对比度。普通文本与背景的对比度必须至少达到 4.5:1,大号文本(大于 18pt)必须达到 3:1。 在开发时,必须使用 Chrome DevTools 的颜色选择器检查对比度,如果不达标,必须强制调整颜色,哪怕这会稍微破坏原有的设计稿。
常见问题
学习「Shopify 主题可访问性 (a11y) 优化:满足官方上架标准」前需要什么基础?
建议先熟悉 HTML、CSS、基础 JavaScript 和 Shopify 后台结构。涉及 Liquid、Section、Schema 或主题工作流的内容,可以边读边在测试主题里练习,不要直接改线上主题。
可以直接在正在使用的线上主题里操作吗?
不建议。主题开发和结构调整应先在复制主题、开发主题或本地环境中完成,确认移动端、产品页、购物车和关键模板正常后,再发布到线上主题。
修改主题前最应该备份什么?
至少保留当前主题副本,并用 Git 记录代码变化。如果文章涉及主题编辑器配置,还要注意模板 JSON 和 settings_data.json 这类配置文件是否需要同步。
遇到教程和后台界面不一致怎么办?
优先以当前 Shopify 后台、主题代码和官方文档为准。Shopify 后台和 CLI 会持续更新,旧截图可用于理解路径,但不能替代当前界面提示。
这类主题开发内容适合什么时候上线到正式店铺?
当改动已经在测试主题中完成移动端、桌面端、产品页、集合页、购物车和速度检查后,再安排上线。影响结账、价格、库存或应用兼容的改动要单独回归。