面向 Web 开发人员版 — 最后更新于 2024 年 9 月 12 日
本节仅描述标记为 HTML MIME 类型 的资源的规则。XML 资源的规则在下面题为 "XML 语法" 的章节中讨论。
文档必须包含以下部分,并按给定顺序排列
html
元素 的形式。上面提到的各种内容类型将在接下来的几个部分中进行描述。
此外,对 字符编码声明 的序列化方式也有一些限制,如相关章节所述。
ASCII 空格 在 html
元素之前,在 html
元素的开头以及在 head
元素之前,将在文档解析时被丢弃;ASCII 空格 在 html
元素之后将被解析,就好像它在 body
元素的末尾一样。因此,ASCII 空格 在 文档元素 周围不会往返。
建议在 DOCTYPE 之后、在文档元素之前的任何注释之后、在 html
元素的开始标签之后(如果它没有 被省略)以及在 html
元素内部但在 head
元素之前的任何注释之后插入换行符。
HTML 语法中的许多字符串(例如,元素及其属性的名称)不区分大小写,但仅适用于 ASCII 大写字母 和 ASCII 小写字母。为方便起见,在本节中,这仅称为“不区分大小写”。
DOCTYPE 是一个必需的前言。
由于遗留原因,DOCTYPE 是必需的。如果省略,浏览器往往会使用与某些规范不兼容的不同渲染模式。在文档中包含 DOCTYPE 可确保浏览器尽最大努力遵循相关规范。
DOCTYPE 必须包含以下组件,并按此顺序排列
<!DOCTYPE
” ASCII 不区分大小写 匹配的字符串。html
” ASCII 不区分大小写 匹配的字符串。换句话说,<!DOCTYPE html>
,不区分大小写。
对于无法使用简短 DOCTYPE“<!DOCTYPE html>
”输出 HTML 标记的 HTML 生成器,可以将 DOCTYPE 遗留字符串 插入到 DOCTYPE 中(在上面定义的位置)。此字符串必须包含
SYSTEM
” ASCII 不区分大小写 匹配的字符串。about:legacy-compat
”。换句话说,<!DOCTYPE html SYSTEM "about:legacy-compat">
或 <!DOCTYPE html SYSTEM 'about:legacy-compat'>
,除了单引号或双引号中的部分外,不区分大小写。
除非文档是从无法输出较短字符串的系统生成的,否则不应使用 DOCTYPE 遗留字符串。
有六种不同的 元素:空元素、template
元素、原始文本元素、可转义原始文本元素、外来元素 和 普通元素。
area
、base
、br
、col
、embed
、hr
、img
、input
、link
、meta
、source
、track
、wbr
template
元素template
script
、style
textarea
、title
标签 用于在标记中分隔元素的开始和结束。 原始文本、可转义原始文本 和 普通 元素都有一个 开始标签 来指示它们的开始位置,以及一个 结束标签 来指示它们的结束位置。某些 普通元素 的开始和结束标签可以 被省略,如下面关于 可选标签 的章节所述。那些不能省略的标签必须不能省略。 空元素 只有开始标签; 空元素 必须不能指定结束标签。 外来元素 必须要么有开始标签和结束标签,要么有一个标记为自闭合的开始标签,在这种情况下,它们必须不能有结束标签。
元素的 内容 必须放置在开始标签之后(在某些情况下 可能隐含)和结束标签之前(同样,在某些情况下 可能隐含)。每个单独元素的确切允许内容取决于该元素的 内容模型,如本规范前面所述。元素必须不能包含其内容模型不允许的内容。但是,除了这些内容模型对内容施加的限制之外,五种类型的元素还有额外的语法要求。
空元素 不能有任何内容(因为没有结束标签,所以不能在开始标签和结束标签之间放置任何内容)。
template
元素 可以有 模板内容,但这些 模板内容 本身并不是 template
元素的子元素。相反,它们存储在一个与不同的Document
关联的 DocumentFragment
中——没有 浏览上下文——以避免 template
内容干扰主Document
。 template
元素的 模板内容 的标记放置在 template
元素的开始标签之后和 template
元素的结束标签之前(与其他元素一样),并且可以包含任何 文本、字符引用、元素 和 注释,但文本必须不能包含字符 U+003C 小于号 (<) 或 歧义的 & 符号。
可转义原始文本元素 可以包含 文本 和 字符引用,但文本不得包含 模棱两可的 & 符号。下面还描述了 其他限制。
外部元素 其开始标签标记为自闭合的,不能有任何内容(因为,同样,由于没有结束标签,所以无法在开始标签和结束标签之间放置内容)。外部元素 其开始标签未标记为自闭合的,可以包含 文本、字符引用、CDATA 节、其他 元素 和 注释,但文本不得包含字符 U+003C 小于号 (<) 或 模棱两可的 & 符号。
HTML 语法不支持命名空间声明,即使在 外部元素 中也不支持。
例如,考虑以下 HTML 片段
< p >
< svg >
< metadata >
<!-- this is invalid -->
< cdr:license xmlns:cdr = "https://www.example.com/cdr/metadata" name = "MIT" />
</ metadata >
</ svg >
</ p >
最里面的元素 cdr:license
实际上位于 SVG 命名空间中,因为“xmlns:cdr
”属性无效(与 XML 中不同)。事实上,如上文片段中的注释所说,该片段实际上不符合规范。这是因为 SVG 2 没有在 SVG 命名空间中定义任何名为“cdr:license
”的元素。
普通元素 可以包含 文本、字符引用、其他 元素 和 注释,但文本不得包含字符 U+003C 小于号 (<) 或 模棱两可的 & 符号。一些 普通元素 对其允许包含的内容还有 更多限制,这超出了内容模型强加的限制以及本段中描述的限制。这些限制将在下面描述。
标签包含一个 标签名称,给出元素的名称。所有 HTML 元素的名称仅使用 ASCII 字母数字字符。在 HTML 语法中,标签名称,即使是 外部元素 的标签名称,也可以使用任何大小写字母组合来编写,当转换为全小写时,与元素的标签名称匹配;标签名称不区分大小写。
开始标签 必须具有以下格式
结束标签 必须具有以下格式
属性 用于元素,在元素的开始标签内表达。
属性具有名称和值。属性名称 必须由一个或多个字符组成,这些字符不包括 控制字符、U+0020 空格、U+0022 (")、U+0027 (')、U+003E (>)、U+002F (/)、U+003D (=) 和 非字符。在 HTML 语法中,属性名称,即使是 外部元素 的属性名称,也可以使用任何 ASCII 小写 和 ASCII 大写字母 的组合来编写。
属性值 是 文本 和 字符引用 的混合,但附加限制是文本不能包含 模棱两可的 & 符号。
属性可以通过四种不同的方式指定
仅 属性名称。该值隐式为空字符串。
在以下示例中,disabled
属性使用空属性语法给出
< input disabled >
如果使用空属性语法的属性后面要跟另一个属性,则必须有 ASCII 空格 分隔这两个属性。
属性名称,后跟零个或多个 ASCII 空格,后跟单个 U+003D 等号字符,后跟零个或多个 ASCII 空格,后跟 属性值,该属性值除了上面为属性值给出的要求外,还必须不包含任何文字 ASCII 空格、任何 U+0022 双引号字符 (")、U+0027 单引号字符 (')、U+003D 等号字符 (=)、U+003C 小于号字符 (<)、U+003E 大于号字符 (>) 或 U+0060 反引号字符 (`),并且不能为空字符串。
在以下示例中,value
属性使用未加引号的属性值语法给出
< input value = yes >
如果使用未加引号的属性值语法的属性后面要跟另一个属性或上面 开始标签 语法第 6 步中允许的可选 U+002F 斜杠字符 (/),则必须有 ASCII 空格 分隔这两个属性。
属性名称,后跟零个或多个 ASCII 空格,后跟单个 U+003D 等号字符,后跟零个或多个 ASCII 空格,后跟单个 U+0027 单引号字符 ('),后跟 属性值,该属性值除了上面为属性值给出的要求外,还必须不包含任何文字 U+0027 单引号字符 ('),最后再跟单个 U+0027 单引号字符 (')。
在以下示例中,type
属性使用单引号属性值语法给出
< input type = 'checkbox' >
如果使用单引号属性值语法的属性后面要跟另一个属性,则必须有 ASCII 空格 分隔这两个属性。
属性名称,后跟零个或多个 ASCII 空格,后跟单个 U+003D 等号字符,后跟零个或多个 ASCII 空格,后跟单个 U+0022 双引号字符 ("),后跟 属性值,该属性值除了上面为属性值给出的要求外,还必须不包含任何文字 U+0022 双引号字符 ("),最后再跟单个 U+0022 双引号字符 (")。
在以下示例中,name
属性使用双引号属性值语法给出
< input name = "be evil" >
如果使用双引号属性值语法的属性后面要跟另一个属性,则必须有 ASCII 空格 分隔这两个属性。
同一开始标签上绝不能有两个或多个属性,其名称在 ASCII 不区分大小写 方面相互匹配。
当 外部元素 具有以下表格中某一行的第一列和第二列的本地名称和命名空间给出的命名空间属性之一时,必须使用该行第三列给出的名称来编写。
本地名称 | 命名空间 | 属性名称 |
---|---|---|
actuate | XLink 命名空间 | xlink:actuate
|
arcrole | XLink 命名空间 | xlink:arcrole
|
href | XLink 命名空间 | xlink:href
|
role | XLink 命名空间 | xlink:role
|
show | XLink 命名空间 | xlink:show
|
title | XLink 命名空间 | xlink:title
|
type | XLink 命名空间 | xlink:type
|
lang | XML 命名空间 | xml:lang
|
space | XML 命名空间 | xml:space
|
xmlns | XMLNS 命名空间 | xmlns
|
xlink | XMLNS 命名空间 | xmlns:xlink
|
在 HTML 语法 中不能表达其他命名空间属性。
上表中属性是否符合规范由其他规范定义(例如 SVG 2 和 MathML);本节仅描述如果使用 HTML 语法序列化属性的语法规则。
某些标签可以 省略。
在下面描述的情况下省略元素的 开始标签 并不意味着该元素不存在;它是隐含的,但仍然存在。例如,HTML 文档始终具有根 html
元素,即使字符串 <html>
在标记中任何地方都没有出现。
如果 html
元素内部的第一个内容不是 注释,则可以省略 html
元素的 开始标签。
例如,在以下情况下,删除“<html>
”标签是可以的
<!DOCTYPE HTML>
< html >
< head >
< title > Hello</ title >
</ head >
< body >
< p > Welcome to this example.</ p >
</ body >
</ html >
这样做会使文档看起来像这样
<!DOCTYPE HTML>
< head >
< title > Hello</ title >
</ head >
< body >
< p > Welcome to this example.</ p >
</ body >
</ html >
这具有完全相同的 DOM。特别要注意,解析器会忽略 文档元素 周围的空格。以下示例也将具有完全相同的 DOM
<!DOCTYPE HTML> < head >
< title > Hello</ title >
</ head >
< body >
< p > Welcome to this example.</ p >
</ body >
</ html >
但是,在以下示例中,删除开始标签会将注释移动到 html
元素之前
<!DOCTYPE HTML>
< html >
<!-- where is this comment in the DOM? -->
< head >
< title > Hello</ title >
</ head >
< body >
< p > Welcome to this example.</ p >
</ body >
</ html >
删除标签后,文档实际上会变成与以下内容相同的内容
<!DOCTYPE HTML>
<!-- where is this comment in the DOM? -->
< html >
< head >
< title > Hello</ title >
</ head >
< body >
< p > Welcome to this example.</ p >
</ body >
</ html >
这就是为什么只有在标签后面没有注释时才能删除标签:当存在注释时删除标签会更改文档的最终解析树。当然,如果注释的位置无关紧要,则可以省略标签,就好像注释已首先移动到开始标签之前一样。
如果 html
元素后面没有紧跟着 注释,则可以省略 html
元素的 结束标签。
如果元素为空或 head
元素内部的第一个内容是元素,则可以省略 head
元素的 开始标签。
如果 head
元素后面没有紧跟着 ASCII 空格 或 注释,则可以省略 head
元素的 结束标签。
如果元素为空,或者 body
元素内部的第一个内容不是 ASCII 空格 或 注释,则可以省略 body
元素的 开始标签,但如果 body
元素内部的第一个内容是 meta
、noscript
、link
、script
、style
或 template
元素,则除外。
如果 body
元素后面没有紧跟着 注释,则可以省略 body
元素的 结束标签。
请注意,在上面的示例中,head
元素的开始和结束标签以及 body
元素的开始标签不能省略,因为它们周围有空格
<!DOCTYPE HTML>
< html >
< head >
< title > Hello</ title >
</ head >
< body >
< p > Welcome to this example.</ p >
</ body >
</ html >
(body
和 html
元素的结束标签可以毫无问题地省略;这些标签后面的任何空格都会被解析到 body
元素中。)
但是,通常情况下,空格不是问题。如果我们首先删除我们不关心的空格
<!DOCTYPE HTML> < html >< head >< title > Hello</ title ></ head >< body >< p > Welcome to this example.</ p ></ body ></ html >
然后我们可以省略一些标签而不会影响 DOM
<!DOCTYPE HTML> < title > Hello</ title >< p > Welcome to this example.</ p >
此时,我们还可以添加一些空格
<!DOCTYPE HTML>
< title > Hello</ title >
< p > Welcome to this example.</ p >
这将等同于此文档,省略的标签显示在其解析器隐含的位置;由此产生的唯一空格文本节点是 head
元素末尾的新行
<!DOCTYPE HTML>
< html >< head > < title > Hello</ title >
</ head >< body > < p > Welcome to this example.</ p > </ body ></ html >
如果 li
元素后面紧跟着另一个 li
元素,或者父元素中没有更多内容,则可以省略 li
元素的 结束标签。
如果 dt
元素后面紧跟着另一个 dt
元素或 dd
元素,则可以省略 dt
元素的 结束标签。
如果 dd
元素后面紧跟着另一个 dd
元素或 dt
元素,或者父元素中没有更多内容,则可以省略 dd
元素的 结束标签。
如果 p
元素后面紧跟着 address
、article
、aside
、blockquote
、details
、dialog
、div
、dl
、fieldset
、figcaption
、figure
、footer
、form
、h1
、h2
、h3
、h4
、h5
、h6
、header
、hgroup
、hr
、main
、menu
、nav
、ol
、p
、pre
、search
、section
、table
或 ul
元素,或者父元素中没有更多内容并且父元素是 HTML 元素(不是 a
、audio
、del
、ins
、map
、noscript
或 video
元素),或者是一个 自主自定义元素,则可以省略 p
元素的 结束标签。
因此,我们可以进一步简化前面的示例
<!DOCTYPE HTML> < title > Hello</ title >< p > Welcome to this example.
如果 rt
元素后面紧跟着 rt
或 rp
元素,或者父元素中没有更多内容,则可以省略 rt
元素的 结束标签。
如果 rp
元素后面紧跟着 rt
或 rp
元素,或者父元素中没有更多内容,则可以省略 rp
元素的 结束标签。
如果 optgroup
元素后面紧跟着另一个 optgroup
元素,或者后面紧跟着 hr
元素,或者父元素中没有更多内容,则可以省略 optgroup
元素的 结束标签。
如果 option
元素后面紧跟着另一个 option
元素,或者后面紧跟着 optgroup
元素,或者后面紧跟着 hr
元素,或者父元素中没有更多内容,则可以省略 option
元素的 结束标签。
colgroup
元素的 开始标签 可以省略,前提是 colgroup
元素内部的第一项是 col
元素,并且该元素前面没有紧跟着另一个 colgroup
元素,且该元素的 结束标签 被省略。(如果该元素为空,则不能省略。)
colgroup
元素的 结束标签 可以省略,前提是 colgroup
元素后面没有紧跟着 ASCII 空格 或 注释。
caption
元素的 结束标签 可以省略,前提是 caption
元素后面没有紧跟着 ASCII 空格 或 注释。
thead
元素的 结束标签 可以省略,前提是 thead
元素后面紧跟着 tbody
或 tfoot
元素。
tbody
元素的 开始标签 可以省略,前提是 tbody
元素内部的第一项是 tr
元素,并且该元素前面没有紧跟着 tbody
、thead
或 tfoot
元素,且它们的 结束标签 被省略。(如果该元素为空,则不能省略。)
tbody
元素的 结束标签 可以省略,前提是 tbody
元素后面紧跟着 tbody
或 tfoot
元素,或者父元素中没有更多内容。
tfoot
元素的 结束标签 可以省略,前提是父元素中没有更多内容。
tr
元素的 结束标签 可以省略,前提是 tr
元素后面紧跟着另一个 tr
元素,或者父元素中没有更多内容。
td
元素的 结束标签 可以省略,前提是 td
元素后面紧跟着 td
或 th
元素,或者父元素中没有更多内容。
th
元素的 结束标签 可以省略,前提是 th
元素后面紧跟着 td
或 th
元素,或者父元素中没有更多内容。
省略所有这些与表格相关的标签的能力使表格标记更加简洁。
以这个例子为例
< table >
< caption > 37547 TEE Electric Powered Rail Car Train Functions (Abbreviated)</ caption >
< colgroup >< col >< col >< col ></ colgroup >
< thead >
< tr >
< th > Function</ th >
< th > Control Unit</ th >
< th > Central Station</ th >
</ tr >
</ thead >
< tbody >
< tr >
< td > Headlights</ td >
< td > ✔</ td >
< td > ✔</ td >
</ tr >
< tr >
< td > Interior Lights</ td >
< td > ✔</ td >
< td > ✔</ td >
</ tr >
< tr >
< td > Electric locomotive operating sounds</ td >
< td > ✔</ td >
< td > ✔</ td >
</ tr >
< tr >
< td > Engineer's cab lighting</ td >
< td ></ td >
< td > ✔</ td >
</ tr >
< tr >
< td > Station Announcements - Swiss</ td >
< td ></ td >
< td > ✔</ td >
</ tr >
</ tbody >
</ table >
除了某些空格差异外,完全相同的表格可以用以下方式标记:
< table >
< caption > 37547 TEE Electric Powered Rail Car Train Functions (Abbreviated)
< colgroup >< col >< col >< col >
< thead >
< tr >
< th > Function
< th > Control Unit
< th > Central Station
< tbody >
< tr >
< td > Headlights
< td > ✔
< td > ✔
< tr >
< td > Interior Lights
< td > ✔
< td > ✔
< tr >
< td > Electric locomotive operating sounds
< td > ✔
< td > ✔
< tr >
< td > Engineer's cab lighting
< td >
< td > ✔
< tr >
< td > Station Announcements - Swiss
< td >
< td > ✔
</ table >
由于单元格以这种方式占据的空间要少得多,因此可以通过将每一行放在一行上使其更加简洁
< table >
< caption > 37547 TEE Electric Powered Rail Car Train Functions (Abbreviated)
< colgroup >< col >< col >< col >
< thead >
< tr > < th > Function < th > Control Unit < th > Central Station
< tbody >
< tr > < td > Headlights < td > ✔ < td > ✔
< tr > < td > Interior Lights < td > ✔ < td > ✔
< tr > < td > Electric locomotive operating sounds < td > ✔ < td > ✔
< tr > < td > Engineer's cab lighting < td > < td > ✔
< tr > < td > Station Announcements - Swiss < td > < td > ✔
</ table >
在 DOM 级别,这些表格之间的唯一区别在于(无论如何在语义上都是中性的)空格的确切位置。
但是,如果 开始标签 具有任何属性,则绝不能省略。
回到前面那个所有空格都被移除,然后所有可选标签都被移除的例子
<!DOCTYPE HTML> < title > Hello</ title >< p > Welcome to this example.
如果此示例中的 body
元素必须具有 class
属性,并且 html
元素必须具有 lang
属性,则标记必须变为
<!DOCTYPE HTML> < html lang = "en" >< title > Hello</ title >< body class = "demo" >< p > Welcome to this example.
本节假设文档符合规范,特别是没有违反 内容模型。在不符合本规范中描述的 内容模型 的文档中以本节中描述的方式省略标签可能会导致意外的 DOM 差异(这部分是内容模型的设计目的)。
出于历史原因,某些元素除了其内容模型给出的限制之外,还具有额外的限制。
table
元素不能包含 tr
元素,即使根据本规范中描述的内容模型,这些元素在技术上允许在 table
元素内部。(如果在标记中将 tr
元素放在 table
内部,实际上会在其前面隐含一个 tbody
开始标签。)
可以在 pre
和 textarea
元素的 开始标签 后面紧跟着放置一个 换行符。这不会影响元素的处理。如果元素的内容本身以 换行符 开头,则必须包含否则可选的 换行符(因为否则内容中的前导换行符将被视为可选换行符并被忽略)。
原始文本 和 可转义原始文本元素 中的文本不得包含任何“</
”(U+003C 小于号,U+002F 斜杠)字符串,后跟与元素的标签名称不区分大小写匹配的字符,然后是 U+0009 字符制表符(制表符)、U+000A 换行符 (LF)、U+000C 换页符 (FF)、U+000D 回车符 (CR)、U+0020 空格、U+003E 大于号 (>) 或 U+002F 斜杠 (/) 之一。
元素、属性值和注释内部允许使用 文本。根据文本要放置的位置,对文本中允许和不允许的内容施加了额外的约束,如其他部分所述。
HTML 中的 换行符 可以表示为 U+000D 回车符 (CR) 字符、U+000A 换行符 (LF) 字符,或者按此顺序排列的 U+000D 回车符 (CR)、U+000A 换行符 (LF) 字符对。
在允许使用 字符引用 的地方,U+000A 换行符 (LF) 字符(但不是 U+000D 回车符 (CR) 字符)的字符引用也表示 换行符。
在其他部分描述的某些情况下,文本 可以与 字符引用 混合使用。这些可用于转义在 文本 中原本无法合法包含的字符。
字符引用必须以 U+0026 和号 (&) 字符开头。在此之后,有三种可能的字符引用类型
上面描述的数字字符引用形式允许引用任何代码点,但不包括 U+000D CR、非字符 和 控制字符(ASCII 空格 除外)。
模棱两可的和号 是一个 U+0026 和号 (&) 字符,后跟一个或多个 ASCII 字母数字,后跟 U+003B 分号 (;) 字符,其中这些字符与 命名字符引用 部分中给出的任何名称都不匹配。
CDATA 部分 必须包含以下组件,按此顺序
<![CDATA[
”。]]>
”。]]>
”。CDATA 部分只能用于外部内容(MathML 或 SVG)。在此示例中,CDATA 部分用于转义 MathML ms
元素的内容
< p > You can add a string to a number, but this stringifies the number:</ p >
< math >
< ms > <![CDATA[x<y]]> </ ms >
< mo > +</ mo >
< mn > 3</ mn >
< mo > =</ mo >
< ms > <![CDATA[x<y3]]> </ ms >
</ math >
注释 必须具有以下格式
<!--
”。>
”开头,也不能以字符串“->
”开头,并且不能包含字符串“<!--
”、“-->
”或“--!>
”,也不能以字符串“<!-
”结尾。-->
”。文本允许以字符串“<!
”结尾,例如 <!--My favorite operators are > and <!-->
。