HTML格式化是硬性约束,直接影响解析、工具链和协作:DOCTYPE必须顶格且无BOM,lang需符合IANA标准,charset必须为UTF-8且置于title前,语义标签如main须唯一,缩进统一用2空格,标签须闭合、属性用双引号。

HTML 格式化不是“看着舒服就行”,而是直接影响浏览器解析、工具链行为和协作效率的硬性约束。不按规范缩进、闭合或声明,轻则 CI 报错,重则 Safari 不渲染 input type="date"、Android WebView 中文变方块、屏幕阅读器跳过 main。
DOCTYPE 和 lang 必须顶格写,且值不能瞎填
漏掉或写错这两项,document.compatMode 可能返回 "BackCompat"(怪异模式),盒模型、getBoundingClientRect() 行为全乱,调试像在盲拆炸弹。
-
<!DOCTYPE html>必须是文件第一行,前面**不能有任何空格、BOM 或注释**;写成<!doctype html>也合法,但统一小写更稳妥 -
<html lang="zh-CN">的值必须来自 IANA 注册语言标签,别用zh、cn或en;多语言项目若靠 JS 动态改document.documentElement.lang,静态模板里仍得写对初始值 - 服务端渲染(如 Next.js)若模板拼接出错导致
<html>被截断,lang就直接失效——得查 SSR 模板逻辑,不是前端单方面能 fix 的
charset 必须写成 UTF-8,大小写和连字符一个都不能错
</meta charset="utf-8"> 或 <meta charset=utf8> 看似能跑,实则埋坑:部分旧版 Android WebView、某些邮件客户端会解析失败,中文变方块;W3C Validator 也会标红。
- 严格按 IETF BCP 47 标准,只接受
UTF-8(大写 UTF,短横线,大写 E) - 该标签必须放在
<head>最靠前位置,**必须在<title>之前**;否则浏览器已开始解析标题里的中文,再读到 charset 就晚了 - 用了 Vite/Webpack?确认 HTML 插件没把
<meta>插到<title>后面——这种错 CI 不报,但 QA 在低版本安卓机上一眼就崩
语义化标签不是加分项,是避免 DOM 操作翻车的刚需
用一堆 <div> 套 <div>,JS 里写 document.querySelector('.content-box-3 .item'),三个月后连你自己都得开 DevTools 才知道这玩意儿对应哪块业务逻辑。
立即学习“前端免费学习笔记(深入)”;
-
<main>必须有且仅有一个,它是页面主内容的语义锚点;屏幕阅读器靠它跳过导航直奔主题,SEO 也依赖它识别核心内容 -
<nav>只包真正导航链路(顶部菜单、面包屑、页脚链接组),别把筛选栏、分页器塞进去;否则 AT 工具会错误提示“你有 4 个导航区” -
<section>不是<div>替代品:<section>需有明确主题,通常带<h2>–<h6>;纯布局容器请用<div>
缩进、闭合、引号这些“基础操作”最容易被忽略
看似琐碎,但它们是构建可维护性的第一道防线。团队里有人用 Tab、有人用 4 空格、有人省略引号,不出三天,Git diff 就全是格式变更。
- 缩进统一用 **2 个空格**(不是 Tab,也不是 4 空格);子元素相对父元素缩进,
<body>下一级直接顶格写<header>,不额外空一行 - 所有成对标签必须显式闭合:
<p>文本</p>,别信“HTML5 允许省略”——省略后<p>A<p>B</p>会被解析成两个段落,而非嵌套 - 属性值一律用双引号:
class="header-nav",不用单引号、不用无引号;alt、src、id都要包住,否则遇到空格或特殊字符直接解析失败
最常被绕开的是 <meta charset="UTF-8"> 的位置和 <main> 的唯一性——它们不报错,但会在特定设备或辅助技术下静默失效,排查成本远高于写对那一刻的两秒确认。



















