<meta charset="UTF-8">必须是<head>内第一个子元素,紧接<head>标签后,前面不得有任何空格、注释或其它标签,否则浏览器解析非ASCII字符时将因编码未及时生效而乱码。

meta charset 必须放在 head 最前面
浏览器解析 HTML 时,一旦遇到非 ASCII 字符(比如中文、emoji),会立即用当前已知的编码去解码;如果 <meta charset="UTF-8"> 没有在前几行出现,它可能根本来不及生效,导致乱码或字符截断。常见错误是把它写在 <title> 后面,或者夹在其他 <meta> 中间。
正确做法只有一条:<meta charset="UTF-8"> 必须是 <head> 内第一个子元素(紧接 <head> 开始标签之后),前面不能有任何空格、注释或其它标签。
- ✅ 正确:
<head><meta charset="UTF-8"><title>... - ❌ 错误:
<head><title>...<meta charset="UTF-8">(title 已触发默认编码) - ❌ 错误:
<head><!-- 注释 --><meta charset="UTF-8">(注释也算内容,延迟生效)
lang 属性要精确到子语言变体
lang 不是可有可无的装饰属性,它直接影响屏幕阅读器发音、搜索引擎语义判断、字体回退逻辑。写成 lang="zh" 或 lang="cn" 都不规范,前者太宽泛,后者根本不是 BCP 47 标准标识符。
实际使用必须匹配真实用户语言环境:
立即学习“前端免费学习笔记(深入)”;
- 简体中文网页 →
<html lang="zh-CN"> - 繁体中文(台湾)→
<html lang="zh-TW"> - 英文(美式)→
<html lang="en-US"> - 页面内某段英文引用 →
<blockquote lang="en">(继承父级但显式覆盖)
注意:JS 动态修改 document.documentElement.lang 时,NVDA 等读屏软件不会自动重读,需配合 aria-live 触发更新提示。
viewport meta 在 WebView 和 iframe 中失效
<meta name="viewport" content="width=device-width, initial-scale=1.0"> 对普通浏览器有效,但在 iOS Safari 的 WebView、Android 的 WebView 组件、或嵌入 iframe 的页面里,它会被忽略——因为宿主环境已接管缩放控制权。
这意味着你无法靠这个标签“强制”让嵌入页适配手机屏幕。真正有效的做法只有两个:
- 宿主应用层设置 WebView 的
setUseWideViewPort(true)和setLoadWithOverviewMode(true)(Android) - iOS WKWebView 中启用
allowsInlineMediaPlayback并通过 JS 监听window.innerWidth动态调整布局 - 不要指望
viewportmeta 在 iframe 里起作用 —— 它只对顶层文档生效
title 和 description 要避开 CMS 自动生成陷阱
<title> 是唯一强制要求的 <head> 子元素,长度建议控制在 50–60 字符;<meta name="description"> 虽非强制,但被 Google 等主流搜索引擎直接用于搜索结果摘要。
容易踩坑的是 CMS 或 SSR 框架自动生成逻辑:
- ❌
<title>{{page.title}} | {{site.name}}</title>→ 若page.title为空,结果变成| Site Name,SEO 价值归零 - ❌
<meta name="description" content="{{page.excerpt}}">→ excerpt 为空时生成空 content,Google 会自行抓取首段文本,不可控 - ✅ 正确做法:服务端 fallback,例如
<title>{{ page.title or '首页' }}</title>,description 同理加默认值
最后提醒:所有元数据都依赖 <head> 结构完整且位置正确。一旦 <meta charset> 放错位置,后续所有 UTF-8 字符(包括中文 title、description)都可能被错误解码,再精细的 SEO 配置也白搭。



















