对链接下方的下划线进行样式设置可能是一项棘手的工作,而我经常会视情况而忘记最佳方法。 不过,值得庆幸的是, 约翰·詹姆森 ( John Jameson)使我们加快了这篇宾客帖子的速度。
有多种不同的样式可以用来标记下划线。 也许您还记得这篇文章Crafting链接在Medium上强调 。 中型并没有做任何疯狂的事情; 他们只是想在其文字下方创建一个看起来很普通的线条。

这是一个非常基本的下划线,但是它的大小合适,并且也跳过了下划线。 绝对好于大多数浏览器的默认设置。 好吧,事实证明,要在网络上获得该样式,Medium必须经历很多麻烦。 两年后,要绘制漂亮的底线仍然很困难。
目标
仅使用text-decoration: underline
什么问题? 如果我们在谈论理想情况,则下划线应该能够执行以下操作:
- 将自身置于基线以下
- 跳过后代
- 更改颜色,厚度和样式
- 重复换行文字
- 在任何背景下工作
我认为这些都是非常合理的要求,但是据我所知,没有直观的方法可以在CSS中实现所有这些。
方法
那么,我们可以在网络上加下划线的所有不同方式有哪些?
这是我能想到的:
-
text-decoration
-
border-bottom
-
box-shadow
-
background-image
- SVG过滤器
- Underline.js(画布)
-
text-decoration-*
让我们一一列出,并讨论每种方法的优缺点。
文字装饰
text-decoration
是在文本下划线的最直接方法。 您只需应用一个属性,便可以使用它。 在较小的尺寸下,它看起来很不错,但是增加了字体大小,同一行开始显得笨拙。
参见演示 。
text-decoration
的最大问题是缺乏可定制性。 它使用其所应用的任何文本的颜色和字体大小,并且没有跨浏览器的方式来更改样式。 以后再说。
好
- 易于使用
- 定位在基线以下
- 在Safari和iOS中默认跳过后裔
- 跨行包装
- 适用于任何背景
坏
- 无法在其他浏览器中跳过后代
- 无法更改颜色,厚度或样式
底边
border-bottom
在快速和可自定义之间提供了良好的平衡。 这种方法使用了久经考验CSS边框,这意味着您可以轻松更改颜色,厚度和样式。
这是inline
元素上的border-bottom
外观:
参见演示 。
最大的问题是,下划线与文本的距离有多远-完全位于下划线的下方 。 您可以通过将元素设置为inline-block
并减小line-height
,但随后您将无法包装文本。 适用于单行,但别无其他。
参见演示 。
此外,您可以使用text-shadow
来遮盖下移线附近的行的一部分,但是您必须使用与背景颜色相同的颜色来伪造它。 这意味着它仅适用于纯色背景,不适用于渐变或图像。
参见演示 。
此时,有四个属性为单个下划线设计样式。 这比text-decoration
要多得多。
好
- 可以使用
text-shadow
跳过后代 - 可以更改颜色,厚度和样式
- 可以过渡和动画化颜色和厚度
- 默认包装,除非它是
inline-block
- 可以在任何背景下使用,除非使用
text-shadow
坏
- 位置较远且难以重新定位
- 许多无关的属性使其正确无误
- 使用
text-shadow
时选择混乱的文本
盒子阴影
box-shadow
绘制带有两个内嵌框阴影的下划线:一个用于创建矩形,另一个用于覆盖矩形。 这意味着您需要扎实的背景才能工作。
请参阅CodePen上的John D. Jameson( @johndjameson ) 撰写的Pen Underlines 5:box-shadow 。
您可以使用相同的text-shadow
技巧来伪造下划线和文本后代之间的间隙。 但是,如果线条的颜色与文本不同,或者甚至足够细,它实际上不会像text-decoration
那样发生冲突。
好
- 可以位于基线以下
- 可以使用
text-shadow
跳过后代 - 可以改变颜色和厚度
- 跨行包装
坏
- 不能改变风格
- 在任何背景下均无效
背景图像
background-image
与我们想要的一切最接近,并且获取的麻烦最少。 想法是使用linear-gradient
和background-position
来创建图像,该图像在文本行之间水平地重复。
您将必须display: inline;
这种方法也是。
参见演示 。
这种方法也不必使用linear-gradient
。 您可以带来自己的背景图片以获得一些很酷的效果。
参见演示 。
好
- 可以位于基线以下
- 可以使用
text-shadow
跳过后代 - 可以更改颜色,厚度(允许半个像素)和样式
- 使用自定义图像
- 跨行包装
- 可以在任何背景下使用,除非使用
text-shadow
坏
- 图像在分辨率,浏览器和缩放级别上可以不同地调整大小
SVG过滤器
这是我一直在尝试的一种方法:SVG过滤器。 您可以创建一个内联SVG filter
元素,该元素绘制一条线,然后展开文本以遮盖我们希望透明的部分线。 然后,您可以为filter
指定一个id
,并在CSS中使用类似filter: url('#svg-underline')
引用filter: url('#svg-underline')
。
这样做的好处是,过滤器无需依赖text-shadow
即可增加透明度。 这意味着您可以在任何背景(包括渐变和背景图像)的顶部跳过降序! 不过,此代码仅适用于一行文本,因此请单方面注意。
参见演示 。
这是在Chrome和Firefox中的外观:

IE,Edge和Safari中的浏览器支持存在问题。 很难在CSS中测试SVG过滤器支持。 您可以将@supports
与filter
@supports
使用,但这只会测试引用是否有效,而不是所应用的过滤器本身。 我的方法最终会使浏览器略微嗅探,因此也要加倍小心。
优点
- 定位在基线以下
- 跳过后代
- 能够更改颜色,厚度和样式
- 适用于任何背景
缺点
- 不跨越线
- 在IE,Edge或Safari中不起作用,但是您可以使用
text-decoration
。 Safari的底线看起来仍然不错。
Underline.js(画布)
Underline.js令人着迷。 我认为Wenwen Zhang用JavaScript能够做的事以及对细节的关注给人留下了深刻的印象。 如果您以前没有看过Underline.js 技术演示 ,请绝对停止阅读一分钟并进行检查。 关于它的工作原理 ,有一个长达九分钟的有趣的演讲,但我会给您一个简短的版本:它使用<canvas>
元素画出下划线。 这是一种新颖的方法,效果惊人。
尽管名称很吸引人,但是Underline.js只是一个技术演示 。 这意味着您必须先对其进行大量修改,才能将其放入任何项目中。
值得在这里提出它作为概念证明。 <canvas>
有可能创建漂亮的交互式下划线,但是您必须编写一些自定义JavaScript才能使它们起作用。
text-decoration- *属性
还记得“稍后再说”的部分吗? 好吧,我们到了。
text-decoration
本身可以很好地工作,但是您可以添加一些实验属性来自定义其外观:
-
text-decoration-color
-
text-decoration-skip
-
text-decoration-style
只是不要太兴奋。 您知道, 浏览器支持 。
文字装饰颜色
text-decoration-color
可以将下划线的颜色与其文本颜色分开更改。 该属性甚至具有比预期更好的浏览器支持-它可在Firefox中工作,并在Safari中作为前缀。 这里有个要注意的地方:如果您不清除后代,Safari会将行放在文本的顶部 。 🙃
Firefox:

苹果浏览器:

文本装饰跳过
text-decoration-skip
切换在带下划线的文本中切换跳过的下降器。

此属性是非标准属性,目前仅在Safari中-webkit-
,因此您需要-webkit-
前缀才能使用它。 Safari默认情况下会启用此属性,这就是为什么即使在未指定下划线的网站上,下划线也会跳过下划线的原因。
如果您使用的是Normalize,请知道最新版本会禁用该属性,以使浏览器之间的内容保持一致。 如果您想要这些梦幻般的下划线,则需要重新打开它。
文字装饰风格
text-decoration-style
提供了与border-style
相同的线条,但也添加了wavy
线。
您可以使用以下不同的值:
-
dashed
-
dotted
-
double
-
solid
-
wavy
目前, text-decoration-style
仅在Firefox中有效,因此以下是屏幕截图:

各种纯色下划线样式
看起来熟悉?
少了什么东西?
与使用其他CSS属性设置下划线样式相比, text-decoration-*
属性要直观得多。 但是,如果我们再看一下我们先前的要求,则这些属性无法提供指定线宽或位置的方法。
经过一些研究,我发现了以下两个属性:
-
text-underline-width
-
text-underline-position
看起来好像他们是在CSS的早期草案中提出的,但是由于缺乏兴趣而从未实现。 嘿,别怪我。
外卖
那么在文本下划线的最佳方法是什么?
对于小文本,我建议使用text-decoration
,然后乐观地在顶部应用text-decoration-skip
。 在大多数浏览器中,它看起来有些乏味,但强调始终看起来像这样,人们似乎并不介意。 另外,总是有机会,如果您足够耐心,以后所有下划线都将变得很棒,而您无需进行任何更改。
对于正文,可能使用background-image
方法。 它可以工作,看起来很棒,并且有Sass mixins 。 如果下划线较细或颜色与文本不同,则可以省略text-shadow
。
对于单行文本,请使用border-bottom
以及您想使用的其他任何属性。
而要跳过渐变或背景图像顶部的下降器,请尝试使用SVG滤镜。 或者只是避免完全使用下划线。
将来,当浏览器支持更好时,答案一直是text-decoration-*
。
另请参阅本杰明·伍德拉夫(Benjamin Woodruff)的文章CSS Underlines Suck ,它以类似的方式巧合地践踏了这一点。