我有<div>一些元素可能包含一个或多个<br/>,即硬换行符。我希望每个换行符后的新行文本<br/>都缩进,但第一行<div>不应缩进

我首先尝试了div { text-indent: 2rem each-line; }。这会使每个 后的文本缩进<br/>,但也会缩进 的第一行<div>。因此,我尝试使用 删除第一行的缩进div:first-line { text-indent: 0rem; },但这不起作用,显然是因为text-indent不是伪元素上允许的属性。看来我也不能在伪元素上:first-line使用负数margin。有没有办法实现我想要实现的目标?padding:first-line

<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam placerat metus turpis, et auctor eros porttitor sed.
  <br/>Sed ornare eget metus in interdum. Nulla ut orci eget eros ullamcorper semper.
  <br/>Aliquam fringilla urna lectus, ac vestibulum diam sodales eget.
</div>

因此,在此示例中,“Sed ornare”和“Aliquam fringilla”应该缩进,而不是“Lorem ipsum”。这是我尝试过的CSS:

div { text-indent: 2rem each-line; }
div:first-line { text-indent: 0rem; }

这是我想要实现的目标的图片:

测试

11

  • 您可以在需要缩进​​的句子开头手动添加空格&nbsp


    – 

  • 4
    @MrIzzat 用 ` ) 硬编码空格是你能做的最糟糕的事情,而且绝对一团糟。除此之外,它很容易出错。


    – 


  • 对于像缩进这样简单的事情,硬编码空格就像在文本中添加制表符,就像大多数人在写文章时开始新段落时所做的那样。使用 CSS 来实现简单的缩进有点过分了。


    – 


  • 1
    CSS 永远不会过分。除此之外。想象一下写一篇 30 页的文章,每篇 100 行。然后必须手动用空格缩进每个 3k 行……这就是为什么你使用 CSS 并且永远不会对这样的东西进行硬编码。此外,它可能会让屏幕阅读器变得一团糟。


    – 

  • 3
    @Rob:在我使用的 XHTML 中,<br/>确实需要一个结束斜杠。


    – 



最佳答案
3

这是一个使用负边距的 hack 想法,但只在 Firefox 上可用,因为支持each-line

.indent {
  text-indent: 2rem each-line;
}
.indent:before {
  content:"";
  margin-right: -2rem;
}

/* fallback to avoid the overflow */
@supports not (text-indent: 2rem each-line) {
  .indent {
    text-indent: 2rem;
  }
}
<div class="indent">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam placerat metus turpis, et auctor eros porttitor sed.
  <br>Sed ornare eget metus in interdum. Nulla ut orci eget eros ullamcorper semper.
  <br>Aliquam fringilla urna lectus, ac vestibulum diam sodales eget.
</div>

嗯,这是您无法使用当前 HTML 结构可靠地完成的事情。我尝试保留您的文档结构 ( <div> text <br> more text <br> etc. </div>),但效果不佳,因为<br>元素似乎只在某些条件下才会响应,例如设置display: none为删除换行符或margin

此外,有关 Line Break 元素本身的 MDN 文档也指出,

因此,它本身没有尺寸或视觉输出,而且几乎无法对其进行样式设置。

你可以做的是将段落包裹在<p>标签中,如下所示:

<div>
    <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam placerat metus turpis, et auctor eros porttitor sed.
    </p>
    <p>
        Sed ornare eget metus in interdum. Nulla ut orci eget eros ullamcorper semper.
    </p>
    <p>
        Aliquam fringilla urna lectus, ac vestibulum diam sodales eget.
    </p>
</div>

然后将样式应用于p

div p {
    text-indent: 2rem each-line;
}

div p:first-child {
    text-indent: 0;
}

根本问题是 CSS 无法定位
标签后面没有某种包含该文本的元素的文本节点。(我尝试了几种使用 /br 的方法,但似乎都没有用)所以我有两个可行的解决方案

  1. 解决方案 1:(html-css)
div p {
  margin: 0;  
}

div p:not(:first-child) {
  text-indent: 2rem;
}
<div>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam placerat metus turpis, et auctor eros porttitor sed.</p>
  <p>Sed ornare eget metus in interdum. Nulla ut orci eget eros ullamcorper semper.</p>
  <p>Aliquam fringilla urna lectus, ac vestibulum diam sodales eget.</p>
</div>
  1. 解决方案 2:(html-css-js)
function wrapTextAfterBr(element) {
  let html = element.innerHTML;
  
  let parts = html.split(/<br\s*\/?>/i);
  
  let newHtml = parts.map((part, index) => {
    if (index === 0) return part;
    return `<span>${part}</span>`;
  }).join('<br>');
  
  element.innerHTML = newHtml;
}
document.querySelectorAll('.indent-after-br').forEach(wrapTextAfterBr);
.indent-after-br br + * {
  margin-left: 2rem;
}

.indent-after-br {
  display: flex;
  flex-direction: column;
}

.indent-after-br > *:not(:first-child) {
  margin-left: 2rem;
}
<div class="indent-after-br">
  Lorem ipsum dolor sit amet...
  
  <br/>Sed ornare eget metus...
  <br/>Aliquam fringilla urna...
</div>