天天看點

純 CSS 實作多行文字截斷

做響應式系統設計的時候遇到需要對标題進行多行文字截取的效果,如下圖:

純 CSS 實作多行文字截斷
看似十分簡單的标題截斷效果,但是竟然沒有一個統一 CSS 屬性實作标準,需要用到一些奇淫妙計來實作,一般來說,在做這樣文字截斷效果時我們更多是希望:

  • 相容性好,對各大主流浏覽器有好的支援
  • 響應式截斷,根據不同寬度做出調整
  • 文本超出範圍才顯示省略号,否則不顯示省略号
  • 省略号位置顯示剛好

基于上述的準則,下面我就講介紹各種技巧實作截斷效果,并根據上述的評判标準得出最優解(代碼我都傳到 jsfiddle 平台,可點選 demo 位址檢視)。

單行文本截斷 text-overflow

文本溢出我們經常用到的應該就是

text-overflow:ellipsis

了,相信大家也很熟悉,隻需輕松幾行代碼就可以實作單行文本截斷。

  1. div {

  2.  white-space: nowrap;

  3.  overflow: hidden;

  4.  text-overflow: ellipsis;

  5. }

實作效果:

純 CSS 實作多行文字截斷

屬性浏覽器原生支援,各大浏覽器相容性好,缺點就是隻支援單行文本截斷,并不支援多行文本截取。

适用場景:單行文字截斷最簡單實作,效果最好,放心使用。

如果是多行文字截取效果,實作起來就沒有那麼輕松。

-webkit-line-clamp 實作

先介紹第一種方式,就是通過

-webkit-line-clamp

屬性實作。具體的方式如下:

  1. div {

  2.  display: -webkit-box;

  3.  overflow: hidden;

  4.  -webkit-line-clamp: 2;

  5.  -webkit-box-orient: vertical;

  6. }

它需要和

display

-webkit-box-orient

overflow

結合使用:

  • display:-webkit-box;

     必須結合的屬性,将對象作為彈性伸縮盒子模型顯示。
  • -webkit-box-orient;

     必須結合的屬性,設定或檢索伸縮盒對象的子元素的排列方式。
  • text-overflow:ellipsis;

     可選屬性,可以用來多行文本的情況下,用省略号“…”隐藏超出範圍的文本。
純 CSS 實作多行文字截斷

從效果上來看,它的優點有:

1. 響應式截斷,根據不同寬度做出調整。

2. 文本超出範圍才顯示省略号,否則不顯示省略号。

3. 浏覽器原生實作,是以省略号位置顯示剛好。

但是缺點也是很直接,因為 -webkit-line-clamp 是一個不規範的屬性,它沒有出現在 CSS 規範草案中。也就是說隻有 webkit 核心的浏覽器才支援這個屬性,像 Firefox, IE 浏覽器統統都不支援這個屬性,浏覽器相容性不好。

使用場景:多用于移動端頁面,因為移動裝置浏覽器更多是基于 webkit 核心,除了相容性不好,實作截斷的效果不錯。

定位元素實作多行文本截斷

另外還有一種靠譜簡單的做法就是設定相對定位的容器高度,用包含省略号(…)的元素模拟實作,實作方式如下:

  1. p {

  2.    position: relative;

  3.    line-height: 18px;

  4.    height: 36px;

  5.    overflow: hidden;

  6. }

  7. p::after {

  8.    content:"...";

  9.    font-weight:bold;

  10.    position:absolute;

  11.    bottom:0;

  12.    right:0;

  13.    padding:0 20px 1px 45px;

  14.    /* 為了展示效果更好 */

  15.    background: -webkit-gradient(linear, left top, right top, from(rgba(255, 255, 255, 0)), to(white), color-stop(50%, white));

  16.    background: -moz-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);

  17.    background: -o-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);

  18.    background: -ms-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);

  19.    background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);

  20. }

實作原理很好了解,就是通過僞元素絕對定位到行尾并遮住文字,再通過

overflow:hidden

隐藏多餘文字。

純 CSS 實作多行文字截斷

從實作效果來看,它所具備的優點:

1. 相容性好,對各大主流浏覽器有好的支援

2. 響應式截斷,根據不同寬度做出調整

但是它無法識别文字的長短,即文本超出範圍才顯示省略号,否則不顯示省略号。還有因為是我們人為地在文字末尾添加一個省略号效果,就會導緻它跟文字其實沒有貼合的很緊密,遇到這種情況可以通過添加

word-break:break-all;

使一個單詞能夠在換行時進行拆分。

純 CSS 實作多行文字截斷

适合場景:文字内容較多,确定文字内容一定會超過容器的,那麼選擇這種方式不錯。

float 特性實作多行文本截斷

回到一開始我要做的内容是多行标題文字截取效果,顯然是無法控制标題的長度的,顯然是無法使用上述的方式。回到事情的本質來看:我們希望 CSS 能夠有一種屬性,能夠在文字溢出的情況下顯示省略号,不溢出時不顯示省略号(兩種形式,兩種效果)。

正當我以為 CSS 已經無能為力,隻能通過 JS 去實作的時候,後來看到了一個方法非常巧妙,而且能夠滿足上述提到的所有準則,下面我就介紹如何通過 float 特性實作多行文本截斷效果。

基本原理:

純 CSS 實作多行文字截斷

有個三個盒子 div,粉色盒子左浮動,淺藍色盒子和黃色盒子右浮動:

1. 當淺藍色盒子的高度低于粉色盒子,黃色盒子仍會處于淺藍色盒子右下方。

2. 如果淺藍色盒子文本過多,高度超過了粉色盒子,則黃色盒子不會停留在右下方,而是掉到了粉色盒子下。

好了,這樣兩種狀态的兩種展示形式已經區分開了,那麼我們可以将黃色盒子進行相對定位,将内容溢出的黃色盒子移動到文本内容右下角,而未溢出的則會被移到外太空去了,隻要我們使用

overflow:hidden

就可以隐藏掉。

純 CSS 實作多行文字截斷

基本原理就是這樣,我們可以将淺藍色區域想象成标題,黃色區域想象為省略号效果。那麼你可能會覺得粉色盒子占了空間,那豈不是标題會整體延後了嗎,這裡可以通過 margin 的負值來出來,設定淺藍色盒子的

margin-left

的負值與粉色盒子的寬度相同,标題也能正常顯示。

那麼我們将前面的 DOM 結構簡化下,變成下面這樣:

  1. <div class="wrap">

  2.  <div class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dignissimos labore sit vel itaque delectus atque quos magnam assumenda quod architecto perspiciatis animi.</div>

  3. </div>

剛才的粉色盒子和黃色盒子都可以用僞元素來代替。

  1. .wrap {

  2.  height: 40px;

  3.  line-height: 20px;

  4.  overflow: hidden;

  5. }

  6. .wrap .text {

  7.  float: right;

  8.  margin-left: -5px;

  9.  width: 100%;

  10.  word-break: break-all;

  11. }

  12. .wrap::before {

  13.  float: left;

  14.  width: 5px;

  15.  content: '';

  16.  height: 40px;

  17. }

  18. .wrap::after {

  19.  float: right;

  20.  content: "...";

  21.  height: 20px;

  22.  line-height: 20px;

  23.  /* 為三個省略号的寬度 */

  24.  width: 3em;

  25.  /* 使盒子不占位置 */

  26.  margin-left: -3em;

  27.  /* 移動省略号位置 */

  28.  position: relative;

  29.  left: 100%;

  30.  top: -20px;

  31.  padding-right: 5px;

  32. }

純 CSS 實作多行文字截斷

這裡我目前看到最巧妙的方式了。隻需要支援 CSS 2.1 的特性就可以了,它的優點有:

1. 相容性好,對各大主流浏覽器有好的支援。

2. 響應式截斷,根據不同寬度做出調整。

3. 文本超出範圍才顯示省略号,否則不顯示省略号。

至于缺點,因為我們是模拟省略号,是以顯示位置有時候沒辦法剛剛好,是以可以考慮:

1. 加一個漸變效果,貼合文字,就像上述 demo 效果一樣。

2. 添加 

word-break:break-all;

 使一個單詞能夠在換行時進行拆分,這樣文字和省略号貼合效果更佳。

這個方法應該是我看到最好的用純 CSS 處理的方式了,如果你有更好的方法,歡迎留言交流!

原文釋出時間為:2018-11-05

本文作者:程式員阿宇

本文來自雲栖社群合作夥伴“

前端大學

”,了解相關資訊可以關注“

”。