標籤:比較 lock 長方形 https 工作原理 member 目標 實驗 支援
本文主要介紹了添加底線樣式的幾乎所有方法,並且比較了每一種方法的優缺點。沒想到之前一直沒有注意的底線還有這麼多玄機奧秘!
本文由 nzbin 翻譯,艾淩風 校稿。未經許可,禁止轉載!
英文出處:css-tricks.com
發表地址:http://web.jobbole.com/89425/
有很多種添加底線樣式的方法。可能你還記得《 Crafting link underlines on Medium 》這篇文章。Medium 並沒有嘗試特殊的方法,只是想建立一個漂亮的看起來正常的底線。
一條纖細的黑色底線並且與下行字母有間隙——引自 Marcin Wichary 的《 Crafting link underlines on Medium 》
這是基本的底線樣式,但是尺寸適中並且避開了下行字母。比大多數瀏覽器的預設效果要好。事實證明 Medium 為了獲得這種樣式遇到了很多麻煩。兩年過去了,添加一個好看的底線樣式仍然很困難。
目標
使用 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 ,一定要停下來看一看。有一個關於它 工作原理 的 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 早期的草案中就被提出來了,但是因為缺乏興趣而沒有實施。嘿,不要怪我!
總結
那麼添加底線最好的方法是什嗎?
視情況而定。
對於字型大小小的文本,我推薦使用 text-decoration
並且樂觀地使用 text-decoration-skip
。這種樣式在大多數瀏覽器中看上去有些乏味,但是因為底線樣式一直如此,所以使用者不會介意。如果你有足夠的耐心,所有的底線在以後看上去會很棒,而你不需要修改任何東西。
對於本文部分,可以使用 background-image
方法。這種方法看上去很棒,而且也有相應的 Sass mixins 。如果底線很細或者與文本的顏色不一樣,可以省略 text-shadow
屬性。
對於單行文本,使用 border-bottom
以及你希望配合使用的其它屬性。
如果想要在漸層或者圖片背景上避開下行字母,嘗試使用 SVG 濾鏡。或者避免使用底線。
將來,當瀏覽器的支援性更好,答案一定是 text-decoration-*
屬性。
網頁中添加底線的方法匯總及優缺點