html属性必须写在开始标签内,用空格分隔,格式为属性名="属性值";禁用中文引号、逗号或分号;全局属性如id、class、data-*等仅限起始标签使用,且需符合命名与访问规范。

直接写在开始标签里,用空格分隔,格式是属性名="属性值",别写在结束标签,也别用中文引号或逗号分隔。
全局属性只能加在开始标签里
HTML 规范明确要求:所有属性(包括全局属性)必须出现在元素的起始标签中,结束标签不接受任何属性。写错位置等于白写。
-
id、class、title这些看似“通用”的属性,一旦塞进这种结束标签,浏览器完全忽略 - 多个属性之间只能用空格隔开,比如
<div id="main" class="container" title="首页">✅;用逗号或分号就是语法错误❌<li>引号必须是英文双引号(<code>")或单引号('),中文引号“”会导致整个标签解析失败 -
accesskey、autocapitalize、autocorrect在移动端更敏感,桌面端可能被系统快捷键拦截,慎用 -
on*类(如onclick)是 DOM 接口行为,不属于 HTML 全局属性范畴,不要混为一谈 -
xml:lang和xml:base已被弃用,仅保留向后兼容,新项目别用 - 必须以
data-开头,后面只能跟小写字母、数字、短横线(-),不能有大写字母或下划线;data-user-id="123"✅,data-userId="123"❌ - JS 中必须用
dataset访问:el.dataset.userId实际读的是data-user-id(自动转驼峰) - 动态设置要用
el.dataset.foo = "bar",而不是el.setAttribute("data-foo", "bar")—— 后者不会同步到dataset对象 -
tabindex="0"是最常用且合规的选择,让元素按 DOM 顺序进入自然焦点流 -
tabindex="-1"只能靠 JS 主动调el.focus()聚焦,不能被 Tab 键到达 - 如果子元素设置了
user-select: none或pointer-events: none,会拦截光标定位,导致“能聚焦但无法输入” - 顺手加上
spellcheck="false"能去掉拼写下划线,避免干扰 UI
哪些属性真能用在任意标签上
不是“看着顺眼就能加”。MDN 当前(2026 年 4 月)明确定义的全局属性共 27 个,常见且安全可用的包括:id、class、title、tabindex、contenteditable、draggable、hidden、lang、spellcheck、style、data-* 等。
data-* 属性命名和读取有硬性规则
它自由度高,但浏览器对格式和 JS 访问方式有强制约定,写错就拿不到值。
contenteditable 必须配 tabindex="0" 才算真正可用
只加 contenteditable="true" 是半残状态:鼠标点得进去,Tab 键跳不过去,屏幕阅读器识别不了,WCAG 2.1 2.1.1 直接不通过。
最容易被忽略的是:全局属性不是“写了就生效”,而是依赖上下文——语言模式、VSCode 设置、浏览器版本、是否在 shadow DOM 里,都可能让某个属性看起来“失灵”。验证时别只看 HTML 是否写对,要连带检查运行环境。











