【问题标题】:When are <br> elements ignored when within a paragraph?段落中的 <br> 元素何时被忽略?
【发布时间】:2020-09-06 11:47:42
【问题描述】:

我发现有时,&lt;br&gt; 元素不会在我使用的浏览器(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 :我知道将 br 元素放在 HTML 中的这个位置是非常“不正确”的,我不是生成这个 HTML 的人,但我需要把这个 HTML 转换为另一种格式,所以我有兴趣了解浏览器如何处理这种情况。

【问题讨论】:

  • 因为这涉及渲染,我想说 CSS 规范是查看的地方,而不是 HTML。让我看看。我确实知道
    在 CSS 方面...有点奇怪,而且不同的浏览器实际上在内部实现它的方式不同,这使事情变得更加复杂。
  • 不应像在示例中那样使用该元素。它会中断一行文本,但在 br 之后没有任何文本。 w3.org/TR/html52/textlevel-semantics.html#the-br-element
  • 您对此有什么期望?关闭一个段落已经提供了空间
  • 对不起,我不清楚,我正在创建一个从 HTML 到另一种格式的转换器,我知道 &lt;br&gt; 不应该这样使用。我不是创建这个 HTML 的人,其他人有,我仍然想妥善处理它。我想在这种情况下复制浏览器的行为,即使它被错误地使用,了解更多关于如何呈现对我来说很重要。
  • 好的,
    描述 的 CSS 实现(但不保证这样实现)非常简单:它的功能类似于换行(& #x0A;) 带有空格:pre。我不知道是否要查看 CSS 规范或其他规范(Unicode?),因为它说不需要呈现行尾的强制换行符。

标签: html line-breaks specifications


【解决方案1】:

据我观察,&lt;br&gt; 元素导致尾随 inline 元素被渲染到下一行。在你的情况下:

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

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

p {
    display: inline;
}

您将看到您的&lt;br&gt; 标签将渲染兄弟&lt;p&gt; 标签以渲染到下一行。

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

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

要渲染显式 &lt;br&gt; b/w block 元素,请使用 2 个 &lt;br&gt;s。从技术上讲,它们将只是 1 个换行符。 为什么会起作用?它会起作用,因为当第一个&lt;br&gt; 将其标记为下一行时,渲染器会遇到另一个&lt;br&gt;,默认情况下它是一个inline 元素,因此,移动到下一行说得通。但是,对于第二个&lt;br&gt;,当它将其标记为下一行时,下一个元素将是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

【讨论】:

    【解决方案2】:

    在我看来,大多数浏览器都遵循 WHATWG 规范,我也会这样做。 World Wide Web Consortium (W3C) 已于 2019 年 5 月 28 日 announced 宣布 WHATWG 将成为 HTML 和 DOM 标准的唯一发布者。如果我们在本规范中仅遵循规则,那么我将遵循这些规则。

    WHATWG 对br 元素有以下建议:

    br 元素表示换行符。

    注意: 虽然换行符在视觉媒体中通常通过将后续文本物理移动到新行、样式表或 用户代理同样有理由导致换行符 以不同的方式呈现,例如绿点,或 额外的间距。

    br 元素必须仅用于实际上是部分的换行符 内容,如诗歌或地址。

    下面的例子是br元素的正确用法:

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

    br 元素不得用于分隔主题组 段。

    以下示例不符合标准,因为它们滥用了br 元素:

    <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>
    

    以下是上述的替代方案,它们是正确的:

    <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>
    

    如果一个段落只包含一个 br 元素,它 表示占位符空白行(例如在模板中)。这样的 空行不得用于演示目的。

    br 元素内的任何内容不得被视为 周围的文字。

    注意: This element has rendering requirements involving the bidirectional algorithm

    来源:WHATWG: The br element

    在您的示例中,&lt;br&gt;&lt;/p&gt;&lt;br&gt;&lt;/a&gt;&lt;/p&gt; 中的 br 元素位于 &lt;p&gt; 元素的末尾。这个元素末尾的新行什么都不做,但仅在这种情况下。在这种情况下,您可以忽略它。对于&lt;br&gt;&lt;/a&gt;&lt;/div&gt; 中的br 元素以及&lt;div&gt; 元素末尾的&lt;br&gt;&lt;/div&gt; 中的元素也是如此。

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

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


    2020 年 6 月 25 日更新

    我想再次发布并解释 WHATWG 推荐中的引用(见上文):

    如果一个段落只包含一个 br 元素,则它表示一个占位符空白行

    显示如下:

    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>

    第一个例子中的情况意味着这代表一个占位符空白行。这不是!为什么?因为占位符空白行具有一些字体大小属性。在其他情况下,就像在第三个示例中一样 - empty

    第二个例子中的例子展示了块元素末尾的两个br元素,我们可以看到最后一个br元素被忽略了,但是从末尾开始的第二个br元素有他自己的行。

    用户kalkronline has done the research again,但他发现用户Rei误解了错误的解释。用户 Rei 的解释乍看之下是合乎逻辑的,但如果我们阅读我写的内容,就会发现他做了 logical mistakes。我的第二个示例向我们展示了用户的 Rei 错误,因为根据他的描述,我们必须有一个空行。引自用户Rei的误解:

    因为该行有零个字符,所以呈现为空行。

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

    结论

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

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

    有用的链接:

    【讨论】:

    • 我对有关如何使用&lt;br&gt; 的建议部分不感兴趣,我只想知道浏览器如何理解我提出的案例,以及&lt;br&gt; 的确切时间没有效果
    • @edi9999,在我的回答中来自 WHATWG 的引用中,您可以看到对 &lt;br&gt; 元素的建议,浏览器使用该元素作为规则进行渲染。它不是“如何使用”,而是浏览器在渲染中必须如何处理它。在您的转换器中,您还必须遵守一些规则。在 WHATWG 引用之后的部分中,我为您编写了解决方案: 此元素末尾的新行 (&lt;br&gt;) 什么都不做,但仅在这种情况下。在这种情况下,您可以忽略它。 请再次查看我的答案。 ?
    • 这里是从If a paragraph consists of nothing but a single br element 概括为:If a paragraph ends with a br element and has no content after it,没有参考官方来源。
    • @edi9999,是的,这是因为在 WHATWG 的官方来源中,您只有建议,浏览器将其用作渲染规则。每个浏览器都可以实现这些规则,并且可以按照自己的方式执行此操作以及所有其他操作。 你没有更多的规则了。你可以做的是仔细看看它是如何被每个浏览器实现的,并且可以尝试以相同的方式实现它。从我这里你得到了很好的提示(like next rule)最后你可以忽略&lt;br&gt;元素。请考虑一下我的话。 ?
    【解决方案3】:

    &lt;br&gt; 元素始终在所有浏览器中呈现,因为所有浏览器都按照 W3C 联盟修订的特定规范对齐,但在某些情况下它们的效果会被隐藏。

    当您更深入地了解&lt;br&gt;&lt;p&gt; 标签如何在您的问题的特定上下文中工作时,您就会明白为什么会这样。因此,让我们更深入地了解一下。

    &lt;br&gt; 标签 - 在内容之后应用时,它会留下一个换行符,两个&lt;br&gt; 标签同时可以在可见文本之间留下一行空格,如段落之间所见。 注意:由于&lt;br&gt;标签的设计,两个连续的&lt;br&gt;标签之后的每一个&lt;br&gt;标签都会插入一行空白(注意:单行空白空间通常称为段落分隔符)而不是换行符。

    &lt;p&gt; 标签 - 它确实确保在嵌入内容的两侧都有一个空行(注意:内容中的空行在之前或之后它,被视为内容本身的一部分)。它不考虑任何换行符(注意:需要两个换行符才能留下一个空行(段落分隔符)即;2个&lt;br&gt;标签& 每个后续的&lt;br&gt; 标记在两个后续的&lt;br&gt; 标记之后插入一行空白而不是换行符。)。

    看看下面的代码sn-ps。

    1.

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

    在上面的代码sn-p中,看到第一行文本在&lt;p&gt;标签内,而第二行不在,它的功能和我上面描述的一样。

    2.

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

    在上面的代码 sn-p 中,两个文本都嵌入在 2 个独立的 &lt;p&gt; 标记中,它们之间仍然只有一行空白。这是因为&lt;p&gt; 标记将只考虑作为文本/内容一部分的空行空间,同时保留它自己的空行空间。 当您检查下面的代码 sn-ps 时,您会更加清楚。

    3.

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

    在上面的代码sn-p中,在第一个&lt;p&gt;标签中嵌入了一个&lt;br&gt;标签,但是看到一个&lt;br&gt;并不等同于一个空行空格(需要 2 个&lt;br&gt; 标签才相当于一个空行)。所以空行不是我们的第一个文本内容的一部分所以你不会看到&lt;br&gt;标签的效果,因为一个换行符不等同于一行空格&@987654345 @> 标签在插入自己的单行空格之前只考虑前面的空格。 根据设计,&lt;p&gt; 标签会将元素内的空白行视为该元素的一部分,因此如果元素在其末尾有空白行,则&lt;p&gt; 标签仍会保留其自己的单行空白行从而在内容的现有空格行中添加一个额外的空白行,请看下面的示例。

    4.

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

    在上面的代码sn-p中,2个&lt;br&gt;标签被插入到第一个&lt;p&gt;标签中,所以它留下一个空行作为第一个@的一部分987654351@标签第二个&lt;p&gt;标签会将此空行视为第一个&lt;p&gt;标签内内容的一部分,并在插入自己的单行空格时在前面的内容之后,好像又多了一个空行。

    5.

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

    在上面的代码sn-p中,你可以看到3个&lt;br&gt;标签是第一个&lt;p&gt;标签的一部分,现在向上滚动看看@987654357的作用@> 标签正如我在开头描述的,你可以看到现在两行空白是第一个&lt;p&gt;标签内内容的一部分,因此@之间的间距987654359@标签为3行空白(2个空行由3个&lt;br&gt;标签组成,1个空行由随后的&lt;p&gt;标签组成)。

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

    【讨论】:

      【解决方案4】:

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

      注意事项:

      如果您检查 br 标签 的尺寸,它的宽度 = 0 和一些高度(~18px)。但是如果你在 p 标签 中使用它,那么 br 标签 会采用 p 元素 的高度 但重要的是它自己的宽度是 0

      回答您的问题

      如果我们将其用作 = &lt;p&gt;Hello&lt;br&gt;&lt;/p&gt; 那么您将能够在开发者控制台中看到 br 元素,但没有多余的空间,因为我们在 br 标记 之后没有任何文本,并且它自己的宽度是0,因此整体宽度变为零。因此它不需要任何额外的空间或换行符。 示例 -

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

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

      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

      【讨论】:

        【解决方案5】:

        找到this answer,它给出的解释比我想出的要优雅得多。我将尝试总结并将其应用于您的情况。让我们再看看你的代码。

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

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

        为什么?

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

        考虑查看其他答案以了解更多详细信息。据称提出该问题的用户正在制作一个类似的程序,并且答案有很多示例和链接的文档。 pdiv 都是 block level elements,,所以在阅读这篇文章时请记住这一点。

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

        【讨论】:

        • @Bharata 对不起,但我很难理解你写的内容......我的回答是 &lt;br/&gt; 标签表示一行的结尾。你的第一个例子有宽度,因为p 标签不是空的,它有换行符。您的第二个示例有两行长,因为它有两个行尾。您的第三个示例是空的,因为您的 p 标记是空的。如果您可以改写您的编辑,这将很有帮助,这样我就可以更清楚地理解您要指出的内容。我不认为我误解了 Rei 所说的话。
        • 关于用户对Rei的误解,我的回答中并没有写得很清楚。我已经改变了。这不是你的误解。对不起!请删除您在上面的评论。
        • 请阅读我在本主题的回答中关于用户Rei误解的解释。
        • @Bharata 就像我之前说的,你给出的例子上面已经清楚地解释了。第二个例子的第二行有宽度的原因是因为第二行有一个换行符。在一行上有两个行尾没有意义,因此浏览器呈现两个。另外,对不起,我无法在您的回答下发表评论,我没有足够的代表。
        【解决方案6】:

        请查看我的更明智的更新答案。


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

        <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

        【讨论】:

        • 我认为您正在做某事。您可以通过对
          应用边距来判断折叠边距也在起作用。 that 是否重要或相关是另一回事......
        • @BoltClock 这篇文章的主要思想是传达
          将文本分成单独的行,如果一行没有文本,则以 0px 的高度呈现,类似于标准如何要求以 0px 的高度呈现空

        • @kalkronline “空”&lt;p&gt; 的部分以 0px 的高度呈现似乎很有希望,您能否深入挖掘并更新您的答案? (或者如果您没有权限这样做,您可以用其他答案来回答)。
        【解决方案7】:

        &lt;br&gt; 元素有一个明确的用途——在文本块中创建换行符。

        换行符定义为回车 (&amp;#x000D;)、换行 (&amp;#x000A;) 或回车/换行 饲料对。所有换行符构成空白。

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


        让我们强力测试一下,看看哪些标签最后呈现&lt;br/&gt;,哪些不呈现。 https://jsfiddle.net/t7bnokzc/1/

        我们可以看到这些标签完全忽略了最后一个&lt;br/&gt;,因为它们不会转到下一行,而是在它们旁边显示文本。

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

        同时这些标签忽略了最后一个&lt;br/&gt;

        <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标签:它们呈现最后一个换行符,除非它在一个块元素。

        【讨论】:

        • 随着后面的HTML,&lt;p&gt;Hello &lt;a href="https://ddg.gg"&gt;ddg&lt;br&gt;&lt;/a&gt;&lt;a href="https://ddg.gg"&gt;ddg&lt;br&gt;&lt;/a&gt;&lt;/p&gt;,第一个br被渲染了,所以If you put it at the end of basically any HTML tag, with no text after, it gets ignored这句话可能不完全正确。
        • @edi9999 编辑了我的答案,进行了一些蛮力挖掘,逐案测试,答案就出现了。
        【解决方案8】:

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

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

        如cmets中所说,不同浏览器的实现可能不同,但最终逻辑是相同的,没有大小的阻塞元素。

        【讨论】:

        • 什么是“阻塞元素”?
        • 一个,阻止整行(如divp 等,基本上任何具有diplay: blockdisplay: flex 的东西)。插件:BR 并不完全是阻塞元素,但它的行为如此
        • @SergeS 感谢您通过一些示例和引用的权威资料来解释您的答案。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-06
        • 1970-01-01
        • 2020-05-14
        • 1970-01-01
        • 1970-01-01
        • 2021-10-18
        相关资源
        最近更新 更多