本文來自css-tricks,介紹了在不一樣的場景下實現下劃線的7種方式。css
有許多種不一樣的方式來實現下劃線,你也許還記得Crafting link underlines on Medium這篇文章。Medium也不是想作什麼瘋狂的事情,他們只是想讓他們的文字下面好看一點。web
這是一條基本的下劃線,它大小合適。絕對比瀏覽器的默認樣式好看的多。因此,看上去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
是最直接的實現方式,只用一個屬性就能實現給文字添加下劃線。當字體比較小的時候,看上去沒什麼問題,可是當字體變大的時候,看上去就有點笨拙了。
{% codepen lixuejiang aByLLO 0 %}
text-decoration
最大的問題是缺乏定製化,它直接使用文字的顏色和字體,不能跨瀏覽器修改樣式,更多內容後面會介紹
使用方便
定位在基線下面
在Safari和iOS裏跳過了descenders
多行也沒問題
全部的背景也ok
在其餘瀏覽器裏不能跳過descenders
不能修改顏色,厚度和樣式
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
須要兩個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 filter行內元素,把他該在文本上面。而後給這個元素設置一個ID,以後就能夠在css裏引用這個元素:url(‘#svg-underline’)
其中一個優點就是在不依賴text-shadow
的狀況下支持透明。這也就意味着在任何背景上均可以跳過descenders,包括漸變和背景圖。可是他只支持單行的文本
{% codepen lixuejiang bBrYEJ 0 %}
在 Chrome 和 Firefox裏看起來像這樣:
IE, Edge, 和 Safari的瀏覽器支持有問題,很難在css裏測試瀏覽器對SVG filter的支持。能夠用@supports
屬性。可是這隻能測試引用是否生效。而不是filter本身。這個方法不支持跨瀏覽器。
能夠定位在基線下面
跳過descenders
能夠改變顏色,厚度和樣式
支持任意背景
不支持多行
在 IE, Edge, 或者 Safari裏不生效,在這幾個瀏覽器裏能夠用text-decoration
Underline.js很屌,若是你還沒看過他的tech demo,趕忙停下來,去看一看。有一個很酷炫的時長9分鐘的介紹它是如何工做的視頻。在這裏我會簡短的介紹一下:它用<canvas>
標籤來畫下劃線。這是一種很新穎的方法,並且能效果出奇的好。
儘管有名氣。Underline.js只是個demo。你不能在不修改他們的代碼的狀況下直接在你的項目裏引用它。
在這裏把它做爲一種實現方式來討論仍是很值得的。<canvas>
能夠實現漂亮的可交互的下劃線。可是你必須得寫一些JavaScript代碼。
還記得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
容許你改變下劃線的顏色,能夠和文字顏色不同。它的跨瀏覽器支持比想象中的要好。在Firefox和Safari裏都能正常運行。
可是有一個問題:若是沒有清除descenders,Safari會把下劃線放在文字上面?
Firefox:
Safari:
text-decoration-skip
能夠跳過descenders
這個屬性是非標準的,如今只有Safari支持。因此須要加-webkit-前綴。Safari默認啓用這個屬性,這也就是爲何在沒有指定這個值的時候,下劃線也跳過了descenders
若是你在用Normalize,你應該知道最近的版本禁止了這個屬性,來保證各個瀏覽器的顯示一直。若是你想要一些夢幻般的下劃線,你能夠打開這個屬性
text-decoration-style
提供了像border-style
同樣的屬性。另外還添加了wavy lines
:
dashed
dotted
double
solid
wavy
目前只有FireFox支持這個屬性:
是否是看上去很眼熟?
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-*
屬性