HTML无自动联动机制,需属性与JavaScript协同;id+for绑定label与控件是可访问性底线;data-*仅作标记,非驱动逻辑;aria-controls与aria-expanded须同步DOM状态;form属性可跨结构关联表单,但需type="submit"且IE10+支持。

HTML 本身不提供“自动联动”机制,所有复杂联动都依赖属性 + JavaScript 协同完成。关键不是堆砌属性,而是选对属性、明确职责、避免 DOM 和状态脱节。
用 id + for 绑定 label 和控件,不是可选,是可访问性底线
点击 <label for="user-name"> 必须让 <input id="user-name"> 获得焦点,这是浏览器原生行为,也是屏幕阅读器识别控件名称的唯一可靠路径。
-
for值必须和目标元素的id完全一致(大小写、连字符、空格都不能差) - 重复
id会让for指向第一个匹配项,其余控件失去语义关联 -
input、textarea、select、button等可交互元素才支持该绑定;div或span加id后用for指向它,点击无效 - DevTools 的 Accessibility 面板里能看到 “Labelled by” 字段是否为空,这是最直接的验证方式
用 data-* 传递关系标识,别存逻辑或敏感数据
dataset 是跨元素轻量传参的事实标准,但它的作用只是“标记”,不是“驱动”。真正触发行为还得靠 JS 监听和响应。
- 命名统一用小写字母+短横线:
data-group="filter",不要dataGroup或data_group,否则el.dataset.group读不到 - 值永远是字符串,
data-active="true"读出来是"true",要布尔判断得写el.dataset.active === "true" - 多个按钮控制同一区域时,用相同
data-filter值 + 不同data-value区分:<button data-filter="category" data-value="tech"> - 别把用户 token、价格计算公式塞进
data-—— 它在 HTML 源码里明文可见,等同于公开
用 aria-controls + aria-expanded 声明控制关系,不是装饰
折叠面板、下拉菜单、手风琴组件这类“一个元素控制另一个显隐”的场景,仅靠 class 切换或 JS 显隐远远不够。辅助技术需要明确的语义映射。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
立即学习“前端免费学习笔记(深入)”;
-
aria-controls的值必须是被控元素的id字符串,不能是 class 名或 CSS 选择器 -
aria-expanded只接受"true"或"false",写成aria-expanded=""或aria-expanded="1"会被视为无效 - JS 更新状态时,两个属性必须同步修改:先设
el.setAttribute('aria-expanded', 'true'),再显示内容;反之亦然 - 如果被控元素没有
id,或者id被 JS 动态删改过,aria-controls就断链了,辅助技术完全感知不到变化
用 form 属性跨结构关联提交按钮,IE10+ 才支持
当提交按钮不在 <form> 内部时(比如固定在页脚),form 属性是唯一合法的原生方案,比手动调用 form.submit() 更符合表单语义。
-
button必须带type="submit",否则form="xxx"不生效 -
form属性值是目标<form id="xxx">的id,不是name或 class - 一个按钮只能关联一个表单,不支持空格分隔多个
id - 旧版 IE 不支持,需降级处理:
if (!supportFormAttr) { button.addEventListener('click', () => document.getElementById('target-form').submit()); }
真正容易被忽略的,是属性变更和 DOM 状态的同步时机 —— 比如用 JS 改了 dataset 却忘了更新对应 UI,或切了 aria-expanded 但没真正 show/hide 元素,这种“半吊子语义”比完全不用还危险。


















