我的 HTML 样板(HTML Boilerplate)
原文:My HTML Boilerplate · 作者:Declan Chidlow(VALE)· 2026-09-09 · 标签:#前端 #HTML 本文为中文翻译,仅供学习交流。
引言
当 HTML 最初被创建时,一个文档可以非常简单。一个合法文档可以长这样:
html
<TITLE>HTML document</TITLE>
<H1>Heading</H1>
<P>This is a paragraph with a <A HREF="https://example.com/">link</A>.
直到 HTML 2.0------第一个正式标准------才出现了完整的文档结构。DOCTYPE 声明用于说明文档类型并处理兼容性,成为预期的必备内容,head 和 body 部分也是如此:
html
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HEAD>
<TITLE>HTML document</TITLE>
</HEAD>
<BODY>
<H1>Heading</H1>
<P>This is a document.
</BODY>
自 1995 年 HTML 2.0 诞生以来,Web 已经发生了翻天覆地的变化。然而,Web 标准界有一句名言:"不要打破 Web"(Don't Break The Web)。虽然存在少数例外,但总的来说,在 Web 诞生之初开发的网站应当能在现代浏览器中正常工作,无论时间过去了多久。然而,为了维持这种兼容性,也带来了风险:因为害怕破坏现有网站,改动可能变得寸步难行。
Web 应对这个问题的方式之一,是某些被"期待"出现在 HTML 文档中的元素。如果元素存在,就启用新功能;如果不存在,就默默回退到旧功能。再结合 Web 上各种集成和系统各自的期望,这就意味着存在相当多的"样板代码"(boilerplate)------几乎每个新建或维护的网站上都会重复出现的代码。HTML 样板通常既用于选择启用现代功能,也用于设定站点的偏好和细节,例如网站在社交媒体上应当如何被嵌入、应当加载什么样式、浏览器应当如何为网站周边界面设置主题,以及诸如此类的细节。
完整样板(Boilerplate)
正如我维护自己的 CSS Reset(为自己的样式提供一个干净的起点)一样,我也维护自己的 HTML 样板,把它作为创建 HTML 文档时的基础结构和参考。和我的 CSS Reset 一样,它非常"有主见"。以下是完整代码:
html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="text-scale" content="scale">
<title>Name of Page | Name of Website</title>
<link rel="stylesheet" href="/styles.css">
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
<meta property="og:title" content="Name of Page">
<meta name="description" content="Description of this page.">
<meta property="og:description" content="Description of this page for embeds.">
<link rel="icon" type="image/svg+xml" href="https://example.com/favicon.svg">
<meta property="og:image" content="https://example.com/embed-image.webp">
<meta property="og:image:alt" content="A picture of something.">
<meta property="og:image:type" content="image/webp">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<link rel="canonical" href="https://example.com/page">
<meta property="og:url" content="https://example.com/page">
<meta property="og:site_name" content="Website Name">
<meta name="author" content="A N Other">
<meta name="color-scheme" content="light dark">
<meta name="theme-color" content="red" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="green" media="(prefers-color-scheme: dark)">
<link rel="alternate" type="application/rss+xml" title="RSS feed of posts on Website Name." href="/posts/feed.xml">
<link rel="alternate" type="application/feed+json" title="JSON feed of posts on Website Name." href="/posts/feed.json">
<link rel="search" type="application/opensearchdescription+xml" title="Website Search" href="https://example.com/opensearch.xml">
<link rel="manifest" href="/app.webmanifest">
</head>
<body>
<header><nav></nav></header>
<main id="main"></main>
<footer id="footer"></footer>
</body>
</html>
逐项解析
需要说明的是,我的 HTML 样板是有顺序讲究的。尤其是 head 的顺序对性能有着巨大影响。Capo.js 是一个很棒的工具,可以从性能角度评估文档 head 中元素的顺序。
<!doctype html>
这是"活标准"(living standard)HTML 的文档类型声明,由 HTML 5 引入。我总是包含它,以避免落入怪异模式(quirks mode)。
<html lang="en"></html>
开启包裹整个文档的 html 标签,并通过 lang 属性使用符合 RFC 5646 的标签定义文档语言。所设置的语言是整页的默认语言,也可以按元素单独覆盖。提供语言信息对于自动翻译、排版(如断字 hyphens)以及辅助技术(尤其是屏幕阅读器)非常重要。
<meta charset="UTF-8">
我放在 head 中的第一个元素永远是 charset 元标签,值为 UTF-8------这是 HTML 5 中唯一合法的编码。它总是位于 head 的最顶端,因为它必须出现在文档的前 1024 字节内,而且应当放在任何可能被"搞乱"的元素之前。
<meta name="viewport" content="width=device-width">
2007 年第一部 iPhone 发布时,它以"期望用户自行缩放和拖动"的方式渲染桌面网站。Apple 针对真正为移动端优化的网站引入了上面的 meta 标签,后来它被各大浏览器更广泛地采用,如今已被广泛支持,用来让网站具备响应式能力。
很多人会包含 initial-scale=1,但经过大量测试和研究,我发现它已经不再需要了。当某个元素在水平方向超出视口宽度时,它可以改变页面的呈现方式,但这本就不应该被允许发生,我建议避免这种情况。
minimum-scale、maximum-scale 和 user-scalable 都会严重损害可访问性,永远不应该使用。一旦注意到,通常就应该把它们从网站中移除。
<meta name="text-scale" content="scale">
让文本根据系统设置进行缩放。如果存在此标签,那么页面的样式必须预期到这一点,并据此编写。这对于避免内容缩放带来的可访问性陷阱尤为重要。
<title>Name of Page | Name of Website</title>
页面的标题。它是必填值,会显示在很多界面上:被收藏时作为书签名称、搜索引擎标签页中的名称,以及任何需要页面名称的地方。我通常按照"页面标题 | 网站名称"的格式展示。
<link rel="stylesheet" href="/styles.css">
需要导入的任何样式都可以在这里导入。样式通常应当在页面 head 中导入,而不是在样式表内部使用 CSS 的 @import 规则,以避免"瀑布"效应------即必须先获取该样式表,才能再获取额外的样式表。
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
复杂的可变字体(variable fonts)即使经过子集化和其他优化,体积也可能相当大,所以我会预加载已知要在页面上使用的字体。即使字体位于同源,crossorigin 属性仍然是必需的。我总是以 WOFF2 格式提供字体,因为它是性能最好且被广泛支持的字体格式。
<meta property="og:title" content="Name of Page">
og:title 用于网络嵌入场景,例如社交媒体上的分享卡片。它是 Open Graph 协议的众多元数据值之一。虽然我通常会在 <title> 元素末尾加上网站名称,但在 og:title 中我会省略它。因为在大多数情况下,嵌入卡片会在标题旁边显示域名或 og:site_name,再写上网站名就重复了。
<meta name="description" content="Description of this page.">
我主要把这个 meta description 字段当作一次搜索引擎优化(SEO)的实践。过去,主流搜索引擎会在搜索结果页向用户展示这段描述,不过现在它们大多直接从文档本身抓取内容了。
<meta property="og:description" content="Description of this page for embeds.">
og:description 有时会显示在嵌入卡片中。如果缺失,嵌入通常要么省略描述,要么回退到 meta description。我喜欢在这里写简短、常有几分俏皮的内容,能勾起好奇心,又适合社交媒体或聊天信息流。
<link rel="icon" type="image/svg+xml" href="https://example.com/favicon.svg">
网站图标(favicon)是所有网站的重要品牌元素------尤其是在打开很多标签页时,它用于识别标签。我用 SVG 作为网站图标,因为 SVG 支持良好,可以动态适配亮色/暗色模式,在任何尺寸下都很好看,而且无需维护一组不同尺寸的位图图标。
og:image 一组
html
<meta property="og:image" content="https://example.com/embed-image.webp">
<meta property="og:image:alt" content="A picture of something.">
<meta property="og:image:type" content="image/webp">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
og:image 中定义的图片通常会展现在网站在社交媒体或聊天平台上的嵌入卡片中。几乎每个网站都值得包含它,因为它能提供上下文,而且通常能增大嵌入卡片的尺寸,提升存在感。嵌入图片对 alt 文本的支持参差不齐,所以不应依赖它:有些网站支持,有些忽略,有些则以奇怪的方式支持。我会努力包含它,但保持简短。1200px × 630px 是被广泛支持的尺寸;而在我测试过的现代图片格式中,WebP 是支持最好的。
canonical + og:url
html
<link rel="canonical" href="https://example.com/page">
<meta property="og:url" content="https://example.com/page">
指向页面权威版本的 canonical(规范)链接非常重要,它标明哪个地址应被视为"事实来源"。当内容出现重复时,这一点尤其关键。
<meta property="og:site_name" content="Website Name">
在嵌入卡片中显示的网站名称。如前所述,有些嵌入会在页面标题旁边显示这个名称。
<meta name="author" content="A N Other">
author 标签显然表示页面的作者。它不是严格必需的,但对于开发者识别谁对页面负责很有用。
<meta name="color-scheme" content="light dark">
将 color-scheme 元标签的 content 属性设置为 light dark,会告诉浏览器该网站同时支持亮色和暗色两种模式。在 head 中定义它可以避免"无样式内容闪烁"(FOUC, Flash of Unstyled Content)------比如网站和浏览器都设置为暗色模式时,却先闪出一片刺眼的亮白。
theme-color(亮色 / 暗色)
html
<meta name="theme-color" content="red" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="green" media="(prefers-color-scheme: dark)">
用于为已安装为渐进式 Web 应用(PWA)的网站设置浏览器界面(browser chrome)的主题,也用于设置 Android 版 Chrome 的浏览器界面主题(但仅限亮色模式)。一些其他浏览器也会以各种方式解读这些值。我使用 media 属性分别设置亮色和暗色模式下的颜色。
订阅源(RSS / JSON Feed)
html
<link rel="alternate" type="application/rss+xml" title="RSS feed of posts on Website Name." href="/posts/feed.xml">
<link rel="alternate" type="application/feed+json" title="JSON feed of posts on Website Name." href="/posts/feed.json">
如果网站有内容聚合(syndication)订阅源,那么在 head 中包含这些标签可以实现订阅源的自动发现(autodiscovery)。
<link rel="search" type="application/opensearchdescription+xml" title="Website Search" href="https://example.com/opensearch.xml">
如果网站集成了搜索功能,那么建立一个 opensearch.xml 文件并在文档 head 中引用它,就能向浏览器暴露搜索能力,提供丰富的搜索体验。具体体验因浏览器而异,但在很多情况下,它允许通过浏览器自带的地址栏直接搜索该网站,也提供了将网站添加为搜索引擎的简便方式。
<link rel="manifest" href="/app.webmanifest">
我是渐进式 Web 应用的布道者。我喜欢它们,很多网站都能从成为 PWA 中获益,即使它并不是典型的"应用"。我会为大多数网站定义一个 manifest,哪怕唯一的好处只是:人们把网站添加到主屏幕时,呈现效果更美观。这个声明能帮助浏览器发现 manifest。
<body> 结构
html
<header><nav></nav></header>
<main id="main"></main>
<footer id="footer"></footer>
这定义了任何网站的大致 body 结构:header 中承载用于全站导航的 nav 元素;main 承载页面的主要内容,并带有 id 属性以提供锚点,这对"跳到主内容"(skip to)链接很重要;footer 存放关于当前网站和页面的信息。和 main 一样,我也给 footer 一个 id 用于锚定。我不会再把 HTML body 样板写得更细,因为不同网站的差异实在太大。
结语
这只是样板而已。它是一个模板,差不多每个网站上我都会包含这些内容,并做些轻微调整。每个网站当然都会根据自己的需求偏离它,但它是一个合理的基础。
如果页面预期会被学术引用,那么你会考虑加入 Google Scholar 的 citation_* 元标签和 Dublin Core 的 dc 元标签。如果页面代表一篇文章,你会加入 Open Graph 协议 article 命名空间中的标签,也许还有与发布系统相关的标签。视频、音频、图书或其他内容类型也同样需要不同的标记方式。许多网站还会受益于 JSON-LD 结构化数据。这完全取决于具体页面和它的需求。
如果你想看一个更大型、列出更多可选内容的样板,我推荐 Manuel Matuzović 的精彩文章《My HTML boilerplate in 2026》。
脚注
确实存在可以使用它们的场景,但当你遇到那些极其罕见的场景时,你自然就会明白。请务必格外小心。