7种方式实现web下划线

本文来自css-tricks,介绍了在不一样的场景下实现下划线的7种方式。css

简介

有许多种不一样的方式来实现下划线,你也许还记得Crafting link underlines on Medium这篇文章。Medium也不是想作什么疯狂的事情,他们只是想让他们的文字下面好看一点。web

http://ggbond.qiniudn.com/2016-11-27%2010:46:33.png
这是一条基本的下划线,它大小合适。绝对比浏览器的默认样式好看的多。因此,看上去Medium为了实现这个效果也经历了许多困难。两年后,实现一个好看的下划线依然同样困难canvas

目标

为何不能直接用text-decoration: underline呢?若是咱们谈论的是理想场景,underline须要知足下面这些场景:浏览器

  • 在基线下面定位svg

  • 跳过descenders测试

  • 改变颜色,厚度(thickness)和样式字体

  • 重复包裹文字动画

  • 在任何背景下都生效url

我认为这些需求都是很合理的,可是到目前为止,没有一种直观的方式用css来实现上面的全部目标spa

方法

所以,能实现下划线的方法都有哪些?

  • text-decoration

  • border-bottom

  • box-shadow

  • background-image

  • SVG filters

  • Underline.js (canvas)

  • text-decoration-*

让咱们来一个个的讨论这些方法的好处和坏处

text-decoration

text-decoration是最直接的实现方式,只用一个属性就能实现给文字添加下划线。当字体比较小的时候,看上去没什么问题,可是当字体变大的时候,看上去就有点笨拙了。

{% codepen lixuejiang aByLLO 0 %}

text-decoration最大的问题是缺乏定制化,它直接使用文字的颜色和字体,不能跨浏览器修改样式,更多内容后面会介绍

好处

  • 使用方便

  • 定位在基线下面

  • 在Safari和iOS里跳过了descenders

  • 多行也没问题

  • 全部的背景也ok

坏处

  • 在其余浏览器里不能跳过descenders

  • 不能修改颜色,厚度和样式

border-bottom

border-bottom在快速和定制化之间提供了一个很好的平衡。这个方法用了css边框,你能够修改颜色,厚度和样式。
inline元素的border-bottom长这样

{% codepen lixuejiang XNaeVW 0 %}

最大的问题是下划线离文本有多远--下划线就在descenders下面。你能够经过让元素变成inline-block而后减小line-height来改变这个距离。可是你就失去了包裹文本的能力。单行元素没问题,其余状况就不行了。

{% codepen lixuejiang xRLXYZ 0 %}

另外,你能够用text-shadow来盖住descenders附近的部分,可是你须要用和背景色同样的颜色。这一位置他只能在固定颜色的背景上生效,渐变的背景和背景图没用。

好处

  • text-shadow能够跳过descenders

  • 能够改变颜色,厚度和样式

  • 能够对颜色和厚度实施渐变和动画

  • inline-block自动包裹

  • text-shadow能够支持任意背景

坏处

  • 定位很远,并且很难重定位

  • 须要使用一系列不相干的属性

  • Janky text selection when using text-shadow ??

box-shadow

box-shadow须要两个inset box shadows来实现下划线:其中一个建立一个矩形,另一个盖在上面。这种方法要能生效的前提是使用固定颜色的背景

{% codepen lixuejiang eBEeOp 0 %}
你也能够用text-shadow来模拟文字的descenders和underline之间的空白。可是若是下划线和文字的颜色不同的时候,或者空白最够薄的时候,他就不能像text-decoration同样很好的工做了。

好处

  • 能够定位在基线下面

  • text-shadow能够跳过descenders

  • 能够改变颜色,厚度

  • 多行也能生效

坏处

  • 不能修改样式

  • 不能在渐变和背景图的状况下生效

背景图

background-image是最接近咱们想要的并且问题最少的实现方式。想法是用线性渐变和background-position来建立一个在水平方向重复的背景图。而后设置元素display: inline

{% codepen lixuejiang LbjOEj 0 %}

下面这个方法没有用线性渐变,而是用的背景图,你能够用你本身的图片来实现一些很酷的效果:
{% codepen lixuejiang RoZjNy 0 %}

好处

  • 能够定位在基线下面

  • text-shadow能够跳过descenders

  • 能够改变颜色,厚度(容许0.5像素)和样式

  • 可使用自定义图片

  • 多行也能生效

  • text-shadow能够支持任意背景

坏处

  • 在不一样的分辨率,不一样的浏览器和不一样的缩放状况下,图片的尺寸不同

SVG filters

这种方法我一直在研究。你能够建立一个画了一条线的SVG filter行内元素,把他该在文本上面。而后给这个元素设置一个ID,以后就能够在css里引用这个元素:url(‘#svg-underline’)
其中一个优点就是在不依赖text-shadow的状况下支持透明。这也就意味着在任何背景上均可以跳过descenders,包括渐变和背景图。可是他只支持单行的文本

{% codepen lixuejiang bBrYEJ 0 %}

在 Chrome 和 Firefox里看起来像这样:
http://ggbond.qiniudn.com/2016-11-27%2013:27:08.png
IE, Edge, 和 Safari的浏览器支持有问题,很难在css里测试浏览器对SVG filter的支持。能够用@supports属性。可是这只能测试引用是否生效。而不是filter本身。这个方法不支持跨浏览器。

好处

  • 能够定位在基线下面

  • 跳过descenders

  • 能够改变颜色,厚度和样式

  • 支持任意背景

坏处

  • 不支持多行

  • 在 IE, Edge, 或者 Safari里不生效,在这几个浏览器里能够用text-decoration

Underline.js (Canvas)

Underline.js很屌,若是你还没看过他的tech demo,赶忙停下来,去看一看。有一个很酷炫的时长9分钟的介绍它是如何工做的视频。在这里我会简短的介绍一下:它用<canvas>标签来画下划线。这是一种很新颖的方法,并且能效果出奇的好。

尽管有名气。Underline.js只是个demo。你不能在不修改他们的代码的状况下直接在你的项目里引用它。
在这里把它做为一种实现方式来讨论仍是很值得的。<canvas>能够实现漂亮的可交互的下划线。可是你必须得写一些JavaScript代码。

text-decoration-* 属性

还记得text-decoration里提到的后面会详细介绍吗?
text-decoration自身也能很好的工做,你也能够添加一些实验性的属性来定义样式:

Remember the “more on that later” part? Well, here we are.

  • text-decoration-color

  • text-decoration-skip

  • text-decoration-style

也不要太激动。须要考虑浏览器兼容性

TEXT-DECORATION-COLOR

text-decoration-color容许你改变下划线的颜色,能够和文字颜色不同。它的跨浏览器支持比想象中的要好。在Firefox和Safari里都能正常运行。
可是有一个问题:若是没有清除descenders,Safari会把下划线放在文字上面?
Firefox:
http://ggbond.qiniudn.com/2016-11-27%2013:47:03.png

Safari:
http://ggbond.qiniudn.com/2016-11-27%2013:47:57.png

TEXT-DECORATION-SKIP

text-decoration-skip能够跳过descenders
http://ggbond.qiniudn.com/2016-11-27%2013:49:05.png

这个属性是非标准的,如今只有Safari支持。因此须要加-webkit-前缀。Safari默认启用这个属性,这也就是为何在没有指定这个值的时候,下划线也跳过了descenders
若是你在用Normalize,你应该知道最近的版本禁止了这个属性,来保证各个浏览器的显示一直。若是你想要一些梦幻般的下划线,你能够打开这个属性

TEXT-DECORATION-STYLE

text-decoration-style提供了像border-style同样的属性。另外还添加了wavy lines:

  • dashed

  • dotted

  • double

  • solid

  • wavy

目前只有FireFox支持这个属性:
http://ggbond.qiniudn.com/2016-11-27%2013:55:21.png

是否是看上去很眼熟?

少了什么?

text-decoration-*这一系列属性确实比用其余的css属性来实现下划线要直观。可是看一看咱们一开始的需求。这些属性不支持定义厚度和位置。

通过一番研究,发现了下面两个属性:

  • text-underline-width

  • text-underline-position

他们出如今早起的css草案里,可是由于缺乏利润而没被实现。不用怪他们(指浏览器厂商)。

结论

因此实现下划线最好的方式是什么?

这就要看实际状况了
对于字体小的问题,我推荐text-decoration,而后用text-decoration-skip。在大多数浏览器里看起来有点平淡。可是下划线就那样,人们也不会介意。可是若是你足够耐心,老是有机会的。总有一天,下划线在不须要更改任何东西的状况下变得很帅气。

对于body text,能够用background-image。它能生效,并且很不错,还有Sass mixins。若是下划线很细或者须要和文本不同 的颜色的时候,还能够用text-shadow

对于单行的文本,能够用border-bottom.
若是想跳过渐变和背景图上的descenders,用SVG filters。
未来的浏览器支持足够好了,答案是text-decoration-* 属性

原文

相关文章
相关标签/搜索