doctype必须顶格写在第一行,前面不能有任何空格、bom或注释,否则触发怪异模式;lang属性须精确匹配bcp 47标准(如zh-cn),且必须存在并全局唯一。

DOCTYPE 和 lang 必须顶格写在第一行
只要前面多一个空格、BOM 或注释,IE 和旧版 Safari 就会进怪异模式:flex 布局失效、100vh 计算错误、<input type="date"> 直接不渲染。更隐蔽的是某些 Webpack HTML 插件会在注入 <title></title> 前悄悄加空行。
-
DOCTYPE必须是文件绝对首字符,前面不能有任何内容(包括 UTF-8 BOM) -
lang值必须精确匹配 BCP 47 标准:中文站点用zh-CN,港澳台按实际用zh-HK、zh-TW;lang="zh"或lang="cn"是无效值 - 多语言项目不能只靠静态 HTML,需在 JS 中同步更新
document.documentElement.lang
全局只能出现一次且必须存在
这不是语义“加分项”,而是 W3C 强制定义的唯一语义锚点:main 缺失会导致 SEO 抓取权重分散、屏幕阅读器无法定位核心内容;重复则触发 axe/Lighthouse 报错,且部分爬虫直接忽略主体内容。
-
main必须直接包含至少一个h1–h6,否则被当作文本缺失处理 - SPA 场景下,
main应包裹实际渲染区域(如#app内部),而非仅套在静态壳层里 - 服务端渲染时,若模板中
main被条件注释或动态移除,需确保 fallback 内容仍符合语义流
属性值必须用双引号,布尔属性要显式书写
iOS WKWebView 对未加引号的 class=header 可能截断为 class=header 后跟空格;安卓 X5 内核可能直接忽略;React/Vue SSR 时若遇到 disabled="disabled",可能与客户端 hydrate 不一致,引发 Hydration mismatch 错误。
- 所有属性值强制使用双引号:
class="user-avatar",禁止不加引号或单引号 - 布尔属性(如
disabled、required)必须显式写出完整形式:required="required",而非仅required -
charset值必须写成UTF-8(全大写 + 连字符),utf8、utf-8、UTF8都有兼容性风险
data- 属性才是 JS 模块锚点的唯一可靠方案
靠 class="header-v2" 或 id="product-list" 绑定 JS,等于把样式逻辑和交互逻辑焊死。一旦改名或复用组件,document.querySelector('.header-v2') 就静默失效。
- 统一使用
data-module="header"、data-module="product-grid",版本号用data-version="2.1" - 避免用
id查询:循环渲染商品卡片时,id="card-1"会重复,document.getElementById()只返回第一个 - 查询时用
document.querySelectorAll('[data-module="header"]'),既稳定又支持多实例
真正卡住团队的不是规则多,而是 DOCTYPE 前那一个看不见的 BOM、main 被嵌套在 nav 里的那一层 DOM、或者 JS 里还在用 getElementById 查一个早已被模板引擎复用掉的 id —— 这些点不盯死,其他规范再漂亮也白搭。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











