html兼容性核心是三件事:doctype必须顶格无bom,语义标签需手动设display:block,css/js须基于api存在性检测;其他方案均由此衍生。

用 开头,别写成 XHTML 或省略
很多老项目残留 ..>,或直接没声明。这会让 IE、Edge(旧版)进入怪异模式,box-sizing、flex 行为全乱。现代浏览器对缺失 DOCTYPE 也降级处理,不是“还能用”,而是“用得不对”。
实操建议:
- 必须且仅用
,全部小写,无空格,无注释 - 不要加任何系统标识符(如
SYSTEM)、URL 或版本号 - 确保它在文件第一行,前面不能有 BOM、空格或 PHP 输出
根元素用 ,别漏掉 lang
不设 lang 属性,屏幕阅读器无法正确发音,翻译工具可能误判语言,部分 CSS 伪类(如 :lang())失效,甚至影响字体 fallback 行为(比如中英文混排时系统选错字族)。
实操建议:
-
lang值要精确:简体中文用zh-CN,繁体用zh-TW或zh-HK;英语按地区写en-US、en-GB - 子元素可覆盖:局部英文段落加
<span lang="en">API</span> - 避免写成
lang="zh"这种泛化值,部分浏览器/AT 工具不识别
语义化标签从 <header></header> <main></main> <footer></footer> 开始用,但别硬套
很多人以为用了 <section></section> 就算语义化,结果嵌套三层 <section></section> 没 heading,反而破坏结构。辅助技术依赖 heading 层级和区域角色推导内容关系,不是看标签名本身。
实操建议:
- 每个页面必须有且仅有一个
<main></main>,它是主要内容的容器 -
<header></header>和<footer></footer>应出现在直接子级,或包裹在<article></article>/<section></section>内——取决于它是全局还是局部 - 避免用
<div role="main"> 代替 <code><main></main>:前者需手动管理焦点、键盘导航,<main></main>浏览器原生支持 - 没有 heading 的
<section></section>多数时候该用<div> ——语义是“有标题的内容区块”,不是“分块容器” <h3>兼容旧浏览器时,<code><picture></picture>和<video></video>必须配fallback<picture></picture>在 IE 完全不支持,<video></video>在 Android 4.3 及更早版本只认.mp4(H.264+AAC),且不支持preload="metadata"。光写新语法,用户看到的就是空白或报错图标。实操建议:
-
<picture></picture>内部必须有<img src="fallback.jpg" alt="...">作为最后子节点,IE 和旧 Safari 会忽略<picture></picture>但渲染<img> -
<video></video>至少提供.mp4格式,并用<source></source>显式声明:<source src="vid.mp4" type="video/mp4"></source> - 避免只靠 JS 检测后动态插入媒体:禁用 JS 时内容不可见,SEO 也不抓取
真正难的不是写对标签,而是判断哪些地方“看起来一样但行为不同”——比如
<main></main>在 Safari 12 之前不触发document.querySelector('main'),但用getElementById却可以;又比如lang值写错,Chrome 不报错,但 NVDA 读出来就是日语腔调。这些细节不会在控制台报错,但用户已经卡住了。 -











