全局属性不提升视觉可读性,但增强语义与辅助技术可读性;class应前置、id后置以符合“通用→特殊”认知;title慎用于非交互元素;lang/dir须设于html根元素;data-*命名需统一小写连字符。

全局属性本身不直接提高“视觉可读性”,但能显著提升“语义可读性”和“辅助技术可读性”——也就是让代码对人(开发者、审核者)和机器(屏幕阅读器、搜索引擎)都更易理解、更少歧义。
为什么 class 和 id 顺序影响团队可读性
class 和 id 是最常被读到的全局属性,它们的位置决定了开发者第一眼看到的是什么。把 class 放前面,id 放后面,符合“通用 → 特殊”的认知习惯:一个元素可能属于多个类(如 btn btn--primary),但只属于一个唯一标识。
- 错误写法:
<button id="submit-btn" class="btn btn--large"></button>—— id 抢先出现,容易让人误以为这是“唯一操作目标”,忽略其复用意图 - 推荐写法:
<button class="btn btn--large" id="submit-btn"></button>—— class 先暴露行为特征,id 作为补充定位 - CI 工具(如 htmlhint)可配置
attr-order规则强制该顺序,避免人工疏漏
title 属性不是 tooltip 替代品,慎用在非交互元素上
title 在鼠标悬停时显示文字,但它在键盘导航、触摸设备、部分读屏器中不可靠,且会干扰焦点管理。滥用它会让代码语义模糊,比如给 <div> 加 <code>title,既不能聚焦也不传达结构意图。
- 可用场景:
<input>、<button></button>、<abbr></abbr>等原生支持焦点与解释的元素 - 禁用场景:
<div title="用户头像区域"> —— 应改用 <code>aria-label或显式<label></label>,或直接用语义标签如<section aria-labelledby="avatar-heading"></section> - 性能影响:每个
title都触发浏览器 tooltip 渲染逻辑,大量使用会轻微拖慢滚动响应 - 正确写法:
—— 所有子元素自动继承,无需重复 - 例外情况:仅当某段内容明确切换语言时才覆盖,如
<p lang="en">The term “accessibility”</p> - 常见坑:Next.js / Remix 等框架生成的 HTML 模板常漏掉
lang,需手动补全;SSR 渲染时若服务端未传入语言上下文,lang值可能为空字符串,等同于未设置 - 命名规范:全小写 + 连字符分隔,如
data-track-id、data-modal-trigger,禁用驼峰或下划线 - 作用域控制:不要在顶层
上堆砌大量data-*,应绑定到最接近使用它的组件容器上 - 替代方案:复杂状态优先走 JS 模块变量或 Context,
data-*只用于传递静态元信息(如埋点 ID、模板版本号)
lang 和 dir 属性必须写在根元素,否则语义链断裂
lang 和 dir 是影响文本渲染、断字、语音朗读节奏的基础属性。如果只在局部元素上设置,而 标签没声明主语言,屏幕阅读器会回退到系统默认语言,导致中文页面被读成英文音调,或 RTL 文本方向错乱。
data-* 属性命名要收敛,避免变成“私有配置黑洞”
data-* 是唯一允许自由扩展的全局属性,但随意命名会让 HTML 变成难以维护的“配置文件”。比如 data-user-id、data-userId、data_userid 并存,后续 JS 查询就得写三套逻辑。
最容易被忽略的是 lang 和 dir 的缺失——它们不报错、不闪动、不影响布局,但会让整页内容在辅助技术中“失语”。一个没设 lang 的中文页面,在 VoiceOver 下可能被识别为日语或韩语,连“登录”两个字都读不准。这不是锦上添花,而是语义地基。











