原創(chuàng)文章,轉(zhuǎn)載請(qǐng)注明出處涩维。
背景
在項(xiàng)目需求開(kāi)發(fā)時(shí)殃姓,由于文本內(nèi)容長(zhǎng)度的不確定性,經(jīng)常會(huì)碰到文本內(nèi)容超出的問(wèn)題瓦阐,通常這種情況蜗侈,UI/UE都會(huì)要求我們將超出部分用省略號(hào)(...
)來(lái)顯示,這種做法基本上已經(jīng)是一個(gè)業(yè)界共識(shí)了睡蟋。然而踏幻,這么一個(gè)理所當(dāng)然的效果,在前端卻一直是一個(gè)難題戳杀。
希望
對(duì)于文本省略该面,由于CSS3的出現(xiàn),出現(xiàn)了單行文本省略和多行文本省略的劃分了(看完Can I Use
信卡,你會(huì)覺(jué)得這句話不合理隔缀,可,那又如何傍菇,哈哈(?ω?)hiahiahia)猾瘸。之所以這么說(shuō),那是因?yàn)镃SS3定義了一個(gè)文本省略方案:
text-overflow: ellipsis | clip;
這在前端界可謂是相當(dāng)膩害的進(jìn)步丢习,前端大拿牵触、二拿、小拿們紛紛舉起鍵盤(pán)YY:前端的巨輪勢(shì)不可擋咐低!
永遠(yuǎn)在那綠油油的田野上
不得不說(shuō)揽思,text-overflow
的出現(xiàn) ,確實(shí)讓前端為之動(dòng)容见擦,多么美好钉汗,哪里還需要什么JS算字?jǐn)?shù)啊羹令。然而,真正用上text-overflow
才發(fā)現(xiàn)损痰,理想很美好特恬,現(xiàn)實(shí)很骨感,這哥們只管單行文本溢出的省略徐钠,對(duì)于多行文本,卻視而不見(jiàn)役首。
希望尝丐,依舊在那綠油油的田野上……
于是,文本省略從沒(méi)有變成了兩種:?jiǎn)涡形谋臼÷院投嘈形谋臼÷浴?/p>
單行文本省略
有衡奥,總比沒(méi)有好
這是一條永恒的道理爹袁,好歹,解決單行文本省略時(shí)候矮固,我們可以開(kāi)開(kāi)心心用CSS解決失息,而不用再去搞有的沒(méi)的JS了。
用之前先看兼容
這是一條CSS規(guī)則档址。查Can I Use盹兢,這哥們的兼容性簡(jiǎn)直震憾人心啊:
牛不牛守伸,服不服绎秒,連讓你們?cè)嵅〉腎E都兼容到不可思議的地步了。(看到這里尼摹,我就想問(wèn)见芹,這哥們?cè)趺吹紺SS3才被定義哈)
當(dāng)然,并不是一條text-overflow: ellipsis;
就可以實(shí)現(xiàn)文本省略蠢涝。
無(wú)規(guī)矩玄呛,不成方圓
同樣,text-overflow
的使用和二,需要滿足一些規(guī)矩
:
- 塊級(jí)元素
- overflow: 計(jì)算值
非visible
;- 元素寬度:超出時(shí)徘铝,有一個(gè)確切的計(jì)算值
- white-space: nowrap | pre;
估計(jì)你們會(huì)發(fā)現(xiàn),上述的規(guī)矩和你們認(rèn)識(shí)的儿咱,或者在網(wǎng)上找到的教程不太一樣庭砍。嗯嗯,的確如此混埠,搜索各類教程基本給的說(shuō)法是這樣的:
- 塊級(jí)元素
- overflow: hidden; // 也有說(shuō)非visible
- width: 具體值怠缸,非auto
- white-space: nowrap;
其實(shí),基本差不多钳宪,解釋一下不一樣的地方:
- overflow確實(shí)是
非visible
揭北,但是扳炬,是計(jì)算值,并不是設(shè)定值搔体。因?yàn)镃SS里有個(gè)叫inherit
的關(guān)鍵字恨樟。 - 元素寬度,而不是width疚俱,比如劝术,max-width,以及厲害的flex布局也是可以的呆奕。
- white-space: pre; 也是可以的养晋,這個(gè)屬性的設(shè)定主要是為了
不折行
,pre
也是可以達(dá)到目的梁钾。
每個(gè)規(guī)則我就不一一給例子驗(yàn)證了绳泉,如果有問(wèn)題,歡迎評(píng)論留言哈。這里就簡(jiǎn)單
P.S. 圖片來(lái)源于網(wǎng)絡(luò),但是沒(méi)找到源頭奋刽,若你們知道报亩,麻煩告訴我,萬(wàn)分感謝!若是作者看到,覺(jué)得不可使用,告知于我蛔琅,必及時(shí)刪除之!
width規(guī)則里峻呛,我們用flex布局:
<div style="display: flex;">
<div id="ellipsis-item" style="flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
">這是一串很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)的文字</div>
<div style="flex: 1;">這是一串很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)很長(zhǎng)的文字</div>
</div>
把這坨下代碼放到你的頁(yè)面里罗售,如果看不到...,縮小一下窗口钩述,你會(huì)看到類似這樣的情況:
很顯然寨躁,代碼里,我們并沒(méi)有為
#ellipsis-item
元素聲明width
或是max-width
屬性牙勘,但是职恳,省略依然見(jiàn)效。原因就是方面,設(shè)定flex
屬性后放钦,元素就會(huì)被分配寬度計(jì)算值,從而使省略生效恭金。在這個(gè)例子操禀,寬度值是50%父元素寬度。
單行文本省略雖然不是本文的重點(diǎn)横腿,但是也簡(jiǎn)單回顧一下颓屑,并完善些(可能不是完美)text-overflow
的使用規(guī)則斤寂。
多行文本省略
也許有人會(huì)說(shuō),多行文本也有實(shí)現(xiàn)方法啊揪惦。確實(shí)遍搞,在Webkit系瀏覽器里還是有的:
line-clamp
OK,再回顧一下器腋。
Webkit系解決方案
和text-overflow
一樣溪猿,我們先看一下兼容性:
兼容性和
text-overflow
比起來(lái),簡(jiǎn)單是慘不能睹纫塌,真是清一色Webkit再愈,而且,還是-webkit-line-clamp
护戳,連正經(jīng)的line-clamp
都不是。為什么是-webkit-line-clamp
呢垂睬?因?yàn)?p>
- W3C沒(méi)規(guī)范
- Webkit系自己YY的:所以帶-webkit-
- 規(guī)則上媳荒,這哥們要轉(zhuǎn)正,以后也得改哈
那就說(shuō)下規(guī)則吧:
- display: -webkit-box | -webkit-inline-box;
- -webkit-box-orient: vertical | block-axis
- overflow: 計(jì)算值
非visible
- -webkit-line-clamp: N; // 行數(shù)
可以看出來(lái)驹饺,-webkit-line-clamp
依賴于box
布局钳枕,而這家伙是最老的Flex布局
方案,已經(jīng)由新版的flex
系替代赏壹,所以說(shuō)鱼炒,這哥們即使進(jìn)W3C規(guī)范,估計(jì)也得改改了蝌借。
換句說(shuō)昔瞧,現(xiàn)在的寫(xiě)法,很可能未來(lái)不能再使用菩佑,結(jié)局估計(jì)是這兩種:
- W3C收錄規(guī)范:規(guī)則要改自晰,因?yàn)閎ox遲早會(huì)被廢棄
- W3C自己定義一個(gè)新的屬性:整個(gè)廢棄
所以,如果不是別無(wú)選擇稍坯,還是不太建議使用酬荞。
好殘酷,需求還要做瞧哟,怎么辦混巧。。勤揩。JS搞起啊咧党,算字?jǐn)?shù)啊,加...
哈哈……
假裝很完美的方案
哇靠陨亡,講了那么多凿傅,總算回到標(biāo)題了缠犀。。扯了這么多聪舒,感覺(jué)成了標(biāo)題黨辨液,會(huì)不會(huì)被打哈。箱残。
那些用JS算寬度算字?jǐn)?shù)的方案我就不說(shuō)了哈滔迈,你要是喜歡就自行到網(wǎng)上搜索唄。由于本人一貫的原則是:
能用CSS的被辑,就不要用JS
所以燎悍,接下來(lái)這個(gè)方案,也必然是純CSS方案了盼理。另外谈山,給你們點(diǎn)繼續(xù)看下去的勇氣:
- 純CSS
- 高兼容性
- 適用于N行:不區(qū)分單行還是多行
首先,看個(gè)效果圖:
是不是看起來(lái)超厲害宏怔,是不是以為是用的
-webkit-line-clamp
奏路。。臊诊。然而鸽粉,并不是哦。
其次抓艳,來(lái)理一下原理触机。
不管是單行截?cái)噙€是多行截?cái)啵聦?shí)上玷或,瀏覽器并沒(méi)有把超長(zhǎng)的文字刪除儡首,而是渲染時(shí)候在塊尾渲染個(gè)
...
覆蓋在上面,由于規(guī)則里overflow: 計(jì)算值非visible
偏友,所以椒舵,視覺(jué)上是看不到的。
要驗(yàn)證我的說(shuō)法是正確的约谈,很簡(jiǎn)單笔宿,把你們經(jīng)常用overflow: hidden;
的寫(xiě)法改成overflow: auto;
或overflow: scroll;
即可。
所以棱诱,我們的原理也是這樣的泼橘,
拿個(gè)
...
蓋到上面去
簡(jiǎn)單搞個(gè)圖看下:
從上圖可以看到,實(shí)際上迈勋,我們要做的就是把粉色那個(gè)...炬灭,放在框的右下角,以隱藏右下角的最后那個(gè)字/內(nèi)容靡菇,當(dāng)我們把粉色改成白色重归,就會(huì)得到我們希望的...省略效果了:
說(shuō)到這里米愿,...
的方案很簡(jiǎn)單,可以使用一個(gè)特定的元素鼻吮,也可以用::after
偽元素育苟。最后的代碼類似這樣的:
<div style="
margin: 50px;
width: 200px;
height: 3em;
line-height: 1.5;
overflow: hidden;
position:relative;outline:1px solid #ff9900
">這是一串很長(zhǎng)的文字,現(xiàn)在開(kāi)始哦椎木。第二行文字在這里開(kāi)始了
<i style="
position: absolute;
bottom: 0;
right: 0;
width: 1.5em;
padding-left: 2px;
background-color: white;
">...</i>
</div>
到目前為止违柏,一切似乎很順利,網(wǎng)上隨便一搜香椎,都差不多是這個(gè)樣子的漱竖。或許畜伐,你們有人已經(jīng)在YY:你丫是在逗我嗎馍惹,這誰(shuí)不知道哈。
誠(chéng)然玛界,如果我說(shuō)的方案就到此結(jié)束万矾,還真是在逗你們了,但是脚仔,請(qǐng)認(rèn)真繼續(xù)看哈。
這個(gè)方案有一個(gè)很嚴(yán)重的問(wèn)題舆绎,那就是:
理所當(dāng)然地認(rèn)為內(nèi)容一定會(huì)溢出
是的鲤脏,網(wǎng)上有些認(rèn)真的人在寫(xiě)這個(gè)方案時(shí)候,還是會(huì)來(lái)個(gè)溫馨提醒的吕朵,有的也會(huì)告訴你計(jì)算一下內(nèi)容會(huì)不會(huì)溢出猎醇,如果是這樣,干嘛不一開(kāi)始就直接計(jì)算得了努溃,還整了一個(gè)CSS+JS計(jì)算的方案哈硫嘶。
當(dāng)然,如果你可以百分百確定你的內(nèi)容會(huì)溢出梧税,到目前為止的方案已經(jīng)足夠沦疾。相反,你應(yīng)該繼續(xù)看下去第队∠回到我剛才的截圖里:
截圖里可以看到,我們最終的方案是要保證:
當(dāng)且僅當(dāng)內(nèi)容溢出時(shí)凳谦,顯示...省略
究竟如何實(shí)現(xiàn)這個(gè)功能呢忆畅?回想一下我們這個(gè)...
的方案原理,我們是拿...
蓋住右下角的內(nèi)容來(lái)實(shí)現(xiàn)省略尸执,其實(shí)家凯,同樣的道理缓醋,我們可以
拿個(gè)東西蓋住
...
是的,原理還是那個(gè)原理绊诲,只是換了誰(shuí)蓋誰(shuí)送粱。所以,前面那句話驯镊,我們就可以換成:
當(dāng)且僅當(dāng)內(nèi)容溢出時(shí)葫督,不蓋住...
如何達(dá)到這個(gè)效果呢?要解釋這個(gè)問(wèn)題板惑,我們來(lái)具象一下overflow: hidden;
是什么樣的一個(gè)效果橄镜。
假設(shè)我們的內(nèi)容是用一個(gè)數(shù)組存儲(chǔ)的,我們的內(nèi)容框只能承載20個(gè)字冯乘,也就是說(shuō)洽胶,我們的數(shù)組length一旦大于20,index >= 20的元素就不能再顯示了裆馒。
現(xiàn)在姊氓,我們的數(shù)組是空的,我們給它丟個(gè)字(假設(shè)為:略)進(jìn)去喷好,使用棧方法翔横,從頭往里一直丟字(unshift('X'),X為某個(gè)字)梗搅,那第一次丟進(jìn)去的“略”字禾唁,就會(huì)被一直往后推,直到它被推到20的位置无切,“略”字就“不再顯示”了荡短。
同樣,對(duì)...
的覆蓋哆键,我們也用“推”的方法掘托,想象一下,我們找個(gè)東西
籍嘹,把它蓋到...
上闪盔,這就是第一個(gè)字“略”,然后辱士,我們一直在這個(gè)東西
前面添加我們的文本內(nèi)容锭沟,當(dāng)我們把這個(gè)東西
推到框外時(shí),就意味著我們的內(nèi)容溢出了识补,...
需要顯示族淮。而在此之前,由于東西
一直處在index < 20
,所以祝辣,它就一直存在贴妻,一直蓋住...
,這就是:內(nèi)容未溢出蝙斜,不顯示...
名惩。
至此,原理簡(jiǎn)單地抽象了一下孕荠。接下來(lái)娩鹉,就是實(shí)現(xiàn)了,實(shí)現(xiàn)有很多方式稚伍,這里給出其中一種弯予,具體怎么實(shí)現(xiàn),看個(gè)人喜好吧个曙,畢竟
思想是統(tǒng)一的锈嫩,實(shí)現(xiàn)都是看人的
給出以下某個(gè)實(shí)現(xiàn):
<style type="text/css">
.ellipsis {
margin: 20px;
}
.ellipsis {
position: relative;
width: 200px;
max-height: 3em;
line-height: 1.5;
overflow: hidden;
outline: 1px solid #ff9900;
}
.ellipsis::before {
content: '...';
position: absolute;
z-index: 1;
bottom: 0;
right: 0;
width: 1.5em;
padding-left: 3px;
box-sizing: border-box;
background-color: white;
}
.ellipsis::after {
content: '';
display: inline-block;
position: absolute;
z-index: 2;
width: 100%;
height: 100%;
background-color: white;
}
</style>
<div class="ellipsis">這是一串很長(zhǎng)的文字</div>
<div class="ellipsis">這是一串很長(zhǎng)的文字,現(xiàn)在開(kāi)始哦垦搬。第二行文字在這</div>
<div class="ellipsis">這是一串很長(zhǎng)的文字呼寸,現(xiàn)在開(kāi)始哦。第二行文字在這里開(kāi)始了猴贰,從“里”字開(kāi)始对雪,就應(yīng)該被...省略了。</div>
效果圖這樣的:
原理已經(jīng)講了米绕,我就不再劃實(shí)現(xiàn)的要點(diǎn)了瑟捣,多動(dòng)動(dòng)腦,不會(huì)有害處的义郑。
只是比較完美
雖然蝶柿,最后的實(shí)現(xiàn)效果圖上看丈钙,好像很完美的樣子非驮,但是,這個(gè)方案雏赦,同樣有比較麻煩的地方劫笙,簡(jiǎn)單舉例一下
- 中英文:純英文或純中文,比較簡(jiǎn)單星岗,但是填大,如果右下角的字不能確定是中文還是英文時(shí)候,
...
的size和position的設(shè)定基本不會(huì)有一個(gè)完美值俏橘,有興趣的可以自行測(cè)試- 多選文本省略時(shí)允华,內(nèi)容框的高度,要和N行高度保持一致,這是沒(méi)有辦法像瀏覽器處理那樣靴寂,可以處理行上的省略的(
overflow: hidden;
只會(huì)截?cái)啵?/li>
其他的磷蜀,我就不再舉例了。對(duì)于1百炬,可以考慮用漸變混合一下褐隆,弱化問(wèn)題,對(duì)于2剖踊,就乖乖設(shè)定高度吧庶弃。
總之,這是一個(gè)還算比較完美的方案德澈,但是歇攻,還是有其缺陷。如果有更好的方案圃验,再做補(bǔ)充吧掉伏,也歡迎評(píng)論提供。
總結(jié)
本文總結(jié)了文本省略的方案澳窑,既有對(duì)瀏覽器支持方案的一些新見(jiàn)解斧散,也分享了自己的解決方案,來(lái)劃一下重點(diǎn):
text-overflow使用規(guī)矩:
- 塊級(jí)元素
- overflow: 計(jì)算值非visible;
- 元素寬度:超出時(shí)摊聋,有一個(gè)確切的計(jì)算值
- white-space: nowrap | pre;
Webkit系列的多行文本省略:
- display: -webkit-box | -webkit-inline-box;
- -webkit-box-orient: vertical | block-axis
- overflow: 計(jì)算值
非visible
- -webkit-line-clamp: N; // 行數(shù)
本人的方案:
- 在框右下角放個(gè)
...
鸡捐,蓋住右下角的內(nèi)容- 在內(nèi)容尾,跟隨一個(gè)mask麻裁,蓋住上述的
...
箍镜,內(nèi)容超出時(shí),mask被推出煎源,顯示...
P.S. 原創(chuàng)文章色迂,轉(zhuǎn)載請(qǐng)注明出處。