有很多种添加下划线样式的方法. 可能你还记得《 Crafting link underlines on Medium https://medium.com/design/7c03a9274f9 》这篇文章. Medium 并没有尝试特殊的方法, 只是想创建一个漂亮的看起来正常的下划线.
一条纤细的黑色下划线并且与下行字母有间隙 -- 引自 Marcin Wichary 的《 Crafting link underlines on Medium https://medium.com/design/7c03a9274f9 》
这是基本的下划线样式, 但是尺寸适中并且避开了下行字母. 比大多数浏览器的默认效果要
目标
使用 text-decoration: underline 添加下划线有什么问题吗? 如果我们讨论一个理想的场景, 下划线应该符合以下特点:
位于文本基线以下
避开下行字母
可以改变颜色, 粗细及样式
适用于文本换行的情况
适用于任意背景
我认为这些要求非常合理, 但是据我所知, CSS 中还没有简单的方法实现上述所有要求.
方法
那么有哪些在网页中添加下划线的方法?
以下是我能想到的方法:
- text-decoration
- border-bottom
- box-shadow
- background-image
SVG 滤镜
- Underline.JS (canvas)
- text-decoration-*
让我们逐一分析这些方法的优缺点.
text-decoration
text-decoration 是添加文本下划线最直接的方式. 你只需要应用一个单独的属性就可以全部搞定. 字号较小的话, 下划线看起来不错, 但增加字号之后, 同样的下划线就很难看.
text-decoration 的最大问题是缺乏自定义. 它继承文字的颜色及字号, 并且无法通过跨浏览器的方式改变样式. 稍后做详细介绍.
优点
易于使用
位于文本基线以下
默认在 Safari 和 iOS 上会避开下行字母
可以换行
适用于任意背景
缺点
在其它浏览器中不能避开下行字母
不能改变颜色, 粗细或样式
border-bottom
border-bottom 介于快速及可自定义之间. 这种方法使用真正的 CSS border, 意味着你可以改变它的颜色, 粗细及风格样式.
以下就是 border-bottom 添加到 inline 元素上的效果.
最大的问题是下划线到文本的距离 -- 它完全在下行字母以下. 可以通过设置元素为 inline-block 以及减少 line-height 解决这个问题, 但是文本换行就不行了. 这种方法只适合单行文本, 不适合多行文本.
另外, 可以使用 text-shadow 覆盖下行字母附近的下划线, 但必须使用与背景色一样的颜色. 这意味着只在纯色背景上有效, 而不能应用于渐变色或者图片上.
现在, 需要四个属性来定义一个单下划线. 相比 text-decoration 的工作量要大.
优点
可以使用 text-shadow 避开下行字母
可以改变颜色, 粗细及样式
可以给颜色及粗细添加 transition 和 animate 属性
只要不使用 inline-block , 可以换行
只要不使用 text-shadow , 可以适用于任意背景
缺点
下划线距离文本较远, 难以定位
需要很多不想关的属性才能正确显示
使用 text-shadow 之后选择文本显得粗糙
box-shadow
box-shadow 使用两个内阴影画一条下划线: 一个用于创建长方形, 另一个覆盖在上面. 这意味着该属性必须在纯色背景上使用.
同样要使用 text-shadow 的方法伪造下划线与下行字母的间隙. 但是如果下划线与文本的颜色不一样, 或者太细, 并不会像 text-decoration 那样不协调.
优点
可以位于文本基线以下
使用 text-shadow 属性可以避开下行字母
可以改变颜色及粗细
可以换行
缺点
不能改变样式
不能适用于任意背景
background-image
background-image 是最容易满足我们要求的属性并且问题较少. 思路就是通过 linear-gradient 和 background-position 创建沿着文本水平复制的图像.
这个方法也要设置 display: inline;
下面的方法不必使用 linear-gradient , 你可以用自己的图片做出酷炫的效果.
优点
可以位于文本基线以下
使用 text-shadow 属性可以避开下行字母
可以改变颜色, 粗细 (允许半个像素) 及样式
适用于自定义图片
可以换行
只要不使用 text-shadow , 可以适用于任意背景
缺点
图片在不同的分辨率, 浏览器及缩放级别下可能大小不同
SVG filters
我一直在考虑使用 SVG 滤镜的方法. 可以创建一个行内 SVG 滤镜元素画一条线, 通过扩展文本边界遮盖下行字母附近的下划线. 然后给滤镜一个 id , 通过 filter: url('#svg-underline')在 CSS 中引用它.
滤镜的优点不需要借助 text-shadow 添加了透明间隙. 这意味着可以在任何背景上避开下行字母, 包括渐变及图片背景. 这种方法只适用于单行文本, 需要注意这一点.
以下是在 Chrome 和 Firefox 中的效果:
在 IE,Edge 和 Safari 上的浏览器支持有问题. 很难在 CSS 中测试 SVG 滤镜的支持情况. 可以使用 filter 的 @supports 属性, 但是只能检测引用是否可用, 而不能检测滤镜本身. 我最终的方法是使用一些浏览器嗅探检测, 所以也要注意这一点.
优点
位于文本基线以下
可以避开下行字母
允许改变颜色, 粗细及样式
适用于任意背景
缺点
不允许换行
在 IE,Edge 及 Safari 中无效, 但是你可以使用 text-decoration .Safari 中的下划线看起来很棒.
Underline.JS (Canvas)
Underline.JS 很迷人. 我觉得最印象深刻的是 Wenting Zhang 使用了 JavaScript 实现以及对细节的关注. 如果你还没有看过 Underline.JS 的 tech demo http://underlinejs.org/ , 一定要停下来看一看. 有一个关于它 工作原理 http://embed.wirewax.com/8013554/7bafa8/ 的 9 分钟的视频, 但是我可以简单说一下: 它是通过 <canvas> 元素添加下划线. 这是一种新方法, 效果非常好.
尽管 Underline.JS 有一个引人注目的名字, 但只是一个技术演示. 这意味着在修改完善之前还不能用在任何项目中.
这种方法作为概念证明有必要提出来.<canvas> 可以创建漂亮, 可交互的下划线, 但是需要写一些 JavaScript 才能正常工作.
text-decoration-* properties
还记得 "稍后做详细介绍" 这句话吗? 现在就讲到这里了.
text-decoration 自身可以表现的更好, 但是必须添加一些实验性的属性定制它的外观:
- text-decoration-color
- text-decoration-skip
- text-decoration-style
不要高兴的太早, 因为有浏览器兼容的问题.
text-decoration-color
text-decoration-color 允许你改变下划线的颜色. 这一属性比预期的浏览器支持要好 -- 它可以在 Firefox 以及 Safari (需加前缀)中工作. 需要注意的是: 如果没有清除下行字母, Safari 中的下划线会位于文本之上.
Firefox:
Safari:
text-decoration-skip
text-decoration-skip 设置文本下划线是否避开下行字母.
这是一个非标准属性, 只在 Safari 中正常工作, 所以要加 -webkit- 前缀. Safari 默认使用该属性, 所以即使没有设置, 下划线也会避开下行字母.
如果你正在使用 Normalize.CSS , 需要知道当前版本为了浏览器之间的一致性而禁用了该属性. 如果你想要这个优秀的下划线样式, 你需要自己设置一下.
text-decoration-style
text-decoration-style 提供了和 border-style 一样的线条样式, 但是也增加了 wavy 波浪线样式.
以下是你可以使用的不同属性值:
- dashed
- dotted
- double
- solid
- wavy
现在, text-decoration-style 只在 Firefox 上有效, 以下是截图:
眼熟吗?
还缺少什么?
text-decoration-* 属性比其它添加下划线的 CSS 属性要方便. 但是如果我们回顾一下之前的需求, 这个属性不能改变下划线的粗细及位置.
研究了一下之后, 我发现了下面两个属性:
- text-underline-width
- text-underline-position
这些属性好像在 CSS 早期的草案中就被提出来了, 但是因为缺乏兴趣而没有实施. 嘿, 不要怪我!
总结
那么添加下划线最好的方法是什么?
视情况而定 https://codepen.io/rachsmith/details/YweZbG/ .
对于字号小的文本, 我推荐使用 text-decoration 并且乐观地使用 text-decoration-skip . 这种样式在大多数浏览器中看上去有些乏味, 但是因为下划线样式一直如此, 所以用户不会介意. 如果你有足够的耐心, 所有的下划线在以后看上去会很棒, 而你不需要修改任何东西.
对于正文部分, 可以使用 background-image 方法. 这种方法看上去很棒, 而且也有相应的 Sass mixins https://codepen.io/jimmynotjim/pen/EabQjV . 如果下划线很细或者与文本的颜色不一样, 可以省略 text-shadow 属性.
对于单行文本, 使用 border-bottom 以及你希望配合使用的其它属性.
如果想要在渐变或者图片背景上避开下行字母, 尝试使用 SVG 滤镜. 或者避免使用下划线.
将来, 当浏览器的支持性更好, 答案一定是 text-decoration-* 属性.
来源: http://www.css88.com/web/css/16027.html