浏览器向上拆分<p>和包含嵌套<p>块的嵌套<代码>块。为什么?

2022-03-22 00:00:00 html-parsing browser html

您可以在this jsFiddle中查看我的问题。

我尝试使用code标记来区分特殊内容,但这很快就适得其反(正如您在上面的链接中看到的那样)。当我使用Firebug查看内容时,如下所示:

<p>
    This is a sample paragraph with a code block:
    <code>
        <p> Some line of code </p>
        <p> Another line of code </p>
    </code>
</p>

已变成这样:

<p>
    This is a sample paragraph with a code block:
    <code> </code>
</p>
<p>
    <code> Some line of code </code>
</p>
<code>
    <p> Another line of code </p>
</code>

现在,可以通过将<code>更改为<div class="code">(如this jsFiddle所示)来解决此问题,但是浏览器最初为什么要这样做,为什么它只对每个段落的第一部分这样做?

Firefox、Opera、Chrome、Internet Explorer、Safari--它们都这样做,但我真的想知道为什么。它只在code中发生,还是会在其他标记中发生?为什么浏览器要那样移动标签呢?

HTML

推荐答案对哪些元素可以嵌套在哪些其他元素中进行了某些限制。有时,浏览器会乐于从某些嵌套场景中构造一个无意义的DOM,例如直接在<ul>中使用<div>。其他时候,由于其他编写或不编写的解析规则,它们绝对不能这样做,例如<p>元素从不包含任何其他挡路元素,甚至不包含其他<p>元素(这是implied by the spec),因此它们必须通过将DOM更改为它们可以使用的内容来解决这个问题,从而导致您观察到的行为。

因为您根本不能将<p>个元素嵌套在另一个元素中,所以这里发生的情况是该元素:

    <p> Some line of code </p>

正在导致此其他元素被终止:

<p>
    This is a sample paragraph with a code block:
    <code>

由于其中有一个空的<code>标记,因此它已关闭,包含<p><p>也已关闭,因为随后的<p>开始标记将自动关闭前面的<p>开始标记:

<p>
    This is a sample paragraph with a code block:
    <code> </code>
</p>
在这一点上,浏览器必须处理这样一个事实,即<code><p>标记现在的顺序实际上是错误的,但仍然嵌套。为了补偿第一个"out"<p>元素的重构,以及在第二个"Internal"<p>之前将有一个<code>标记的事实,它将<code>标记插入到第二个<p>元素中,将其内容转换为代码:

<p>
    <code> Some line of code </code>
</p>

由于浏览器似乎确实出于某种原因允许<p><code>内(请注意,此时<code>仍未以</code>显式终止),因此浏览器将按如下方式构建DOM的睡觉,然后继续运行:

<code>
    <p> Another line of code </p>
</code>
出于遗留和跨浏览器兼容性的原因,这在不同浏览器之间可能是一致的;其中一些遗留解析规则也已经retconned into sections of the HTML5 spec。不幸的是,我不是浏览器实现者,所以我不能列出所有可能的场景;另一方面,考虑到您正在编写的标记从一开始就是无效的,依赖这样的细节是不明智的。

,最后,today's highly relevant xkcd(当然):

相关文章