meta charset="utf-8"必须位于doctype之后、所有其他标签之前,且文件须存为无bom的utf-8;lang与dir需按bcp 47规范在对应元素上同时设置,不可互换或遗漏。

meta charset="UTF-8"必须写在最前面
不写或位置错,浏览器可能用系统默认编码(如GBK)解析,中文直接变。常见错误是把它塞在<script>或<style>后面,甚至放在DOCTYPE之前——此时<meta>完全失效。</script>
实操建议:
-
meta charset="UTF-8"必须是中第一个标签(DOCTYPE之后、其他任何标签之前) - 文件本身也得存为无BOM的UTF-8:VS Code默认符合,Sublime Text/Notepad++需手动选“UTF-8 without BOM”
- 如果后端用PHP/Python生成HTML,确保源文件编码也是UTF-8,否则
echo "<meta charset='\"UTF-8\"'>"输出时会被转成乱码 - HTTP响应头
Content-Type: text/html; charset=UTF-8应与一致;若冲突,以响应头为准——可在DevTools Network面板检查
lang属性不能只写在html>上,局部文本要单独声明
只设html lang="zh-CN",页面里一段英文引文<p>“Hello world”</p>仍会被屏幕阅读器按中文读,Chrome翻译也会误判整段为中文。语言识别是逐元素生效的,不是继承的。
实操建议:
- 英文术语、代码、URL等混排内容,必须用语义化标签包裹并显式加
lang:<code lang="en">useState、<blockquote lang="fr">Merci</blockquote> - 避免用
<div lang="en">包单词——<code><q></q>、<cite></cite>、<abbr></abbr>才是语义正确载体 -
input和textarea必须单独设lang和dir,仅靠父容器设置无效;阿拉伯语输入框不加dir="rtl",光标会从左开始跳 - 值必须严格符合BCP 47:
zh-CN✅,zh_CN❌,Chinese❌,zh-Hans仅在明确排除繁体时用 - RTL语言(阿拉伯语、希伯来语、波斯语)必须在根元素、
input、textarea上同时写lang和dir -
textarea换行后新行应从右边界开始;若异常,检查是否误用了padding-left(应改用padding-inline-start) - 混合内容中嵌入LTR片段(如URL、代码),必须用
<span lang="en" dir="ltr">https://example.com</span>隔离,不能只靠CSSdirection: ltr - 别在已设
dir="rtl"的容器里再写text-align: right——冗余声明会让BIDI算法行为不可预测 - 如果支持多个中文变体,样式要枚举:
:lang(zh-CN), :lang(zh-TW), :lang(zh-HK) { quotes: "「" "」"; } - 避免用泛化值如
lang="zh"来简化开发——它无法触发拼音输入提示、TTS声调区分、字体回退链切换 - 不要给
<script></script>或<style></style>加lang属性,它们不参与文本渲染,浏览器忽略 - 动态插入的DOM(如AJAX弹窗、分页表格行)必须手动设置
lang,MutationObserver监听不到语言属性变化
dir="rtl"和lang必须同时出现,且不能互换职责
设lang="ar"但没dir="rtl",阿拉伯文字显示为LTR流向,تَعْلِيم被拆成孤立字符;设dir="rtl"但lang="en",数字仍用012…而非٠١٢…,屏幕阅读器念阿拉伯词却用英语音调。
实操建议:
:lang()伪类样式匹配很挑剔,别指望它自动降级
:lang(zh)只匹配lang="zh",不匹配lang="zh-CN";:lang(zh-CN)也不匹配lang="zh-Hans"。写错就等于没写,样式完全不生效。
实操建议:
pre lang="bash"里的中文注释、img alt里的描述、button的title,全得按实际语言分别标注。漏掉一个,无障碍体验就断一环。











