Web Layout Design: Attacking line-clamp
Introduction
相信大家都有過這樣的需求 — 「如果文字超過容器寬度要怎麼去遮掉多餘的部分」。 最 low 的方法不外乎就是去 trim 制約長度,然後動態補上「…」。雖然可以在特定 inline-size 下滿足需求,但是一旦遇上 responsive 那類浮動的 inline-size 就立即破功,更不用說如果想要呈現的文字是多行的時候該怎麼調整?!比較搞的工程師可能搭配 JavaScript 監聽容器變化且動態去調整呈現的內容,也是一招啦!不過把效能運算用這種地方似乎又太過了,所以今天想跟大家聊聊筆者這些年來最常使用的方法 CSS > -webkit-line-clamp。
CSS > -webkit-line-clamp
只要是 CSS 便可以完成的事務,我一定不會讓 JavaScript 指染。彼此分進合擊方能獲取最大效益~如果想要 trim 掉容器內的多餘文字的話,我個人首推 -webkit-line-clamp 屬性,設定上簡單非常,更無視容器高度以及文字行距,輕輕鬆鬆達成下列需求:
對應的 CSS code 如下:
主要便是透過 LINE 9~13 來設置相關的屬性,便可以讓內容物超過 3 行的便會搭配「…」來將多餘的文字藏起來。更棒的是它完全是 responsive design ready。也就是說若容器寬度呈現浮動變化,那麼瀏覽器亦會作出對應的調整,完全不需要搭配 JavaScript 去進行監聽與調整。
APPLE App Store & line-clamp
不知道大家有沒有看過 APPlE App Store 對於藏字的呈現效果?它不僅完整了將多餘的字藏了起來,更在結尾之處做了淡出的效果並賦予了展開全部的 trigger。
不禁好奇心想要如何來達到這樣的呈現?畢竟現階段無法輕易地做到特定行數才賦予 padding-inline-end 的效果的屬性。試過了 float 或者 flex 硬推會來的擠壓都無法確切地達到上述的呈現效果,就在失望之際,突然看到了有人搭配 CSS mask 來達成這樣的效果,所以接下來就要來跟大家分享如何透過 -webkit-line-clamp 以及 mask 來完成這樣的效果。
Attacking line-clamp
從 codepen 上的火力展示可以發現其核心思想為:
- 一樣透過 -webkit-line-clamp 去依照所設定的行數去藏字。
- 搭配 mask 去把「更多」附近的區塊去隱藏。
也就是說如何製作出 responsive 的 mask 便是至關重要的條件了。
如上面範例所示,筆者簡單帶大家導讀一下相關的 code。
- Line 3~5:把 -webkit-line-clamp 以及預期要隔開的寬高變數透過 custom properties 進行抽離,方便日後 maintain 與調整。
- Line 10~26:設置 button 「更多」的樣式,並讓它對齊容器右下角。
- Line 33~38:一樣設定行數為 3 的 -webkit-line-clamp。如果一來只要行數超過 3 的文字便會有效地被遮起來。筆者搭配 custom property 把行數抽離出來,方便快速地進行調整。
- Line 40~51:這裡辨識 mask 的設置。基本來說有塗上顏色的便是我們希望保留的部分。這裡製作兩個色塊,分別是追隨容器大小的 A 以及 var( — padding-inline-size) X var( — line-height) 的 B。兩者皆對其容器的右下角位置。然後透過 mask-composite: exclude 讓 A 和 B 做 xor。便能取出我們希望得到的 mask(下圖紅色區塊)。
透過 -webkit-line-clamp 以及 mask 的交錯影響,最終便能做到 APPLE App Store 文字遮掩的效果了。
Conclusion
透過 CSS 的渲染讓文字的呈現變得更加靈活了,更不需要額外的 JavaScript 輔助,可以說既簡約且優雅。有興趣的朋友不妨試試,一同感受 CSS > -webkit-line-clamp 與 mask 的威力。