本文首發(fā)于政采云前端團隊博客:可能是最全的 “文本溢出截斷省略” 方案合集
前言
在我們的日常開發(fā)工作中叹坦,文本溢出截斷省略是很常見的一種需考慮的業(yè)務(wù)場景細節(jié)婴氮。看上去 “稀松平匙断蹋” 史隆,但在實現(xiàn)上卻有不同的區(qū)分戈轿,是單行截斷還是多行截斷筛圆?多行的截斷判斷是基于行數(shù)還是基于高度篙顺?這些問題之下,都有哪些實現(xiàn)方案拌禾?他們之間的差異性和場景適應(yīng)性又是如何取胎?凡事就怕較真,較真必有成長湃窍。本文試圖通過編碼實踐闻蛀,給出一些答案。
先來點基礎(chǔ)的您市,單行文本溢出省略
******核心 CSS 語句******
overflow: hidden觉痛;(文字長度超出限定寬度,則隱藏超出的內(nèi)容)
white-space: nowrap茵休;(設(shè)置文字在一行顯示薪棒,不能換行)
text-overflow: ellipsis;(規(guī)定當(dāng)文本溢出時榕莺,顯示省略符號來代表被修剪的文本)
******優(yōu)點******
無兼容問題
響應(yīng)式截斷
文本溢出范圍才顯示省略號俐芯,否則不顯示省略號
省略號位置顯示剛好
********短板********
- 只支持單行文本截斷
**********適用場景**********
- 適用于單行文本溢出顯示省略號的情況
************Demo************
<style> .demo { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }</style><body> <div class="demo">這是一段很長的文本</div></body>
**************示例圖片**************
進階一下,多行文本溢出省略(按行數(shù))
○ 純 CSS 實現(xiàn)方案
****核心 CSS 語句****
-webkit-line-clamp: 2钉鸯;(用來限制在一個塊元素顯示的文本的行數(shù)吧史,2 表示最多顯示 2 行。為了實現(xiàn)該效果亏拉,它需要組合其他的 WebKit 屬性)
display: -webkit-box扣蜻;(和 1 結(jié)合使用,將對象作為彈性伸縮盒子模型顯示 )
-webkit-box-orient: vertical及塘;(和 1 結(jié)合使用 ,設(shè)置或檢索伸縮盒對象的子元素的排列方式 )
overflow: hidden锐极;(文本溢出限定的寬度就隱藏內(nèi)容)
text-overflow: ellipsis笙僚;(多行文本的情況下,用省略號 “…” 隱藏溢出范圍的文本)
********優(yōu)點********
響應(yīng)式截斷
文本溢出范圍才顯示省略號灵再,否則不顯示省略號
省略號顯示位置剛好
**********短板**********
- 兼容性一般:-webkit-line-clamp 屬性只有 WebKit 內(nèi)核的瀏覽器才支持
**********************適**********用場景************
- 多適用于移動端頁面肋层,因為移動設(shè)備瀏覽器更多是基于 WebKit 內(nèi)核
**************Demo**************
<style> .demo { display: -webkit-box; overflow: hidden; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }</style><body> <div class='demo'>這是一段很長的文本</div></body>
****************示例圖片****************
○ 基于 JavaScript 的實現(xiàn)方案
********優(yōu)點********
無兼容問題
響應(yīng)式截斷
文本溢出范圍才顯示省略號,否則不顯示省略號
**********短板**********
需要 JS 實現(xiàn)翎迁,背離展示和行為相分離原則
文本為中英文混合時栋猖,省略號顯示位置略有偏差
**********************適**********用場景************
- 適用于響應(yīng)式截斷,多行文本溢出省略的情況
**************Demo**************
當(dāng)前僅適用于文本為中文汪榔,若文本中有英文蒲拉,可自行修改
<script type="text/javascript"> const text = '這是一段很長的文本'; const totalTextLen = text.length; const formatStr = () => { const ele = document.getElementsByClassName('demo')[0]; const lineNum = 2; const baseWidth = window.getComputedStyle(ele).width; const baseFontSize = window.getComputedStyle(ele).fontSize; const lineWidth = +baseWidth.slice(0, -2); // 所計算的strNum為元素內(nèi)部一行可容納的字數(shù)(不區(qū)分中英文) const strNum = Math.floor(lineWidth / +baseFontSize.slice(0, -2)); let content = ''; // 多行可容納總字數(shù) const totalStrNum = Math.floor(strNum * lineNum); const lastIndex = totalStrNum - totalTextLen; if (totalTextLen > totalStrNum) { content = text.slice(0, lastIndex - 3).concat('...'); } else { content = text; } ele.innerHTML = content; } formatStr(); window.onresize = () => { formatStr(); };</script><body> <div class='demo'></div></body>
****************示例圖片****************
再進階一步,多行文本溢出省略(按高度)
○ 多行文本溢出不顯示省略號
******核心 CSS 語句******
overflow: hidden;(文本溢出限定的寬度就隱藏內(nèi)容)
line-height: 20px雌团;(結(jié)合元素高度燃领,高度固定的情況下,設(shè)定行高锦援, 控制顯示行數(shù))
max-height: 40px猛蔽;(設(shè)定當(dāng)前元素最大高度)
********優(yōu)點********
無兼容問題
響應(yīng)式截斷
**********短板**********
- 單純截斷文字, 不展示省略號,觀感上較為生硬
**********************適**********用場景************
- 適用于文本溢出不需要顯示省略號的情況
****************Demo****************
<style> .demo { overflow: hidden; max-height: 40px; line-height: 20px; }</style><body> <div class='demo'>這是一段很長的文本</div></body>
******************示例圖片******************
○ 偽元素 + 定位實現(xiàn)多行省略
******核心 CSS 語句******
position: relative; (為偽元素絕對定位)
overflow: hidden; (文本溢出限定的寬度就隱藏內(nèi)容)
position: absolute;(給省略號絕對定位)
line-height: 20px; (結(jié)合元素高度,高度固定的情況下,設(shè)定行高, 控制顯示行數(shù))
height: 40px; (設(shè)定當(dāng)前元素高度)
::after {} (設(shè)置省略號樣式)
********優(yōu)點********
無兼容問題
響應(yīng)式截斷
**********短板**********
無法識別文字的長短灵寺,無論文本是否溢出范圍, 一直顯示省略號
省略號顯示可能不會剛剛好曼库,有時會遮住一半文字
************************適**********用場景**************
- 適用于對省略效果要求較低,文本一定會溢出元素的情況
**************Demo**************
<style> .demo { position: relative; line-height: 20px; height: 40px; overflow: hidden; } .demo::after { content: "..."; position: absolute; bottom: 0; right: 0; padding: 0 20px 0 10px; }</style><body> <div class='demo'>這是一段很長的文本</div></body>
****************示例圖片****************
○ 利用 Float 特性略板,純 CSS 實現(xiàn)多行省略
******核心 CSS 語句******
line-height: 20px毁枯;(結(jié)合元素高度,高度固定的情況下,設(shè)定行高, 控制顯示行數(shù))
overflow: hidden;(文本溢出限定的寬度就隱藏內(nèi)容)
float: right/left蚯根;(利用元素浮動的特性實現(xiàn))
position: relative后众;(根據(jù)自身位置移動省略號位置, 實現(xiàn)文本溢出顯示省略號效果)
word-break: break-all;(使一個單詞能夠在換行時進行拆分)
********優(yōu)點********
無兼容問題
響應(yīng)式截斷
文本溢出范圍才顯示省略號颅拦,否則不顯示省略號
**********短板**********
- 省略號顯示可能不會剛剛好蒂誉,有時會遮住一半文字
**********************適**********用場景************
- 適用于對省略效果要求較低,多行文本響應(yīng)式截斷的情況
**************Demo**************
<style> .demo { background: #099; max-height: 40px; line-height: 20px; overflow: hidden; } .demo::before{ float: left; content:''; width: 20px; height: 40px; } .demo .text { float: right; width: 100%; margin-left: -20px; word-break: break-all; } .demo::after{ float:right; content:'...'; width: 20px; height: 20px; position: relative; left:100%; transform: translate(-100%,-100%); }</style><body> <div class='demo'>這是一段很長的文本</div></body>
****************示例圖片****************
******************原理講解******************
有 A距帅、B右锨、C 三個盒子,A 左浮動碌秸,B绍移、C 右浮動。設(shè)置 A 盒子的高度與 B 盒子高度(或最大高度)要保持一致
當(dāng) B 盒子高度低于 A 盒子讥电,C 盒子仍會處于 B 盒子右下方蹂窖。
如果 B 盒子文本過多,高度超過了 A 盒子恩敌,則 C 盒子不會停留在右下方瞬测,而是掉到了 A 盒子下。
接下來對 C 盒子進行相對定位纠炮,將 C 盒子位置向右側(cè)移動 100%月趟,并向左上方向拉回一個 C 盒子的寬高(不然會看不到喲)。這樣在文本未溢出時不會看到 C 盒子恢口,在文本溢出時孝宗,顯示 C 盒子。
收耕肩,大道歸簡因妇,能力封裝
凡重復(fù)的问潭,讓它單一;凡復(fù)雜的沙峻,讓它簡單睦授。
每次都要搞一坨代碼,太麻煩摔寨。這時候你需要考慮將文本截斷的能力去枷,封裝成一個可隨時調(diào)用的自定義容器組件。市面上很多 UI 組件庫是复,都提供了同類組件的封裝删顶,如基于 Vue 的 ViewUI Pro,或面向小程序提供組件化解決能力的 MinUI淑廊。
結(jié)語
本文介紹了幾種目前常見的文本截斷省略的方案逗余,各有利弊,各位同學(xué)可根據(jù)實際開發(fā)情況及需求選擇方案季惩。如果你還知道更好其他實現(xiàn)方案录粱,歡迎在評論區(qū)留下寶貴評論。
參考文章
純 CSS 實現(xiàn)多行文字截斷 ( https://github.com/happylindz/blog/issues/12 )
【 CSS / JS 】限制一行和多行文字數(shù)量画拾,溢出部分用省略號顯示 ( https://blog.csdn.net/qq_40072782/article/details/82908581 )
HTML技巧篇:如何讓單行文本以及多行文本溢出顯示省略號(…) ( https://baijiahao.baidu.com/s?id=1621362934713048315&wfr=spider&for=pc )