写HEAD、BODY和HTML标签是必要的吗?

234

需要编写 <html><head><body> 标记吗?

例如,我可以制作这样的页面:

<!DOCTYPE html>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>Page Title</title>
    <link rel="stylesheet" type="text/css" href="css/reset.css">
    <script src="js/head_script.js"></script><!-- this script will be in head //-->


<div>Some html</div> <!-- here body starts //-->

    <script src="js/body_script.js"></script>

而且Firebug可以正确分离头部和正文:

在此输入图片描述

W3C验证器显示这是合法的。

但我很少在网上看到这种做法。

写这些标记的原因是什么?


9
HTML5 验证器(https://html5.validator.nu/)需要 title 标签。这是它认为有效的最小文档:<!DOCTYPE html><title>A</title> - bonh
1
@bonh 这是它认为完全有效的最小文档(没有错误或警告):<!DOCTYPE html><html lang=""><title>x</title> - Géry Ogam
6个回答

174

省略 htmlheadbody 标签 符合 HTML 规范。其背后的原因是浏览器一直试图与现有的网页保持一致,而最早版本的 HTML 没有定义这些元素。当 HTML 第一次定义这些元素时,标签会在缺失时被推断出来。

在原型设计和编写测试用例时,我经常将标签省略掉,这有助于让标记集中于所需的测试上。推断过程应该以 Firebug 中所看到的方式创建元素,并且浏览器执行此操作非常一致。

但是……

Internet Explorer 在这个领域至少有一个已知的 bug。甚至Internet Explorer 9 也存在此问题。假设标记如下:

<!DOCTYPE html>
<title>Test case</title>
<form action='#'>
   <input name="var1">
</form>

你应该(在其他浏览器中也是如此)得到一个看起来像这样的DOM

HTML
    HEAD
        TITLE
    BODY
        FORM action="#"
            INPUT name="var1"

但在Internet Explorer中,您会得到以下结果:

HTML
    HEAD
       TITLE
       FORM action="#"
           BODY
               INPUT name="var1"
    BODY

点击查看

这个 bug 只会在 form 开始标签之前有任何文本内容和 body 开始标签的情况下出现。


9
HTML 1.0定义了HTML、HEAD和BODY:http://www.w3.org/MarkUp/draft-ietf-iiir-html-01.txt - Liza Daly
7
@Liza - 争论的焦点在于是否该文件定义了 HTML 1.0,但我认为我需要更正的是,这些元素早于 HTML 2.0。谢谢您指出来。然而,请参阅1992年http://www.w3.org/History/19921103-hypertext/hypertext/WWW/MarkUp/Tags.html。那时这些元素并不存在。 - Alohci
1
这个 bug 似乎不会影响到 Internet Explorer 11(我也测试了 IE8,确认它受到了影响)。 - jornane
3
@Justin - 这些限制大多是技术性的,通常不会影响您。因此,如果一个注释节点或空格出现在head元素之前或之内对您的页面很重要(页面的JS 可能依赖于它),那么您必须明确标识head开始标记以使该关系正确。但是,如果没有(我从未编写过一个HTML页面,其中它确实存在),则head标记将被推断到某个合理的位置,并且您可以安全地省略它。其他html、head和body标记也是如此。 - Alohci
4
@Justin,这个回答似乎与问题“是否需要编写HEAD、BODY和HTML标签?”有很大的关联,而不是是否做到最佳实践。约定惯例往往会发生变化...只需看看Google样式指南...这是一种规范,规定应该忽略这些标签... :-) - Potherca
显示剩余4条评论

99

谷歌 HTML 样式指南建议省略所有可选标签,包括 <html><head><body><p><li>

根据 3.1.7 可选标签

出于文件大小优化和扫描性能考虑,请考虑省略可选标签。HTML5 规范定义了哪些标签可以省略。

(该做法可能需要一个过渡期来作为更广泛的指南,因为它与通常教给网页开发人员的方法有很大不同。出于一致性和简单性的原因,最好省略所有可选标签,而不仅仅是选择性地省略。)

<!-- Not recommended -->
<!DOCTYPE html>
<html>
  <head>
    <title>Spending money, spending bytes</title>
  </head>
  <body>
    <p>Sic.</p>
  </body>
</html>

<!-- Recommended -->
<!DOCTYPE html>
<title>Saving money, saving bytes</title>
<p>Qed.
抱歉,我只能使用英文进行语言沟通。

3
不兼容性示例:我在网站开发中使用的实时重载工具(puer)会自动在<head>标签中插入一个脚本。如果没有至少<head>标签,它将无法正常工作。 - Offirmo
1
@Offirmo 这是什么鬼? - Ken Sharp
1
@KenSharp livereload 网页开发工具通常通过在服务的页面中插入一些代码来工作,例如:<script src="http://localhost:35729/livereload.js"></script>。对于奇特的模板,它们不知道应该在哪里插入它们的代码。 - Offirmo
20
省略所有可能的标记是小节省,大损失。带宽的节约很少(特别是因为大多数连接自动压缩),而边缘情况下出现人为错误的可能性很高(考虑作者、编辑甚至HTML解析器编写者)。此外,发现错误也更难(因为熵的变化)。 - TextGeek
2
有趣的是,goiogle.com违反了Google样式指南,因为它包含<html>。 - Frank Buss
显示剩余6条评论

53
Liza Daly的笔记相反,HTML5规范实际上非常明确地说明了哪些标签可以省略,何时可以省略(规则与HTML 4.01有所不同,主要是为了澄清注释和空格等含糊不清的元素所属位置)。
相关参考文献是8.1.2.4可选标签,它说:
  • 如果 html 元素内部的第一个元素不是注释,则可以省略该元素的开始标签。

  • 如果 html 元素后面紧跟着的不是注释,则可以省略该元素的结束标签。

  • 如果 head 元素为空,或者 head 元素内部的第一个元素是一个元素,则可以省略该元素的开始标签。

  • 如果 head 元素后面紧跟着的不是空格字符或注释,则可以省略该元素的结束标签。

  • 如果 body 元素为空,或者 body 元素内部的第一个元素不是空格字符或注释(除非第一个元素是脚本或样式元素),则可以省略该元素的开始标签。

  • 如果 body 元素后面紧跟着的不是注释,则可以省略该元素的结束标签。

所以你的示例是有效的HTML5,将被解析为以下形式,其中htmlheadbody标签处于其隐含位置:

<!DOCTYPE html><HTML><HEAD>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>Page Title</title>
    <link rel="stylesheet" type="text/css" href="css/reset.css">
    <script src="js/head_script.js"></script></HEAD><BODY><!-- this script will be in head //-->


<div>Some HTML content</div> <!-- here body starts //-->

    <script src="js/body_script.js"></script></BODY></HTML>

请注意,“此脚本将位于中”这个注释实际上被解析为的一部分,尽管脚本本身是的一部分。根据规范,如果您希望有所不同,则不能省略</HEAD><BODY>标记。(虽然相应的<HEAD></BODY>标记仍然可以省略。)

20

HTML规范确实允许在某些情况下省略某些标签,但通常这样做是不明智的。

这会产生两个影响-它使规范更加复杂,进而使得浏览器作者编写正确的实现更加困难(正如Internet Explorer所示)。

这使得出现浏览器错误的可能性在这些规范部分中很高。作为网站作者,您可以通过包含这些标签来避免问题-因此,虽然规范没有要求您这样做,但这样做会减少事情出错的机会,这是良好的工程实践。

此外,最新的HTML 5.1 WG规范目前表示(请注意,这是一项正在进行中的工作,可能尚未更改)。

如果元素为空或元素内的第一项不是空格字符或注释,则可以省略元素的起始标签,除非元素内的第一项是meta、link、script、style或template元素。

来自4.3.1 body元素

这有点微妙。您可以省略bodyhead,浏览器将推断应将这些元素插入到哪里。这带来了不明确的风险,可能会引起混淆。

所以这样做

<html>
  <h1>hello</h1>
  <script ... >
  ...

在脚本元素中使用此结果将使脚本元素成为元素的子元素,但这样做会让内容更加通俗易懂。请保留HTML标签。
<html>
  <script ... >
  <h1>hello</h1>

这会使得脚本标签成为head元素的子元素。

您可以通过以下方式更加明确:

<html>
    <body>
      <script ... >
      <h1>hello</h1>

然后,无论您先有脚本还是h1,它们都会可预测地出现在body元素中。这些是在重构和调试代码时容易忽视的事情(例如,您有一个JavaScript正在查找body中的第一个脚本元素-在第二个代码片段中,它将停止工作)。
一般规则是,明确事物总是比将事物留给解释更好。在这方面,XHTML更好,因为它强制您在代码中完全明确元素结构,使其更简单,因此不太容易被误解。
因此,是的,您可以省略它们并且在技术上有效,但通常不明智这样做。

2
IE之所以出现问题,是因为作者根本不关心标准。如果它不能正常工作,那就是他们的错。标准已经定义好了,他们应该确保IE与这些标准兼容。 - Ken Sharp
3
@KenSharp 我不反对你的想法,但在你能强制所有客户都不使用它之前,我们还是得使用它。因此最好编写完全明确的代码,而不是依赖一切正常运行。 - Peter Bagnall
1
用户由于IE不合规范而被迫放弃多年。即使人们仍在安装Windows XP,也没有人指望用户继续使用IE6。我们也不能永远支持Windows 3.1。OSI第8层错误。 - Ken Sharp
1
可以省略哪些标签以及在哪里省略,这也因HTML版本而异。这似乎是避免使用它们的一个很好的理由(除了最明显、最常见和最一致的情况)。 - TextGeek
@TextGeek <!DOCTYPE html> - Det

16

在HTML 4中,省略它们是有效的:

7.3 HTML元素
起始标签:可选,结束标签:可选

7.4.1 HEAD元素
起始标签:可选,结束标签:可选

摘自 7 HTML文档的全局结构.

在HTML5中,没有“必需”或“可选”元素,因为HTML5语法定义更为宽松。例如,title元素:

大多数情况下,title元素是必需的子元素,但当更高级别的协议提供标题信息时,例如在使用HTML作为电子邮件创作格式时,在电子邮件的主题行中,可以省略title元素。

摘自 4.2.2 title元素.

在真正的XHTML5中,省略它们是无效的,尽管这几乎从不使用(与像HTML5一样表现的XHTML相比)。

然而,从实际角度考虑,您经常希望浏览器以“标准模式”运行,以便在呈现HTML和CSS时具有可预测性。提供DOCTYPE和更结构化的HTML树将保证更可预测的跨浏览器结果。


16
不要混淆元素和标签。请查看本页其他地方cHao的评论。对于htmlheadbody,元素是必须的,但标签是可选的。 - Alohci
实际上,在最后一部分,你是错误的。标签省略是 SGML DTD 功能,所有支持 SGML 解析的浏览器(也就是所有浏览器)都支持标签省略。你不能在 XHTML5 中这样做的原因是它是 XML,而不是 SGML。XML 太愚蠢了,无法推断元素。 - OdraEncoded
@OdraEncoded,您能提供一下您的说法的验证吗?我在HTML标准中没有找到相关内容。 - Toothbrush
@OdraEncoded -- 关闭,但不完全正确。标签省略是SGML解析器的可选功能(尽管大多数支持它),如ISO 8879所定义。几乎所有HTML解析器都支持它,尽管Python的'html.parse'似乎不支持(请参见https://dev59.com/GYrda4cB1Zd3GeqPKk41#30083678)。 - TextGeek
1
@OdraEncoded 关于“XML太笨以至于无法推断元素”的问题——当深度魔法被编写时,这是一个有意的设计选择,部分原因是为了让浏览器供应商停止将数百个开发人员年份投入到尝试在恢复错误的HTML方面互相竞争。对于XML,只有一个关于标记省略的规则:“不要”。这很容易理解、测试、生成和正确解析。也许这算是“愚蠢”,但我不这么认为。 - TextGeek

-5

Firebug 正确显示了这个问题,因为你的 浏览器 自动修复了错误的标记。这种行为没有在任何地方指定,并且可能会因浏览器而异。这些标记是 DOCTYPE 所需的,不应省略。

HTML 元素 是每个 HTML 页面的根元素。如果你查看所有其他元素的描述,它会说明一个元素可以在哪里使用(几乎所有元素都需要 headbody)。


6
换句话说,这是一种糟糕的做法,会产生未定义的结果。 - Randy
3
仅仅因为某件事很大,并不意味着它构建得很好。 - Demian Brecht
3
作为一种权威引用,我发现这并不令人信服。google.com也是无效的HTML,但这并不意味着你的网站也应该是如此。 - Rein Henrichs
17
元素必须存在,但并非必须使用标签。实际上,没有html/head/body标签的HTML代码是有效的,只要没有元素出现在不应该出现的位置(例如,在<p></p>之后放置<title>)。 - cHao
1
HTML5规范中确实指定了HTML解析行为,因此不会因浏览器而异。 - Marijn
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接