【问题标题】:Browser splits up <p> and nested <code> blocks that contain nested <p> blocks. Why?浏览器将 <p> 和包含嵌套 <p> 块的嵌套 <code> 块分开。为什么?
【发布时间】:2012-11-25 07:14:59
【问题描述】:

你可以在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>

现在,这可以通过将&lt;code&gt; 更改为&lt;div class="code"&gt; 来解决(如this jsFiddle 所示),但是为什么浏览器首先会这样做,为什么会这样做到每个段落的第一部分?

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

【问题讨论】:

  • 不管怎样,如果你想格式化代码块,每个代码块使用&lt;pre&gt;&lt;code&gt;...&lt;/code&gt;&lt;/pre&gt;

标签: html browser html-parsing


【解决方案1】:

HTML 对哪些元素可以嵌套在哪些其他元素中设置了某些限制。有时浏览器会很乐意从某些嵌套场景中构造一个无意义的 DOM,例如直接在 &lt;ul&gt; 中的 &lt;div&gt;。其他时候,他们绝对不能因为其他书面或不成文的解析规则,例如&lt;p&gt;元素从不包含任何其他块元素,甚至不包含其他&lt;p&gt;元素(这是implied by the spec),所以他们必须工作通过将 DOM 更改为他们可以使用的东西来解决它,从而产生您观察到的行为。

因为您根本无法将 &lt;p&gt; 元素嵌套在另一个元素中,所以这里发生的是这个元素:

    <p> Some line of code </p>

导致这个其他元素被终止:

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

因为里面有一个空的&lt;code&gt;标签,它被关闭了,包含&lt;p&gt;的标签也被关闭了,因为后面的&lt;p&gt;开始标签会自动关闭前面的&lt;p&gt;开始标签:

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

此时,浏览器必须处理&lt;code&gt;&lt;p&gt; 标签现在实际上处于错误顺序但仍然嵌套的事实。为了补偿第一个“外部”&lt;p&gt; 元素的重组,以及在第二个“内部”&lt;p&gt; 之前会有一个&lt;code&gt; 标签的事实,它将&lt;code&gt; 标签插入到第二个@ 987654345@,将其内容转化为代码:

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

由于浏览器似乎确实允许在 &lt;code&gt; 中包含 &lt;p&gt;,无论出于何种原因(请注意,此时 &lt;code&gt; 尚未明确终止 &lt;/code&gt;),浏览器按如下方式构建 DOM 的其余部分,然后继续:

<code>
    <p> Another line of code </p>
</code>

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

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

【讨论】:

  • 为什么这种情况只发生在每段的第一个代码块上?
  • 谁投了反对票,为什么?这是一个非常明智的答案。
  • @Sparky672:我本来说浏览器不能把&lt;p&gt;放在&lt;code&gt;里面,然后我很快意识到我错得很厉害,继续编辑到死。
  • @Sparky672 我猜是因为他稍后编辑了答案,但这确实有道理,使用直接输入检查验证器,使用此小提琴jsfiddle.net/rW6ah/1 中的标记并在此处验证validator.w3.org/#validate_by_input
  • 简短的回答是“验证您的 HTML”或期待意想不到的结果,但我喜欢这里的详细分析。
猜你喜欢
  • 1970-01-01
  • 2017-01-07
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
  • 2015-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多