什么时候在段落中忽略 <br> 元素?

When are <br> elements ignored when within a paragraph?

我发现有时 <br> 元素不会在我使用的浏览器(Firefox 和 Chrome)中呈现。

<p>Hello<br></p>
<p>Hello<br></p>

将呈现为:

<p>Hello</p>
<p>Hello</p>

同理,

<p>Hello <a href="https://ddg.gg">ddg<br></a></p>
<p>Hello</p>

和:

<p>Hello <a href="https://ddg.gg">ddg</a></p>
<p>Hello</p>

在浏览器中打开时也将呈现无任何换行符。

我在 HTML 规范中找不到指定此行为的部分,您知道在哪里可以找到此规范吗?或者您能用简单的方式描述此行为吗?

如果您知道这些行为的原因,我也会感兴趣。

EDIT :我知道在 HTML 中的这个位置放置 br 元素相当 "incorrect",我不是生成者这个 HTML,但我需要将这个 HTML 转换成另一种格式,所以我想了解浏览器如何处理这种情况。

br 元素的行为类似于大小为 0 的普通阻塞元素,因此在您的情况下,它只是在 p(或 a)的末尾添加 0px。当另一个文本跟随任何阻塞元素时,它将被放置在(因此创建换行符)之下。没有文字的时候,最后没有多余的space。

这是 content-editable 的常见行为,将 br 放在每行的末尾,同时将每行换行到 p 元素

如评论所述,浏览器之间的实现可能不同,但最终逻辑是相同的,没有大小的阻塞元素。

请查看我更新后的更详尽的回答。


Here's a W3 doc 表示浏览器应该忽略空的 p 元素。 “忽略”的定义有点松散,因此请考虑以下片段:

<p>hello</p>
<p></p>
<p>hello</p>

它将呈现出与您的代码大致相同的效果:

<p>hello<br /></p>
<p>hello</p>

这并不是说元素已从页面上完全清除。应用样式显示它们刚刚缩小了。

<p>hello<br style="margin-bottom: 100px"/></p>
<p>hello up there!</p>

这里有一些更多的文档和一些提出类似问题的附加链接。

W3 doc on Whitespace

Change Height of Line Breaks

Empty Paragraph Tags

在我看来,大多数浏览器都遵循 WHATWG specification and I would do it also. World Wide Web Consortium (W3C) has On 28 May 2019 announced,即 WHATWG 将是 HTML 和 DOM 标准的唯一发布者。如果我们在本规范中仅遵循以下规则,那么我将遵循这些规则。

WHATWG 对 br 元素有以下建议:

The br element represents a line break.

Note: While line breaks are usually represented in visual media by physically moving subsequent text to a new line, a style sheet or user agent would be equally justified in causing line breaks to be rendered in a different manner, for instance as green dots, or as extra spacing.

br elements must be used only for line breaks that are actually part of the content, as in poems or addresses.

The following example is correct usage of the br element:

<p>P. Sherman<br>
42 Wallaby Way<br>
Sydney</p>

br elements must not be used for separating thematic groups in a paragraph.

The following examples are non-conforming, as they abuse the br element:

<p><a ...>34 comments.</a><br>
<a ...>Add a comment.</a></p>
<p><label>Name: <input name="name"></label><br>
<label>Address: <input name="address"></label></p>

Here are alternatives to the above, which are correct:

<p><a ...>34 comments.</a></p>
<p><a ...>Add a comment.</a></p>
<p><label>Name: <input name="name"></label></p>
<p><label>Address: <input name="address"></label></p>

If a paragraph consists of nothing but a single br element, it represents a placeholder blank line (e.g. as in a template). Such blank lines must not be used for presentation purposes.

Any content inside br elements must not be considered part of the surrounding text.

Note: This element has rendering requirements involving the bidirectional algorithm.

Source: WHATWG: The br element

在您的示例中,<br></p><p> 元素末尾的 <br></a></p> 中有 br 个元素。这个元素末尾的新行什么都不做,但只在这种情况下。在这种情况下,您可以忽略它。 <br></a></div>中的br元素和<div>元素末尾的<br></div>中的元素也是一样的。

引自 WHATWG 推荐(见上文): 如果一个段落只包含一个 br 元素,它表示一个占位符空白行。它也是 not empty(如用户 kalkronline 所写)。如果 W3C 和 WHATWG 的意见发生冲突,用户代理必须遵循 WHATWG 的建议(见上文)。

不要忘记 br 元素的样式可能性(例如 clear)。


2020 年 6 月 25 日更新

我想 post 并再次解释 引用 WHATWG 的建议(见上文):

If a paragraph consists of nothing but a single br element, it represents a placeholder blank line.

显示如下:

p{border:1px dashed red}
<b>1. example:</b>
<code>&lt;p&gt;&lt;br&gt;&lt;/p&gt;</code>
<p><br></p>
<b>2. example:</b>
<code>&lt;p&gt;I am a line&lt;br&gt;&lt;br&gt;&lt;/p&gt;</code>
<p>I am a line<br><br></p>
<b>3. example:</b>
<code>&lt;p&gt;&lt;/p&gt;</code>
<p></p>

第一个例子中的case表示这个代表一个占位符空行。而且这不是!为什么?因为占位符空白行具有一些字体大小属性。在其他情况下,它会像第三个例子一样——empty.

第二个例子中的情况向我们展示了块元素末尾的两个 br 元素,我们可以看到最后一个 br 元素被忽略了,但是第二个 br 元素从头到尾都有自己的台词。

用户kalkronline, but he has found wrong explanation wih misinterpretation from user Rei. The explanation from user Rei is only at the first look logical, but if we read what I wrote than we will see that he has done logical mistakes。我的第二个例子向我们展示了用户的 Rei 错误,因为根据他的描述,我们必须有一个空行。引自用户Rei的错误解读:

Because the line has zero characters, it is rendered as an empty line.

但这是因为在这个块元素中它后面没有元素!

结论

我想为你的转换器写一些规则:

  1. 如果一个段落只包含一个 br 元素,它表示一个占位符空行(来自 WHATWG 的建议)
  2. 块元素末尾的所有 br 个元素,如果在它们之后没有任何内容,则应被忽略。
  3. 只有块元素末尾的两个或多个 br 元素中的最后一个 br 元素必须被忽略。但是之前的 br 元素必须有自己的一行,字体大小高度。
  4. 您必须遵循 WHATWG 的所有建议。

有用链接:

<br> 元素有一个明确定义的用途 — 在文本块中创建换行符。

A line break is defined to be a carriage return (&#x000D;), a line feed (&#x000A;), or a carriage return/line feed pair. All line breaks constitute white space.

https://www.w3.org/TR/REC-html40/struct/text.html#line-breaks


让我们进行暴力测试,看看哪些标签在最后呈现 <br/>,哪些不呈现。 https://jsfiddle.net/t7bnokzc/1/

我们可以看到这些标签完全忽略了最后一个 <br/> 因为它们不会转到下一行,而是显示紧挨着它们的文本。

<button>
<canvas>
<img>
<iframe>
<input>
<ruby>
<meter>
<progress>
<select>
<svg>
<textarea>
<video>

同时这些标签忽略最后一个 <br/> :

<address>
<article>
<aside>
<audio> // Has a default height and width, differs from browser to browser
<blockquote>
<center>
<datalist>
<dd>
<details>
<dir>
<div>
<dl>
<dt>
<fieldset>
<figcaption>
<figure>
<footer>
<form>
<h1>
<header>
<legend>
<li>
<main>
<nav>
<ol>
<optgroup>
<option>
<p>
<pre>
<section>
<summary>
<ul>

以上这些有什么共同点?他们有 display:blockdisplay:list-item.

结论:

如果您在一个不呈现换行符的元素(上面列出)的末尾放置一个换行符,或者在它的末尾有一个不呈现换行符的元素,它会被忽略。

另一个例子:

<address>Hello
  <b>ddg<br></b>
  <b>ddg<br></b>
</address>

知道 address 标签是块元素,它的行为与 p 标签完全一样,知道 b 标签的行为与 a 标签一样:他们呈现最后一个换行符,除非它在块元素内结束。

发现 给出的解释比我想出的要优雅得多。我将尝试总结并将其应用于您的情况。让我们再看一下您的代码。

<p>hello<br/></p>
<p>howdy</p>

<hr/>

<p>hello</p>
<p>howdy</p>

水平线上方和下方的代码呈现完全相同。

为什么?

好吧,正如用户 Rei 所解释的那样,这是因为“根本没有忽略 BR 元素。它标志着必须在该点断开该行。换句话说,它标志着该行的结束当前文本行。这与创建新行无关。" 我们知道它不会被忽略,因为我们能够对其应用样式。正如我之前发现的那样,使边距大于默认值表明中断仍然存在。

考虑查看其他答案以获取更多详细信息。据称提出该问题的用户正在制作类似的程序,答案中有大量示例和文档链接。 pdiv 都是 block level elements,,因此在阅读 post 时请记住这一点。

TLDR: BR 不会自动换行,它只是标记当前文本行的结尾。

为什么我们使用 br 标签 - HTML br 元素 在文本 中产生换行符(回车-return)carriage-return 或 return 是一个控制字符或机制,用于将设备的位置重置为 一行文本的开头.

注意事项:

如果您检查 br 标签的尺寸,它的宽度 = 0,高度为 (~18px)。但是如果你在 p tag 中使用它,那么 br tag 会占据 p element 但是重要的是它自己的宽度是0.

回答你的问题

如果我们将其用作= <p>Hello<br></p> 那么你将能够在开发者控制台中看到 br 元素 但没有额外的 space, 因为我们在 之后没有任何文本br tag 而自身宽度为0,所以整体宽度变为0。因此它不需要任何额外的 space 或换行符。 示例 -

p {
  margin: 0;
}
<p>Hello<br></p>
<p>Hello<br></p>

但是如果我们有这样的代码 - <p>Hello<br>World</p> 然后 br tag 将光标移动到下一行的开头,我们在 br tag 之后有一些宽度的文本。因此,我们将能够看到额外的 space 或换行符。 示例 -

p {
  margin: 0;
}
<p>Hello<br>World</p>
<p>Hello<br>World</p>

我同意这不是使用 br 标签 的正确位置,因为 p 元素会自动添加换行符。因此,在结束 p 标签 之前使用 br 标签 是没有意义的。

请检查以下链接:

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/br

https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-br-element

<br> 元素始终在所有浏览器中呈现,因为所有浏览器都遵循 W3C 联盟修订的特定规范,但在某些情况下它们的效果会被隐藏。

当您更深入地了解 <br><p> 标签在您问题的特定上下文中的工作方式时,您就会明白为什么会这样。那么让我们深入了解一下。

<br>标签 - 当应用在一个内容之后,它留下一个换行符,两个<br>标签同时可以留下一行space 在段落之间看到的可见文本之间。 注意:由于<br>标签的设计,连续两个<br>标签后的每个后续<br>标签都会插入一行空space(注意:单行空space习惯上称为段落中断)而不是换行。

<p> 标签 - 它确实确保在嵌入内容的两边有一个空行 space(注意: space 之前或之后的内容中的空行被视为内容本身的一部分)。它不考虑任何换行符( 注意: 需要两次换行符才能留下一个空行 space(Paragraph Break) ie; 2 <br> tags & every subsequent <br> tags after 2 consequent <br> tags insert a line of empty space instead of a line break .).

看看下面的代码片段。

1.

<p>This is a paragraph.</p>
This is a paragraph.

在上面的代码片段中,看到第一行文本在 <p> 标记内,而第二行不在标记内,它的功能与我上面描述的一样。

2.

<p>This is a paragraph.</p>
<p>This is a paragraph.</p>

在上面的代码片段中,两个文本都嵌入在 2 个单独的 <p> 标签中,它们之间仍然只有一行空 space。这是因为 <p> 标签将只考虑属于 text/content 的 space 的空行,同时留下它自己的空行 space。 当您检查下面的代码片段时,您会变得更加清晰。

3.

<p>This is a paragraph.<br></p>
<p>This is a paragraph.</p>

在上面的代码片段中,单个 <br> 标记嵌入在 第一个 <p> 标记 中,但是看到单个 <br>不等同于space的空行(需要2个<br>标签才等同于space的空行)。所以 space 的空行不是我们第一个文本内容的一部分 所以你不会看到 <br> 标签的效果,因为单个换行符不是相当于一行 space & <p> 标记在插入它自己的单行 space 之前只考虑前面的行 space。 根据设计,<p> 标签会将元素中 space 的空行视为该元素的一部分,因此如果元素的末尾有 space 的空行,则<p> 标签仍​​然保留它自己的单行空行 space 从而在内容的 spaces 的已经存在的行中添加一个额外的空行,请看下面的示例。

4.

<p>This is a paragraph.<br><br></p>
<p>This is a paragraph.</p>

在上面的代码片段中,在 第一个 <p> 标签 中插入了 2 个 <br> 标签,所以它留下了一个空行 space 作为 第一个 <p> 标签 的一部分。 第二个 <p> 标签 会将 space 的空行视为 第一个 <p> 标签<p> 中内容的一部分 并且当它在前面的内容之后插入自己的单行 space 时,似乎已经添加了一个额外的空行 space。

5.

<p>This is a paragraph.<br><br><br></p>
<p>This is a paragraph.</p>

在上面的代码片段中,您可以看到 3 个 <br> 标签是 第一个 <p> 标签的一部分 现在滚动看看 <br> 标签的功能,正如我在开头所描述的,你可以看到现在 2 行空的 space 是 [=117= 中内容的一部分]第一个<p>标签,因此<p>标签之间的间距是3行空space(2空行凭借3<br>标签和 1 个空行(由于后续的 <p> 标签)。

希望这能解决您的疑问,也请参考此 BR tag has no effect when parent has height,以获得不同的视角。

据我观察,<br> 元素导致尾随 inline 元素呈现到下一行。在你的情况下:

<p>Hello<br></p>
<p>Hello</p>

<br> 不会给兄弟 p 标签带来麻烦,因为它们默认是 block 元素。如果你应用一点 CSS:

p {
    display: inline;
}

您会看到您的 <br> 标记将呈现兄弟 <p> 标记以呈现到下一行。

我认为它只是归结为尾随 element(s)display 属性,如果它们又是 inline。在文本流中,那些 element(s) 会发现自己受到 <br> 的影响,否则,如果有任何其他不同 display 属性 的可渲染元素,他们将获胜受其影响。

正如@karlkronline 所说,<br> 元素标记当前行的结尾很可能是真的。而且,如果要呈现的下一个“可见”元素是 inline 元素,它会移至下一行并呈现它。但是,如果是任何其他类型,由于默认情况下元素在单独的行上呈现,因此没有必要再次移动到下一行并呈现元素。 看到我们已经在下一行就足够了,所以忽略并继续渲染。

要呈现显式 <br> b/w block 元素,请使用 2 <br>。从技术上讲,它们将证明只是 1 个换行符。 为什么它会起作用? 它会起作用,因为当第一个 <br> 将其标记为下一行时,渲染器会遇到另一个 <br>,它是一个 inline默认情况下,移动到下一行是有意义的。但是,对于第二个 <br>,当它标记为下一行时,下一个元素将是 block,它已经在单独的行上呈现,因此被忽略。

总结,表达形式:

<br> followed by <INLINE ELEMENT> = Next line starting with <INLINE ELEMENT>
<br> followed by <BLOCK ELEMENT> = Ignore since <BLOCK ELEMENT> will render on the next line anyway