为什么带有换行符的 PRE 元素不会在输出中产生空行?

Lon*_*ner 5 html whitespace w3c newline

实施例1

pre {
  background: lightblue;
}
Run Code Online (Sandbox Code Playgroud)
<pre>
<code>
foo
</code>
</pre>
Run Code Online (Sandbox Code Playgroud)

上方和下方出现空白行foo。这是预期的,因为 PRE 元素中有换行符。

实施例2

pre {
  background: lightblue;
}
Run Code Online (Sandbox Code Playgroud)
<pre><code>
foo
</code></pre>
Run Code Online (Sandbox Code Playgroud)

上方出现空白行foo,但下方不出现。为什么?

实施例3

pre {
  background: lightblue;
}
Run Code Online (Sandbox Code Playgroud)
<pre><code>foo</code></pre>
Run Code Online (Sandbox Code Playgroud)

前后不再有空行,foo因为 HTML 代码中没有换行符。

实施例4

pre {
  background: lightblue;
}
Run Code Online (Sandbox Code Playgroud)
<pre>
<code>foo</code>
</pre>
Run Code Online (Sandbox Code Playgroud)

<pre>之后和之前都有换行符</pre>foo所以我期待输出中前后有空行。为什么这个例子中没有空行?

问题

  1. 为什么示例2中只出现一个空行?
  2. 为什么示例 4 的输出中没有空行?

Alo*_*hci 7

示例 1 与示例 4 有相似之处。我会回过头来讨论这一点...

示例2和示例3是基本情况。在示例 2 中,忽略code标签,您有pre开始标签、创建空行的新行字符、“foo”、结束该行的新行字符,然后是结束标签pre。请注意,结束标记之前的一个空格足以在“foo”行下创建一个空行。

示例 3 根本不包含新行。但pre默认情况下,它是一个块级元素,因此“foo”无论如何都会出现在它自己的一行上。对此没什么好说的。

示例 4 与示例 2 类似,只是代码标记已移动行。这暴露了 HTML 解析器的一个特殊的奇怪之处。HTML 解析算法表示

↪ 标签名称为以下之一的开始标签:“pre”、“listing”

如果打开元素的堆栈在按钮范围内有 ap 元素,则关闭 ap 元素。

插入令牌的 HTML 元素。

如果下一个标记是 U+000A 换行 (LF) 字符标记,则忽略该标记并继续处理下一个标记。(为方便创作,前块开头的换行符将被忽略。)

将frameset-ok 标志设置为“not ok”。

因此,紧跟在开始标记后面的初始换行符pre会掉在地板上,并且“foo”行之前没有空行。而在示例 2 中,code开始标记是紧跟在开始标记之后的标记pre,导致后面的换行符不会被忽略。

实施例1同样如此。开始标记后面的初始新行将pre被忽略,'code 结束标记后面的新行将start tag creates a blank line, then the foo line and its new line character, then the new line following the 'code在“foo”行下方创建一个空行,然后pre元素结束。