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-* 屬性

原文

相關文章
相關標籤/搜索