HTML 渲染新行的规范?

HTML specification for rendering new lines?

我正在尝试将一些简单的 HTML 文档(主要包含 div 和 br 标记)呈现为纯文本,但我正在为何时添加新行而苦苦挣扎。我认为使用 <div><br/> 生成新行会很简单,但看起来有各种微妙的规则。例如:

<div>one line</div>
<div>two lines</div>

<hr/>

<div>one line</div>
<div></div>
<div>still two lines because the empty div doesn't count</div>

<hr/>

<div>one line<br/></div>
<div></div>
<div>still two lines because the br tag is ignored</div>

<hr/>

<div>one line<br/></div>
<div><br/></div>
<div>three lines this time because the second br tag is not ignored</div>

<hr/>

<div><div>Wrapped tags generate only one new line<br/></div></div>
<div><br/></div>
<div>three lines this time because the second br tag is not ignored</div>

所以我正在寻找关于如何在 HTML 文档中呈现新行的规范(当未应用 CSS 时)。知道在哪里可以找到此类文档吗?

我猜你在这里遗漏的是 div 是一个块级元素,因此总是开始一个新行(没有 CSS)。关于空 div 我认为因为没有什么可显示的,所以它不会渲染任何新行;它还可能取决于 HTML 标准的浏览器实现。

您可以在此处找到有关块或内联 HTML 元素的更多信息 here

对于您的第二个示例,您可以将 &nbsp; 放在 <div> 中,以便它呈现为空行。 同样对于您的第四个示例,您可以将双 br 放在第一个 div.

但是,我不知道这方面有任何规范。

<div>one line</div>
<div>&nbsp;</div>
<div>still two lines because the empty div doesn't count</div>

<hr/>

<div>one line<br/><br/></div>
<div>three lines this time because the second br tag is not ignored</div>

块级元素将始终在新行开始,除非它是另一个元素的直接第一个子元素。

在你的例子#2

<div>one line</div>
<div></div>
<div>still two lines because the empty div doesn't count</div>

这些行是三行,但由于第二行中没有视觉内容,所以看起来好像是两行div。您可以定义自定义边距和边框以获得视觉效果。

一个 br 元素总是会中断内容流,之后的节点将在新的一行开始,无论该节点是否恰好是 block-level 元素。

<div>one line</div>
<div></div>
<div>still two lines because the empty div doesn't count</div>

我不会说第二个 div 不算数,更准确地说,它的默认块宽度为 100%,但由于是空的,所以高度为 0px。显然,也没有填充和边距,但从技术上讲它仍然存在。算了。

<div>one line<br/></div>
<div></div>
<div>still two lines because the br tag is ignored</div>

br 标签也不会被忽略,它已经完成了在 current line of text[ 中创建换行符的工作=56=] 在父块级别 div 内。强调的措辞直接来自文档。请注意,它仅提及当前文本行。它不会创建下一行,它会创建一个中断,如果有内容可能会导致换行。

它后面没有任何文字可以放在第二行。因此,下一个 div 是在下面创建的,并遵守上述规则。

<div>one line<br/></div>
<div><br/></div>
<div>three lines this time because the second br tag is not ignored</div>

基于之前的逻辑,br 标签中的 none 将被忽略。此示例中的两个标记实际上都在其父块级别 div 元素中创建了一个新的换行符。

这些 br 标签就像一个标记 "from this point till the end of the line, within my parent block level element, will not be any inline content allowed"。但是,在所有这些情况下,下一行都没有内容。

下一个 div,作为块级元素基本上重置了该行为。先前的中断包含在它们的文本行和它们的父块级元素中。我们知道这一点,因为一行文本不能在两个块级元素之间延伸。

关于您对另一个答案的评论。

Block level elements do always start on a new line. 如上所述,空的 div 确实存在并且确实从新行开始,它的高度仅为 0。如果您有两个嵌套的空 div 元素,它们都从同一行开始,因为它们都是空的块级元素,没有任何创建行的内容。如果您在子 div 之前向父 div 添加文本,它将被推到一个新行。如果有帮助,请将其视为同一行文本。例如:

同一行:

<div>
    <div>
        bar
    </div>
</div>

不同行:

<div>
    foo
    <div>
        bar
    </div>
</div>

如果您正在寻找 <div><br> 的规范, 你不会在一个地方找到它,因为它们每个都遵循不同的规则。 DIV 元素遵循块格式规则,而 BR 元素遵循文本流规则。

我认为造成您混淆的原因是假设它们遵循相同的换行规则。 让我解释一下。

BR元素。

BR 在 HTML4 Specification Section 9.3 中关于行和段落的定义:

The BR element forcibly breaks (ends) the current line of text.

并且在 HTML5 Specification Section 4.5 中关于 Text-level 语义:

The <br> element represents a line break.

规范说明你的第三个例子的结果:

<div>one line<br/></div>
<div></div>
<div>still two lines because the br tag is ignored</div>

那里,BR 元素根本没有被忽略,因为它标志着必须在该点断开该行。 换句话说,它标志着当前文本行的结束。 这不是关于创建新行。

在你的第四个例子中:

<div>one line<br/></div>
<div><br/></div>
<div>three lines this time because the second br tag is not ignored</div>

BR 元素也标记行的结尾。 因为该行有零个字符,所以呈现为空行。

因此,第三个和第四个示例中的规则相同。 什么都不会被忽略。

DIV 元素。

如果没有明确的样式 sheet,则应用默认样式。 DIV 元素默认是 block-level 元素,这意味着它遵循块格式上下文 在 CSS Specification Section 9.4.1:

中定义

In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block.

因此,这也与创建新行无关,因为在块格式化上下文中,没有行的概念。 就是从上到下一个接一个地放置块元素

在你的第二个例子中:

<div>one line</div>
<div></div>
<div>still two lines because the empty div doesn't count</div>

空 DIV 的高度为零,因此它对下一个 block-level 元素的渲染没有影响。

在你的第五个例子中:

<div><div>Wrapped tags generate only one new line<br/></div></div>
<div><br/></div>
<div>three lines this time because the second br tag is not ignored</div>

外部 DIV 用作 Section 9.1.2 中定义的包含块 并且内部 DIV 是我在上面引用的第 9.4.1 节中定义的。 因为没有应用 CSS,默认情况下 DIV 元素具有零边距和零填充, 这使得内部 DIV 的每条边都接触到外部 DIV 的相应边。 换句话说,内部 DIV 与外部 DIV.

在完全相同的位置呈现

我相信这就是一切。

在您的问题中,您是说忽略了两个 div 之间的 <br/> 标记。但是您的代码段似乎有问题。实际上它不会忽略。 我已经纠正了剪断。这是在不使用 css

的情况下插入新行的正确方法

<div>one line</div>
<div>two lines</div>

<hr/>

<div>one line</div>
<div></div>
<div>still two lines because the empty div doesn't count</div>

<hr/>

<div>one line</div>
<br/>
<div>Three lines because the br tag is not ignored</div>

<hr/>

<div>one line</div>
<div><br/></div>
<div>three lines this time because the second br tag is not ignored</div>

<hr/>

<div><div>Wrapped tags generate only one new line<br/></div></div>
<div><br/></div>
<div>three lines this time because the second br tag is not ignored</div>

  • <DIV> = 除法。这是一块可能混合的内容。
  • <BR> = 中断。只是一个换行符。
  • <P> = 段落。

如果您想像文字处理器一样创建文档,那么 <P> 是正确的选择。

许多新开发人员在前几次实施 tinyMCE 时似乎都为此苦苦挣扎。按 [enter] 创建 <P>,而 [shift]+[enter] 创建 <br>。完全像文字处理器。

jQuery 引擎将 HTML 渲染为文本怎么样?看看下面的代码片段,如果您单击 "Run",您将看到一个仅显示文本的警告框:

var sample = $("#sample").text();
alert(sample);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head/>

<body>

  <div id="sample">

    <div>one line</div>
    <div>two lines</div>

    <hr/>

    <div>one line</div>
    <div></div>
    <div>still two lines because the empty div doesn't count</div>

    <hr/>

    <div>one line
      <br/>
    </div>
    <div></div>
    <div>still two lines because the br tag is ignored</div>

    <hr/>

    <div>one line
      <br/>
    </div>
    <div>
      <br/>
    </div>
    <div>three lines this time because the second br tag is not ignored</div>

    <hr/>

    <div>
      <div>Wrapped tags generate only one new line
        <br/>
      </div>
    </div>
    <div>
      <br/>
    </div>
    <div>three lines this time because the second br tag is not ignored</div>

  </div>
</body>

</html>

您可以使用变量sample的内容进一步处理,例如将其提交给AJAX方法。

如果你 运行 它,你会发现所有的标签都被考虑了——这只是一个如何定义样式默认值的问题。话虽如此,我相信您不能完全忽视样式,因为它确实很重要 - 即使您没有指定它,也会假定并应用一些样式。

你从$("#sample").text();得到的只是换行符和纯文本,这是我从你的问题中了解到你想要实现的。

根据规范,只有
元素用于换行:


  • 元素只能用于实际上属于内容一部分的换行符,例如诗歌或地址。

  • 元素不得用于分隔段落中的主题组(只需使用另一个

    元素)。

您也可以使用 (更多信息 here

您可以在规范中找到更多信息。 (单页版本更好地搜索)https://www.w3.org/TR/html/single-page.html#elementdef-br

PD:某些属性接受 LF (U+000A),例如 标签中的 title attribute

最后,任何空块元素都可以完成这项工作。 (没有 CSS) 完整列表是 here