多行填充文本

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

这是一个棘手的 CSS 问题,我每隔几个月就会遇到一次。我想,在 CSS-Tricks 上解决它再好不过了,对吧?

这种情况涉及到参差不齐的右对齐内联文本。就像一段文本在下一个单词无法容纳时换行(即互联网上的大多数文本)。您希望在该文本后面添加一个背景,该背景

  1. 遵循参差不齐的右边缘
  2. 在每行的左右边缘都添加填充

您不能简单地将背景和填充应用于,例如,<p> 元素。段落是块级元素,因此背景将只是一个矩形,而不是遵循参差不齐的右边缘。

您也不能简单地将背景和填充应用于 <span> 或内联元素。左右填充将仅应用于第一行和最后一行。在每一行的中间,背景将紧贴文本。

描述这一点有点徒劳。以下是问题的视觉效果

我们希望每一行都像第一行的开头和最后行的结尾一样填充。我们不想诉诸任何粗俗的方法,比如将每一行都包装在自己的 span 中(换行的位置不可预测)。而且不幸的是,没有 :nth-line 这样的东西

不过,有一些解决方案!

Harry Robert 的伪元素/空白方法

这里的主要技巧是使用 white-space: pre-wrap; 这为我们提供了参差不齐右边缘上的填充。然后,为了在左侧获得填充,在左侧边缘添加了一个伪元素。这里有 原始版本,然后是我的分支以显示元素的工作原理

查看 Chris Coyier 的 CodePen 作品 BtpGo (@chriscoyier) 在 CodePen

不幸的是,Firefox 不喜欢该技术中伪元素的定位方式。可能可以修复,但是,可能还有更好的方法……

Fabien Doiron 的盒阴影方法

事实证明,您可以对内联元素仅在 x 轴上使用零扩展盒阴影来填充每一行。本质上

.padded-multi-line {
  display: inline;
  background: orange;
  box-shadow: 10px 0 0 orange, -10px 0 0 orange;
}

这里有 原始版本,然后是我的分支以显示其工作原理

查看 Chris Coyier 的 CodePen 作品 包装突出显示的文本 (@chriscoyier) 在 CodePen

注意:当 Firefox 32 发布时,我不得不更新此代码。Firefox 需要 box-decoration-break: clone;,因为默认值为 box-decoration-break: split;

Dave Rupert 的 JavaScript/Unicode 方法

公平警告:Dave 说不要使用此方法。 我之所以包含它,是因为我认为它很巧妙,并且以某种奇怪的方式实际上对我来说感觉不太像黑客手段。这个想法是遍历每个元素的文本,并将空格替换为 Unicode 字符 \u205f,即中等数学空格字符。出于某种原因,这在右边缘与填充配合得更好。对于左边缘,您只需沿着块级父元素使用 border-left

这里有 原始版本 和我的简化分支

查看 Chris Coyier 的 CodePen 作品 包装突出显示的文本 (@chriscoyier) 在 CodePen

使行高恰到好处以便边框与填充对齐有点棘手,但我相信您可以解决它。可能甚至有一些花哨的数学方法可以确保它正确。

如果 JavaScript 对您有用,还有一个 jQuery wraplines 插件,然后您可以将填充应用于每一行。 演示

Matthew Pennell 的三元素方法

事实证明,您可以使用几乎没有花哨的 CSS 或 JS 就能做到这一点,但需要使用三个元素。您需要一个块级父元素来设置 border-left。然后是一个内联元素来应用填充和背景。然后是另一个内联元素将文本向左微调以获得右边缘的填充。

<div class="padded-multiline">
  <h1>
    <strong>
      How do I add padding to subsequent lines of an inline text element?
    </strong>
  </h1>
</div>
.padded-multiline { 
  line-height: 1.3; 
  padding: 2px 0; 
  border-left: 20px solid #c0c;
  width: 400px;
  margin: 20px auto;
}
.padded-multiline h1 { 
  background-color: #c0c;
  padding: 4px 0;
  color: #fff; 
  display: inline;
  margin: 0; 
}
.padded-multiline h1 strong { 
  position: relative;
  left: -10px; 
}

原始 在此线程中,以及我的演示

查看 Chris Coyier 的 CodePen 作品 pvBFg (@chriscoyier) 在 CodePen

如果您在 Firefox 中查看此内容,可能会有一些行高问题。我基本上不知道为什么会这样,有点令人沮丧,尤其是在这种情况中。

Adam Campbell 的盒装饰中断方法

在关于此问题的讨论中,Adam 指出有一个 新的 CSS 属性(据我理解)专门用于此。这消除了对三个元素的需求。从技术上讲,您只需要一个内联元素,但您可能会在标题上执行此操作,因此您可能最终会使用块级父元素,这对于间距来说是最好的。

这里有 原始版本 和我的简化演示

查看 Chris Coyier 的 CodePen 作品 hIvFe (@chriscoyier) 在 CodePen

这在我的快速测试中在 Chrome 和 Safari 中有效,但在 Firefox 中无效 现在在 Firefox 32+ 中有效。Chrome 和 Safari 需要将其设置为 -webkit-box-decoration-break

先前技术

我在本文中提到的这些人是我第一次从他们那里看到这项技术的人。但他们并不一定代表“有史以来第一个想到它的人”。在下面的评论中,出现了一些较旧的博文文章也解决了同样的问题。一篇由 Sergey Chikuyonok(俄语)撰写,另一篇由 HTeuMeuLeu(法语)撰写。