90%的可访问性问题可通过优化四类HTML标签解决:img的alt属性、label与表单控件绑定、语义化容器(header/nav/main)、动态内容的aria-live声明。

直接结论:90% 的可访问性问题,靠改四类 HTML 标签就能解决——img 的 alt、label 与表单控件的绑定、语义化容器(header/nav/main)、动态内容的 aria-live 声明。
图片没 alt,屏幕阅读器就当它不存在
电商页里商品图、图标、轮播图占页面大半,但只要 alt 缺失或写成 alt="product.jpg",屏幕阅读器就会跳过整张图——用户连“这是衣服还是手机”都不知道。
- 功能性图片(如商品主图、加入购物车图标)必须写描述性
alt:alt="女士纯棉T恤,圆领短袖,深蓝色,售价¥129" - 纯装饰图(如分隔线 SVG、背景花纹)必须显式写
alt="",不能省略属性 - 带链接的图片,
alt应说明目标动作,不是描述图像本身:alt="查看iPhone 15 Pro详细参数",而非alt="参数图标" - 内联
svg必须加role="img"或aria-hidden="true"+<title>,否则会被当作普通容器忽略
表单控件没 label,键盘用户根本没法填
登录框、收货地址、颜色尺寸选择器……这些表单密集区若只靠 placeholder 或视觉对齐,键盘用户 tab 过去时只会听到“编辑文本”,不知道是手机号还是验证码。
- 优先用包裹式写法:
<label>手机号<input type="tel"></label>,天然建立关联,无需额外属性 - 若布局限制必须分离,务必配对
for和id:<label for="email">邮箱</label><input id="email" type="email">,且id值不能含空格或重复 - 禁用
placeholder替代label:它不提供持久可访问名称,且输入后消失,对低视力用户也不友好 - 所有
select、textarea、input都必须有可访问名称,否则得兜底加aria-label,但不如原生label稳定
一堆 div 套娃,屏幕阅读器只能报“区块”
电商页顶部横幅、分类导航、商品网格、悬浮客服全用 <div class="header"> 或 <div class="product-list">,结构就彻底扁平化。屏幕阅读器无法识别“这是导航”“这是商品列表”,用户得靠键盘逐个 tab 摸索,耗时增 3–5 倍。
立即学习“前端免费学习笔记(深入)”;
-
<header>必须包裹 logo、搜索框、用户入口;<div class="header">对可访问性零贡献 -
<nav aria-label="主导航">包住一级类目链接;页脚导航另起一个<nav aria-label="页脚链接"> -
<main>全局唯一,且必须是<body>的直接子元素;里面再套一层<section>或<div>就会破坏层级识别 - 每个商品项用
<article>包裹,比<div class="product-item">更明确表达“独立可分发单元”语义
AJAX 提交成功却不通知,视障用户以为操作失败
加入购物车弹出 toast、表单校验失败高亮字段、模态框打开……这些动态变化若不主动声明,屏幕阅读器不会读出任何新内容,用户卡在旧状态里反复点击。
- 错误提示必须用
<div aria-live="polite">包裹,且放在 DOM 中靠前位置(最好紧贴<form>开头) - 模态框需同时设
role="dialog"、aria-modal="true"、aria-labelledby指向标题元素,否则读屏可能继续朗读背景内容 - 校验失败字段加
aria-invalid="true"和aria-describedby指向错误消息id,否则读屏不会读出错误文本 - 避免仅用
display: none隐藏错误消息:它会从可访问树中移除内容,读屏完全感知不到
最常被忽略的是 main 的嵌套层级和 aria-live 的放置位置——前者导致整个页面语义结构失效,后者让所有动态反馈形同虚设。改完这两处,多数视障用户的首屏操作时间能直接回落到健全用户水平。



















