網頁中新增下劃線樣式的方法

敘帝利發表於2016-12-17

在網頁中新增下劃線

有很多種新增下劃線樣式的方法。可能你還記得《 Crafting link underlines on Medium 》這篇文章。Medium 並沒有嘗試特殊的方法,只是想建立一個漂亮的看起來正常的下劃線。

1372dd76-784d-11e6-80ad-cdbcb93668ff

一條纖細的黑色下劃線並且與下行字母有間隙——引自 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 是新增文字下劃線最直接的方式。你只需要應用一個單獨的屬性就可以全部搞定。字號較小的話,下劃線看起來不錯,但增加字號之後,同樣的下劃線就很難看。

See the Pen Underlines 1: text-decoration by John D. Jameson (@johndjameson) on CodePen.

text-decoration 的最大問題是缺乏自定義。它繼承文字的顏色及字號,並且無法通過跨瀏覽器的方式改變樣式。稍後做詳細介紹。

優點

  • 易於使用
  • 位於文字基線以下
  • 預設在 Safari 和 iOS 上會避開下行字母
  • 可以換行
  • 適用於任意背景

缺點

  • 在其它瀏覽器中不能避開下行字母
  • 不能改變顏色、粗細或樣式

border-bottom

border-bottom 介於快速及可自定義之間。這種方法使用真正的 CSS border,意味著你可以改變它的顏色、粗細及風格樣式。

以下就是 border-bottom 新增到行內元素上的效果。

See the Pen Underlines 2: border-bottom by John D. Jameson (@johndjameson) on CodePen.

最大的問題是下劃線到文字的距離——它完全在下行字母以下。可以通過設定元素為 inline-block 以及減少 line-height 解決這個問題,但是文字換行就不行了。這種方法只適合單行文字,不適合多行文字。

See the Pen Underlines 3: border-bottom (inline-block) by John D. Jameson (@johndjameson) on CodePen.

另外,可以使用 text-shadow 覆蓋下行字母附近的下劃線,但必須使用與背景色一樣的顏色。這意味著只在純色背景上有效,而不能應用於漸變色或者圖片上。

See the Pen Underlines 4: border-bottom (text-shadow) by John D. Jameson (@johndjameson) on CodePen.

現在,需要四個屬性來定義一個單下劃線。相比 text-decoration 的工作量要大。

優點

  • 可以使用 text-shadow 避開下行字母
  • 可以改變顏色、粗細及樣式
  • 可以給顏色及粗細新增 transition 和 animate 屬性
  • 只要不使用 inline-block ,可以換行
  • 只要不使用 text-shadow ,可以適用於任意背景

缺點

  • 下劃線距離文字較遠,難以定位
  • 需要很多不想關的屬性才能正確顯示
  • 使用 text-shadow 之後選擇文字顯得粗糙

box-shadow

box-shadow 使用兩個內陰影畫一條下劃線:一個用於建立長方形,另一個覆蓋在上面。這意味著該屬性必須在純色背景上使用。

See the Pen Underlines 5: box-shadow by John D. Jameson (@johndjameson) on CodePen.

同樣要使用 text-shadow 的方法偽造下劃線與下行字母的間隙。但是如果下劃線與文字的顏色不一樣,或者太細,並不會像 text-decoration 那樣不協調。

優點

  • 可以位於文字基線以下
  • 使用 text-shadow 屬性可以避開下行字母
  • 可以改變顏色及粗細
  • 可以換行

缺點

  • 不能改變樣式
  • 不能適用於任意背景

background-image

background-image 是最容易滿足我們要求的屬性並且問題較少。思路就是通過 linear-gradientbackground-position 建立沿著文字水平復制的影象。

這個方法也要設定 display: inline

See the Pen Underlines 6: background-image by John D. Jameson (@johndjameson) on CodePen.

下面的方法不必使用 linear-gradient,你可以用自己的圖片做出酷炫的效果。

See the Pen Underlines 7: background-image (External) by John D. Jameson (@johndjameson) on CodePen.

優點

  • 可以位於文字基線以下
  • 使用 text-shadow 屬性可以避開下行字母
  • 可以改變顏色、粗細(允許半個畫素)及樣式
  • 適用於自定義圖片
  • 可以換行
  • 只要不使用 text-shadow ,可以適用於任意背景

缺點

  • 圖片在不同的解析度、瀏覽器及縮放級別下可能大小不同

SVG filters

我一直在考慮使用 SVG 濾鏡的方法。可以建立一個行內 SVG 濾鏡元素畫一條線,通過擴充套件文字邊界遮蓋下行字母附近的下劃線。然後給濾鏡一個 id ,通過 filter: url(‘#svg-underline’) 在 CSS 中引用它。

濾鏡的優點不需要藉助 text-shadow 新增了透明間隙。這意味著可以在任何背景上避開下行字母,包括漸變及圖片背景。這種方法只適用於單行文字,需要注意這一點。

See the Pen Underlines 8: SVG Filters by John D. Jameson (@johndjameson) on CodePen.

以下是在 Chrome 和 Firefox 中的效果:

underlines

在 IE、Edge 和 Safari 上的瀏覽器支援有問題。很難在 CSS 中測試 SVG 濾鏡的支援情況。可以使用 filter 的 @support 屬性,但是隻能檢測引用是否可用,而不能檢測濾鏡本身。我最終的方法是使用一些瀏覽器嗅探檢測,所以也要注意這一點。

優點

  • 位於文字基線以下
  • 可以避開下行字母
  • 允許改變顏色、粗細及樣式
  • 適用於任意背景

缺點

  • 不允許換行
  • 在 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-* 屬性

還記得“稍後做詳細介紹”這句話嗎?現在就講到這裡了。

text-decoration 自身可以表現的更好,但是必須新增一些實驗性的屬性定製它的外觀:

  • text-decoration-color
  • text-decoration-skip
  • text-decoration-style

不要高興的太早,因為有瀏覽器相容的問題。

text-decoration-color

text-decoration-color 允許你改變下劃線的顏色。這一屬性比預期的瀏覽器支援要好——它可以在 Firefox 以及 Safari (需加字首)中工作。需要注意的是:如果沒有清除下行字母,Safari 中的下劃線會位於文字之上。

Firefox:

firefox

Safari:

safari

text-decoration-skip

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 上有效,以下是截圖:

familiar

眼熟嗎?

還缺少什麼?

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

打賞支援我翻譯更多好文章,謝謝!

打賞譯者

打賞支援我翻譯更多好文章,謝謝!

網頁中新增下劃線樣式的方法

相關文章