Kalan's Blog

Software Engineer / Taiwanese / Life in Fukuoka

Current Theme light

把行高設為 1 時常出現在行數只有一行時,為了方便排版,避免上下的空白不符合自己想要的高度,特別是容器有指定高度時會使用的方法。例如按鈕、標籤等等。

網頁中的 line-height 是什麼?

在 W3C 裡有明確的定義

All elements have a 'line-height' property that, in principle, gives the total height of a line of text. Space is added above and below the text of the line to arrive at that line height.

例如把行高設為 1.5,字體大小為 16px,那麼行高則為 16px * 1.2 = 24px ,把 24px-16px=8px 之後再將 8px 切成一半分配到字的上面與下面,又稱為 half-leading。可以參考下圖:

灰色的方塊就是行高,也就是被稱作 half-leading 的部分。W3C 裡面定義的 half-leading 容易跟一般排版印刷的搞混,一般排版印刷裡講的 leading 通常指的是 baseline(下圖的紅線)到下一行的 baseline 的距離。

為什麼不建議設為 1 ?

雖然把 line-height 設定成 1 很簡單,但我覺得這個假設是建立在「文字就只會有一行」的前提上。

然而事實上卻不一定如此,有些人螢幕小可能塞不下那麼多字;有人可能使用習慣上會把文字放很大;有些文字可能來自於使用者輸入,這些情況下原本假定是一行的文字也可能會換行,如果再把行高設成 1,那麼文字就會擠在一團難以閱讀。

另外一種情況是翻譯,有些文字翻譯過後可能會變得更長,如果在實作時是直接寫死 height 反而有可能導致跑版,兩行文字直接超越容器高度。

text-overflow 設為 ellipsis

可能有人會想,既然要保證為一行的話,也可以加入 text-overflow 確保文字超出時用 取代。視情況來看這可能是一個方法,但我最近的體悟是這會因為語系而有不同效果。

舉例來說,日文是一個膠著語,句型會取決於語尾的變化,所以時常最重要的部分都在句子的後面,加上 ellipsis 之後就變成超級容易截掉最重要的資訊。

  • 私はイケメンです 我是帥哥
  • 私はイケメンではありません 我不是帥哥

如果剛好文字截在で,那麼就變成了

  • 私はイケメンで…

到底是帥哥還不是帥哥呢?請讓我知道

解決方法

最簡單解決方式就是盡量不要先行假設文字只會有一行,在設計 UI 時也儘可能讓文字有更多表現空間。另外一個方法就是讓行高成為高度的一部分,容器的高度是取決於文字行高而不是直接寫死 height

就是因為高度對不起來或跑版才會把 line-height 設成 1 啊!

的確,說起來簡單,但最關鍵的問題還是在於 half-leading 會包含在容器的上下,然而大部分的情況下我們只想要保留文字與文字中間的 half-leading 而已。

我們可以利用 CSS 來抵銷 half-leading 所帶來的高度改變。CSS 中有一個非常好用的屬性 1lh ,雖然是相對比較新的單位,但已經支援現代瀏覽器。

用偽元素把多出來的部分用負 margin 抵銷,至於計算方式我們可以用 (1em - 1lh) / 2 來得到 half-leading 的值是什麼。

.btn {
	...
  line-height: 2;

  &::before {
    display: block;
    content: "";
    width: 0;
    height: 0;
    margin-top: calc((1em - 1lh) / 2);
  }
  
  &::after {
    display: block;
    content: "";
    width: 0;
    height: 0;
    margin-bottom: calc((1em - 1lh) / 2);
  }
}

效果會像這樣,儘管 line-height 是 2,我們也成功把上下的 half-leading 消除了!

另外一個方法是仍在草案text-box-trim 屬性,目前只有 Safari Preview 才支援,他的效果就是把上下的 half-leading 給去掉。Github 上面的圖非常生動地展示了它的效果:

這樣一來就不用再煩惱 line-height 造成的高度問題了!雖然等到各個瀏覽器廠商實作還要一段時間,甚至也有可能一直停留在草案沒有下文,但至少可以期待一下。

結論


雖然這篇文章是在反思 line-height 跟 text-overflow 的用法,不過在大部分的情況下其實蠻好用而且蠻夠用的,本文試著提出另外一種思考方式,希望可以給讀者帶來一些新想法。

Prev

RSS 復興與注意權

Next

最糟糕的程序員讀後感

If you found this article helpful, please consider buy me a drink ☕️ It'll make my ordinary day shine✨

Buy me a coffee

作者

Kalan 頭像照片,在淡水拍攝,淺藍背景

愷開 | Kalan

Hi, I'm Kai. I'm Taiwanese and moved to Japan in 2019 for work. Currently settled in Fukuoka. In addition to being familiar with frontend development, I also have experience in IoT, app development, backend, and electronics. Recently, I started playing electric guitar! Feel free to contact me via email for consultations or collaborations or music! I hope to connect with more people through this blog.