css高級應用三種方法實現多行省略

未經容許,請勿私自轉載css

前言

這是個老掉牙的需求啦,不過仍然有不少人在網上找解決方案,特別是搜索結果排名靠前的那些,都是些只會介紹兼容性很差的使用-webkit-line-clamp的方案。html

若是你看到這篇文章,可能表明你正是從那麼多千篇一概的文章中跳轉過來的,想找更好地方案的。那恭喜你,沒有更好的,只有更合不合適的,固然,前提是個人文章流量夠多,能被頂上去你纔有機會看到。web

這裏介紹三種多行文本截斷的方法,固然第一種就是你看到想吐的-webkit-line-clamp方案,不想看就直接跳到第二種方法開始看啦。瀏覽器

使用-webkit-line-clamp

對多行文本的容器應用以下樣式bash

div {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
  -webkit-line-clamp: 2;
}
複製代碼

除了-webkit-line-clamp其餘屬性固定不變,主要是將對象做爲彈性伸縮盒子模型顯示,並設置伸縮盒對象的子元素的排列方式。佈局

-webkit-line-clamp是用來控制多少行進行省略字體

優勢:

  • 瀏覽器原生支持的省略行爲,樣式看起來很舒服
  • 簡單方便使用

缺點:

  • 看屬性的前綴就知道,這是webkit內核的瀏覽器支持的,兼容性不是普遍。

使用場景

若是你只針對webkit內核瀏覽器或者移動端(移動端瀏覽器多數是webkit內核),那麼使用該方案是最好的了。優化


利用絕對定位

這個方案其實很好理解的,首先咱們對於一個裝內容的容器右邊預留一個空間用來放省略號,用padding-right: 1em;來預留空間,爲啥是1em呢,一個省略號差很少就是1em啦,用em單位是爲了響應字體大小。ui

用絕對定位把省略號定位在這個預留的空間右下角。spa

html

<div class="wrap">內容</div>
複製代碼

css

.wrap3 {
    position: relative;
    padding-right: 1em;
    /*max-height是line-height的幾倍,想最多顯示多少行就幾倍*/
    max-height: 3.6em;
    line-height: 1.2em;
    text-align: justify;
    overflow: hidden;
}

.wrap3:before {
    position: absolute;
    right: 0;
    bottom: 0;
    content: '...';
}
複製代碼

效果(多內容時):

這樣的話,省略號永遠都會存在的。 因此要解決這個問題,咱們用一個跟背景顏色同樣的方塊遮住省略號,那麼關鍵點就是,怎麼知道什麼時候要遮住,什麼時候不遮住呢?

思路: 用於擋住省略號的方塊也是絕對定位,靠右定爲,right: 0,可是bottom值就不要設置了,若是不設置的話,該方塊會跟着文本內容的實際高度移動,而不是max-height的高度。這樣的話,當不須要省略時(即不超過max-height)時,就恰好是bottom: 0的狀況,就會擋住省略號。當要進行省略時(即超過max-height)就會擋不住省略號了,它本身也會被overflow: hidden給隱藏掉了。

因此最終方案是

html

<div class="wrap">內容</div>
複製代碼

css

.wrap {
    position: relative;
    /*line-height和height要相互配合,顯示多少行就省略,就是line-height多少倍數*/
    line-height: 1.2em;
    max-height: 3.6em;
    /*此屬性看需求來判斷是否設置,由於設置了padding-right,多騰出了點位置,該值通常爲padding-right的值的負值*/
    /*margin-left: -1em;*/
    /*此值寫死成1em就好,由於省略號大概就是佔用1em的空間*/
    padding-right: 1em;
    text-align: justify;
    overflow: hidden;
}

.wrap:before {
    position: absolute;
    right: 0;
    bottom: 0;
    content: '...';
}

.wrap:after {
    position: absolute;
    right: 0;
    /*寬高寫死1em就好,由於省略號大概就是佔用1em的空間,用來遮擋住省略號,也基本上跟wrap的padding-right一致*/
    width: 1em;
    /*與wrap的行高實際值保持一致*/
    height: 1.2em;
    content: '';
    /*要跟所在背景顏色一致才能遮擋住省略號後以爲沒異樣*/
    background-color: #fff;
}
複製代碼

效果:

demo地址

優勢

  1. 兼容性好,各大瀏覽器支持
  2. 自適應高度,不用寫死高度,設定超過多少行才須要進行省略顯示
  3. 自適應寬度
  4. 自適應字體大小,字體大小不會影響到本來的需求,即要求多少行省略就多少行才省略

缺點

  1. 文字右邊會故意留空一些位置給省略號放置
  2. 須要考慮所在的背景顏色,由於after僞類要用背景顏色來遮擋住省略號

利用float佈局

這個方案對於基礎知識不紮實的童鞋們,可能不太好理解,若是僅是想找個解決方案不想知道原理的話,能夠直接去 小結 裏看

在說該方案以前,要先理解這麼一個現象:

有這麼一段html

<div class="wrap">
    <div class="left">左浮動</div>
    <div class="right1">右浮動1右浮動1右浮動1右浮動1右浮動1右浮動1右浮動1右浮動1右浮動1右浮動1右浮動1右浮動1右浮動1右浮動1右浮動1右浮動1</div>
    <div class="right2">右浮動2</div>
</div>
複製代碼

應用這麼一段樣式

.wrap {
	height: 100px;
}
.left {
	float: left;
	width: 60px;
	height: 100%;
	background: pink;
}
.right1 {
	float: right;
	/*佔滿wrap除left剩餘寬度*/
	width: calc(100% - 60px);
	background: #95d9f8;
}
.right2 {
	float: right;
	background: yellow;
}
複製代碼

正常狀況下會顯示成這樣,這也是你們通常所能想象的預期狀況:

出現這個正常現象的條件是:

  1. .right1的高度不超過.left的高度(即內容少)
  2. .right2的寬度少於.right1的寬度

好了,這個狀況你們理解了吧。那麼接下來,咱們對.right1的內容增多至超出左浮動的高度,會發生接下來的一幕

右浮動2卡在左下角了。

要問我爲何會這樣?額...看來你對float的基礎知識不紮實呀,建議夯實一下基礎知識,其實我也解釋不了,我只知道這是float的一個正常表現。

出現這個現象的條件是:

  1. .right1的高度超過.left的高度(即內容多)
  2. .right2的寬度少於或等於.left的寬度

知識轉化成需求實現

在理解了上述兩個情景後,咱們應該怎麼利用這些知識來匹配對應的需求呢?

假設右浮動1的文本內容就是咱們要進行多行省略的內容,右浮動2的內容就是省略號(...)。這樣當內容少時,省略號就是上述的第一個狀況,內容多的時候就是第二個狀況。

這種動態變化,是否是像「文本少時不省略,文本多時進行省略」這種需求變化呢。在這個基礎上,咱們要解決的是在第一種狀況右浮動2隱藏掉,第二種狀況下右浮動2出如今.wrap的右下角,超出高度的內容隱藏掉。

要解決上述問題,只要使用position: relative;進行相對定位便可。.wrap父容器應用overflow: hidden;。 第一種狀況下,定位到父容器外部,就隱藏掉了。而第二種狀況,就定位到父容器右下角。

好了,如今該解決方案的焦點,就放在如何準肯定位的問題上了(下一小節)。在處理定位問題前,先把目前掌握的狀況轉化爲實際的需求代碼:

<!--把左浮動和右浮動2採用僞類元素替換掉實際標籤-->
<div class="wrap">
    <div class="text">右浮動1</div>
</div>
複製代碼
.wrap {
    height: 100px;
    /*line-height用來控制最多顯示多少行文本*/
    line-height: 20px;
    overflow: hidden;
}
.wrap:before {
    float: left;
    /*要大於或等於after元素寬度*/
    width: 1.5em;
    height: 100%;
    content: '';
}
.text {
    float: right;
    /*用負值的marginLeft來避免由before產生的空白空間*/
    /*由於實際需求上你的父容器裏不可能左邊是一片空白吧*/
    margin-left: -1.5em;
    /*既然採用了負值marginLeft,那麼文本容器寬度就能夠100%佔滿父容器寬度了*/
    width: 100%;
}
.wrap:after {
    float: right;
    /*通常三個點就差很少1em寬,用em做單位能自適應字體大小*/
    width: 1em;
    content: '...';
}
複製代碼

若是你這時候好奇,爲何.text都設置了width: 100%;了,內容多時:after仍是會卡在:before底下呢?是由於即便.text設置了margin-left: -1.5em;,可是實際上並不會影響到本來的文檔流狀況,本來該是怎樣的就是怎樣,設置了負值的margin,影響的只是.text自身的呈現樣式。

如何定位

解決定位問題是基於上小節的代碼基礎上。目前暴露的問題有:

  1. 內容少即不須要作省略時,省略號顯示出來了
  2. 內容多即須要省略時,省略號隱藏了

先解決第二個問題

思路:要把這個:after向右移動到.wrap右邊,向上移動到最後一行的位置。

position: relative;來控制的話,top值好取,取.wrapline-height實際值同樣,取負值就行了。關鍵是left值,怎麼取才能恰好在右下角呈現出來。

若是你能明確知道.text的寬度的話(如100px),其實設置left: 100px;便可,可是這樣的話只能針對固定寬的狀況,不能自適應寬度。要想實現自適應,left的值取百分比就好了,那麼究竟是百分之多少呢?這是糾結的。索性就取100%吧,會發現會移出到父容器外。

那要恰好出如今右下角的話,省略號的初始位置就必需要在.wrap的左側,緊挨着.wrap,才能left: 100%後出如今右下角。

如今問題就變成如何讓:after恰好出如今.wrap的左側了。 如下代碼對於基礎不紮實的人,可能有些難理解了(新增部分在註釋處):

.wrap:after {
    float: right;
    /*由於下面設置了margin,因此這裏的寬度值大小沒有要求*/
    width: 1em;
    content: '...';
    
    /*這兩個屬性是設置緊挨着.wrap左側*/
    /*此值要跟自身寬度同樣,取負值*/
    margin-left: -1em;
    /*此值要跟before寬度同樣*/
    padding-right: 1.5em;
    
    /*這是定位省略號的位置*/
    position: relative;
    left: 100%;
    /*與父元素wrap的行高實際值同樣,取負值*/
    top: -20px;
}
複製代碼

關於設置margin和padding值那裏,若是你能理解就最好了,不能理解的話,我儘可能解釋一下,其實這也真很差說。

首先是應用margin-left: -1em;的時候,因爲:after的寬度比:before的要小,因此按照本來的float佈局的話,在一行裏

粉紅色爲左浮動,藍色紅色爲右浮動,若是紅色的寬度不斷增大至除粉紅色剩餘空間,因爲一行的空間不夠,藍色會被擠到換行右浮動了。可是若是設置藍色的margin-left爲自己寬度的負值,那麼這時候一行的空間仍是有位置給它的,就變成了以下這樣了

按照上述原理,設置了margin-left: -1em;後,:after就變回到父容器的第一行上了,緊挨着父容器左側。可是咱們不能讓它回到第一行上呀,因此設置padding-right: 1.5em;讓它實際佔的空間變大到第一行容不下它,就變回到本來的卡在:before下的位置,只是padding值讓它移動到左側了

好了我解釋完了,能不能看懂,只能看你的造化了哈哈。

值得留意的是,上面代碼裏關於width的註釋寫着「由於下面設置了margin,因此這裏的寬度值大小沒有要求」,以前都要求小於等於:before寬度,可是如今因爲採用margin-left負值抵消了自己的寬度,因此這個要求轉化對padding-right了,這時是等於

小結

到目前位置,全部問題都解決了。針對上述全部討論的問題,總結爲如下代碼(具體優化有註釋說明):

css樣式

.wrap {
    /*須要定高*/
    height: 100px;
    /*用來設置顯示多少行才省略,值通常爲wrap的height值/行數求得,可是這個行數會受到字體大小的限制*/
    /*字體太大了,設置顯示不少行也會很醜,都擠一塊了,因此這個實際值,要看具體需求和實踐*/
    line-height: 25px;
    /*加上此屬性顯示效果更佳,就算部分瀏覽器不支持也影響不大*/
    text-align: justify;
    overflow: hidden;
}

.wrap:before {
    float: left;
    /*這個值能夠隨意設定,不論單位仍是什麼*/
    width: 1em;
    height: 100%;
    content: '';
}

.wrap:after {
    float: right;
    /*大小隨意,設置em單位最好,可隨字體大小變化而自適應*/
    /*若是要採用如下漸變效果,那麼這個值要大於before裏的width值效果會比較好點*/
	/*值越大,漸變的效果越明顯影響的範圍越大。*/
    width: 2.5em;
    /*與父元素wrap的行高實際px值同樣*/
    height: 25px;
    /*此值要跟自身寬度同樣,取負值*/
    margin-left: -2.5em;
    /*此值要跟before寬度同樣*/
    padding-right: 1em;
    content: '...';
    text-align: right;
    /*這裏開始利用在float佈局的基礎上進行定位移動了*/
    position: relative;
    /*與父元素wrap的行高實際值同樣,取負值*/
    top: -25px;
    left: 100%;
    /*設置漸變效果是爲了省略號和內容銜接得天然點,沒那麼突兀,要注意要跟文字所在的背景的顏色搭配(把white替換成背景色)*/
    background: #fff;
    background: -webkit-gradient(linear, left top, right top, from(rgba(255, 255, 255, 0)), to(white), color-stop(50%, white));
    background: -moz-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
    background: -o-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
    background: -ms-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
    background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
}

.wrap .text {
    float: right;
    /*該值要等於wrap:before的width值*/
    margin-left: -1em;
    width: 100%;
}
複製代碼

html文件:

<div class="wrap">
    <span class="text">
        示例2: 散發設解決看手機啦開發交
    </span>
</div>
複製代碼

效果:

demo地址

優勢

  1. 兼容性好,知足不是webkit內核的瀏覽器都能支持
  2. 自適應寬度

缺點

  1. 固定高度,不能自適應高度,所以顯示多少行還要受字體大小限制
  2. 須要爲文字包裹一個標籤用以設置樣式
  3. 從讀樣式代碼上來看,理解起來不是很好理解
  4. 若是省略號所在元素不用漸變色背景,偶爾會截斷得突兀,若是要用漸變色背景,要注意與文字所在的背景下的顏色搭配

總結

其實沒有說哪一個方案更好,只有合不合適你的方案,叫你去削個水果皮,拿把水果刀就行了,不必用個大刀。因此,三個方案,總有一款符合你的需求的。

未經容許,請勿私自轉載

相關文章
相關標籤/搜索