这是一个棘手的 CSS 问题,我每隔几个月就会遇到一次。我想,在 CSS-Tricks 上解决它再好不过了,对吧?
这种情况涉及到参差不齐的右对齐内联文本。就像一段文本在下一个单词无法容纳时换行(即互联网上的大多数文本)。您希望在该文本后面添加一个背景,该背景
- 遵循参差不齐的右边缘
- 在每行的左右边缘都添加填充
您不能简单地将背景和填充应用于,例如,<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(法语)撰写。
我一直想找一种方法在居中的文本上做到这一点。看起来 Fabien Doiron 的方法或盒装饰中断是唯一两种可以与此配合使用的技术。
您可以将 letter-spacing 和 text-shadow 结合使用以获得围绕行的填充效果。但是我对此很疯狂,并发现您还可以使用 text-indent 和内联元素上的负边距来获得一些有趣的结果: http://codepen.io/Merri/pen/tDHsC
此外,额外的内联元素允许更好地控制盒阴影,以便阴影颜色不会覆盖文本: http://codepen.io/Merri/pen/giuLj
非常棒的效果。而且很简单。
你可以用轮廓和一个单独的span标签来实现类似的效果。
http://codepen.io/impressivewebs/pen/nuFHq
不过很难让它看起来很好看。不幸的是,你无法为轮廓设置单独的边。但也许有人可以调整值使其看起来更美观。
奇怪的是,当你调整span标签的行高时,会发生这种奇怪的太空飞船仪表盘效果!
http://codepen.io/impressivewebs/pen/adrEg
这是一个很好的方法,Louis,感谢。
+1 为这种奇怪的太空飞船仪表盘效果!
是的,我之前也曾努力寻找这个问题的解决方案。
遗憾的是,上面这些方法中,只有阴影方法在增加行高时仍然有效——这样你就可以真正拥有多行文本,并在行之间有背景和空白区域。而且,这种方法仅适用于颜色,如果你想在整个行背景上显示背景图片,它就不起作用了。
我难以置信,CSS 还没有提供一种方法,让你可以指定希望内联元素跨越多行时,在每行的开头和结尾应用左右填充 :-(
我最终使用了诸如使用 JS 将文本拆分为包含单个“单词”的元素,并向它们添加侧边填充,以及尝试使用字间距或负边距将它们重新拉近,以便一行中单词之间的间距看起来再次与单个“空格”相同……但这些方法都存在各种跨浏览器问题。
这个问题去年在@HteuMeuLeu的博客(法语)上得到了讨论。
评论中有很多解决方案(主要在法语文章中)。
[英文]
http://www.hteumeuleu.fr/a-css-brain-teaser/
[法语]
http://www.hteumeuleu.fr/un-joli-casse-tete-en-integration/
我的解决方案是这个:http://jsfiddle.net/oilvier/qktGR/
但最好的可能是这个:http://dabblet.com/gist/2994237
我也发现很难在这里启用
border-radius
。我的第一反应是“谁每个月都问你‘你能让我的所有文本看起来都难看吗?’”。
但在文章的最后,我开始接受它了。它有一种“报纸剪报”的感觉。
@Louis 提到了轮廓。这些在浏览器中得到了广泛的支持。不幸的是,一些浏览器(Firefox)也存在一些舍入误差,这会导致轮廓和文本框之间出现 1 像素的间隙。好消息是可以通过在左侧和右侧添加 1 像素的阴影来修复它。
http://codepen.io/Merri/pen/porgF
这似乎是最安全的跨浏览器解决方案,在我测试过的所有东西上看起来都很好,从 IE8 开始。
再添加一个元素,你就可以得到一个漂亮的阴影:http://codepen.io/Merri/pen/Agrus
你可以避免使用阴影,只需使用outline-offset: -1px; 来关闭间隙。
Sergey Chikuyonok(Emmet 作者)的博客在 2010 年也讨论过同样的问题:“文本下方的统一背景”(俄语)。提出了两种解决方案:一种利用‘outline’属性,另一种使用嵌套元素和相对定位。
我最近在几个网站上都实现了这个效果。
简介文本:http://www.jwrihoy.com/
以及引号:http://sueco.gg/
两者都需要在空格之间添加线条,花了点时间才达到我想要的效果,但对结果很满意。引号有点作弊,使用了图片,但第一个是纯 CSS 实现的。
不错的文章!我曾经需要做类似的事情。
我有一个 h1 标签,其中的每个单词都用 span 元素包裹。这些 span 元素是浮动的,并且有左右填充来创建单词之间的空白。现在我看到有很多解决方案,但嘿!它有效。这是我的示例:http://rehabitare.com/
这个方法对我来说最有效。
span {
color: white;
background-color: #343132;
** box-shadow: 0.5em 0 0 #343132,-0.5em 0 0 #343132;**
}
http://stackoverflow.com/questions/12709313/css-background-color-on-multi-line-text
我需要这个功能有一段时间了!很棒的工作。
起初,阴影方法似乎效果最好,但当你在高 DPI 设备上查看它时,总是会出现一些重叠或间隙——我不能将其推荐为完整的解决方案。
看起来 iOS WebKit 中的阴影存在一个 bug,当足够放大时,它会完全裁剪掉阴影。在我的 iPad 上的笔中可以很容易地看到这一点:http://codepen.io/Merri/full/giuLj
这个问题在桌面端不会重现,并且尝试通过强制 GPU 绘制(
-webkit-transform: translate3d(0, 0, 0);
)来修复它没有任何效果。Fabien 的阴影方法无敌!2 秒钟搞定,对我来说有效!需要稍微调整一下填充,但我喜欢它:) 救命黑科技:)
你好,
谁能告诉我如何在 HTML 中为文本添加背景颜色,而不使用 CSS(不使用内联和外部 CSS)?
Leon Wilmanns 在比赛结束哨声响起后写道
https://jsfiddle.net/uuot1bwa/1/