7步實現CSS多行文本的省略符號顯示

來源:互聯網
上載者:User

line-height: 1.76em;">合理的截斷多行文本是件不容易的事情,我們通常採用幾種方法解決:

  • overflow: hidden 直接隱藏多餘的文本

  • text-overflow: ellipsis 只適用於單行文本的處理

  • 各種比較脆弱的javascript實現。之所以說這種實現比較脆弱是由於需要文本長度的變化時刻得到迴流(relayout)後的布局資訊,如寬度

原文寫作時間是2012.9.18號,比較有意義的一天。不過作者忽略了WebKit提供的一個擴充屬性 -webkit-line-clamp ,它並不是CSS規範中的屬性。利用該屬性實現多行文本的省略符號顯示需要配合其他三個屬性: display: -webkit-box 、 -webkit-box-orient 、 text-overflow: ellipsis; 。其中, -webkit-line-clamp 設定塊元素包含的文本行數; display: -webkit-box 設定塊元素的布局為伸縮布局; -webkit-box-orient 設定伸縮項的布局方向; text-overflow: ellipsis; 則表示超出盒子的部分使用省略符號表示。

不過本文將要介紹的方法是採用CSS規範中的屬性,並結合特殊的實現技巧完成的。這意味著在實現CSS2.1規範的瀏覽器中都是可以相容的,不將僅僅是純粹的移動端領域,在傳統的PC瀏覽器(你們懂得我指的是哪些瀏覽器)中仍是可行的。好吧,讓我們一起見識下。

CSS實現多行文本溢出的省略符號顯示

我們把實現的細節劃分為7個步驟,在這個實現過程中最簡單的就是 截斷文本 ,而最難的部分則是 讓一個元素處在其父包含塊溢出時的右下方,並且當父元素未溢出時該元素消失不可見 。為了去難避易,我們先從比較簡單的地方開始--當父包含框比較小時,將子項目布局到父包含框的右下角。

1st 引子

其實這個實現完全利用了元素浮動的基本規則。在這裡不詳細講解CSS2.1規範中的幾種情形,不明白的讀者自行查閱。這段代碼實現很簡單,就是三個子項目和包含塊的高度及浮動設定:

<p class="wrap">  <p class="prop">1.prop<br>float:left</p>  <p class="main">2.main<br>float:right<br>Fairly short text</p>  <p class="end">3.end<br>float:right</p></p>.wrap {  width: 400px; height: 200px;    margin: 20px 20px 50px;    border: 5px solid #AAA;    line-height: 25px; }.prop {    float: left;    width: 100px; height: 200px;     background: #FAF; }.main {    float: right;    width: 300px;     background: #AFF; }.end {    float: right;    width: 100px;    background: #FFA; }

2cd 類比情境

我們通過建立一個子項目來替代將要顯示的省略符號,當文本溢出的情形下該元素顯示在正確的位置上。在接下來的實現中,我們建立了一個realend元素,並利用上一節end元素浮動後的位置來實現realend元素的定位。

<p class="wrap">  <p class="prop">   1.prop<br>   float:right</p>  <p class="main">   2.main<br>   float:left<br>   Fairly short text</p>  <p class="end">   <p class="realend">     4.realend<br>     position:absolute</p>  3.end<br>float:right  </p></p>.end {    float: right; position: relative;    width: 100px;    background: #FFA; }.realend {    position: absolute;    width: 100%;    top: -50px;    left: 300px;    background: #FAA; font-size: 13px; }

這一步中,我們主要關心的是realend元素的定位,基於浮動後的end元素設定位移量,當end元素浮動到第一節第二章圖的位置時(即在prop元素的下方),此時realend元素正好處在end元素的上方50px,右側300px-100px=200px處,而該位置正是父包含框wrap元素的右下角,此時正是我們期待的結果:

若父元素並沒有溢出,那麼realend元素會出現在其右側

這種情況解決很簡單,請看下文之第七節,此處僅作執行個體說明。

3rd 最佳化定位模型

在第二節中,我們針對end元素設定了相對定位,對realend元素設定絕對位置。但是我們可以採用更為簡單的代碼來實現,即只使用相對定位。熟悉定位模型的同學應該知道,相對定位的元素仍然佔據文字資料流,同時仍可針對元素設定位移。這樣,就可以去掉end元素,僅針對realend元素設定相對定位。

<p class="wrap">  <p class="prop">1.prop<br>float:right</p>  <p class="main">2.main<br>float:left<br>Fairly short text</p>  <p class="realend">  3.realend<br>position:relative</p></p>.realend {    float: right;         position: relative;    width: 100px;     top: -50px; left: 300px;    background: #FAA; font-size: 14px; }

其他的屬性並不改變,效果一樣。

4th 削窄prop元素

目前,最左側的prop元素的作用在於讓realend元素在文本溢出時處在其正下方,在前幾節的範例程式碼中為了直觀的示範,設定prop元素的寬度為100px,那麼現在為了更好的類比實際的效果,我們縮小逐漸縮小prop元素的寬度。

<p class="wrap">  <p class="prop">1.prop<br>float:right</p>  <p class="main">2.main<br>float:left<br>Fairly short text</p>  <p class="realend">  3.realend<br>position:relative</p></p>.prop {  float: left;  width: 5px;   height: 200px;   background: #F0F; }.main {    float: right;    width: 300px;     margin-left: -5px;    background: #AFF; }.realend {    float: right;         position: relative;    top: -50px;         left: 300px;    width: 100px;         margin-left: -100px;    padding-right: 5px;    background: #FAA; font-size: 14px; }

針對prop元素,縮小寬度為5px,其餘屬性不變;

針對main元素,設定margin-left:5px,讓main元素左移5px,這樣main元素在寬度上就完全佔滿了父元素;

對於realend元素,top、left和width的值不變。而設定 margin-left: -100px 、 padding-right: 5px 則是為了讓realend元素的盒模型的最終寬度計算為5px。

BoxWidth = ChildMarginLeft + ChildBorderLeftWidth + ChildPaddingLeft + ChildWidth + ChildPaddingLeft + ChildBorderRightWidth + ChildMarginRightWidth;

由於CSS規範規定padding的值不可以為負數,因此只有設定margind-left為負值,且等於其寬度。這樣做的最終目的就是 保證realend元素處在prop元素的下方,保證在文本溢出的情況下定位準確性 :

5th 繼續最佳化:流式布局+虛擬元素

目前,realend元素的相關屬性仍採用 px 度量,為了更好的擴充性,可以改用 % 替代。

同時,prop元素和realend元素可以採用虛擬元素來實現,減少額外標籤的使用。

<p class="ellipsis">  <p>2.main<br>float:left<br>Fairly short text  </p></p>/*相當於之前的prop元素*/.ellipsis:before {     content: "";    float: left;    width: 5px; height: 200px;     background: #F0F; }/*相當於之前的main元素*/.ellipsis > *:first-child {    float: right;    width: 100%;     margin-left: -5px;    background: #AFF; }/*相當於之前的realend元素*/.ellipsis:after {    content: "realend";    float: right; position: relative;    top: -25px; left: 100%;    width: 100px; margin-left: -100px;    padding-right: 5px;    background: #FAA; font-size: 14px; }

和上節一樣。

6th 隱藏

之前的實現中在文本未溢出的情況下,realend元素會出現在父元素的右側,正如 。解決此問題很簡單,急需要設定:

.ellipsis{  overflow:hidden;}

即可解決問題。

7th 大功告成

現在我們離結完就差一步了,即去掉各元素的背景色,並且用“...”替換文本。最後為了最佳化體驗,採用漸層來隱藏“...”覆蓋的文本,並設定了一些相容性的屬性。

到了此處,相信現在關心的只是CSS的代碼了:

.ellipsis {  overflow: hidden;  height: 200px;    line-height: 25px;    margin: 20px;    border: 5px solid #AAA; }.ellipsis:before {    content:"";    float: left;    width: 5px; height: 200px; }.ellipsis > *:first-child {    float: right;    width: 100%;    margin-left: -5px; }        .ellipsis:after {    content: "\02026";      box-sizing: content-box;    -webkit-box-sizing: content-box;    -moz-box-sizing: content-box;    float: right; position: relative;    top: -25px; left: 100%;     width: 3em; margin-left: -3em;    padding-right: 5px;        text-align: right;          background-size: 100% 100%;  /* 512x1 image, gradient for IE9. Transparent at 0% -> white at 50% -> white at 100%.*/background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAABCAMAAACfZeZEAAAABGdBTUEAALGPC/xhBQAAAwBQTFRF////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wDWRdwAAAP90Uk5TgsRjMZXhS30YrvDUP3Emow1YibnM9+ggOZxrBtpRRo94gxItwLOoX/vsHdA2yGgL8+TdKUK8VFufmHSGgAQWJNc9tk+rb5KMCA8aM0iwpWV6dwP9+fXuFerm3yMs0jDOysY8wr5FTldeoWKabgEJ8RATG+IeIdsn2NUqLjQ3OgBDumC3SbRMsVKsValZplydZpZpbJOQco2KdYeEe36BDAL8/vgHBfr2CvTyDu8R7esU6RcZ5ecc4+Af3iLcJSjZ1ivT0S/PMs3LNck4x8U7wz7Bv0G9RLtHuEq1TbJQr1OtVqqnWqRdoqBhnmSbZ5mXapRtcJGOc4t2eYiFfH9AS7qYlgAAARlJREFUKM9jqK9fEGS7VNrDI2+F/nyB1Z4Fa5UKN4TbbeLY7FW0Tatkp3jp7mj7vXzl+4yrDsYoVx+JYz7mXXNSp/a0RN25JMcLPP8umzRcTZW77tNyk63tdprzXdmO+2ZdD9MFe56Y9z3LUG96mcX02n/CW71JH6Qmf8px/cw77ZvVzB+BCj8D5vxhn/vXZh6D4uzf1rN+Cc347j79q/zUL25TPrJMfG/5LvuNZP8rixeZz/mf+vU+Vut+5NL5gPOeb/sd1dZbTs03hBuvmV5JuaRyMfk849nEM7qnEk6IHI8/qn049hB35QGHiv0yZXuMdkXtYC3ebrglcqvYxoj1muvC1nDlrzJYGbpcdHHIMo2FwYv+j3QAAOBSfkZYITwUAAAAAElFTkSuQmCC);      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);}

總結之相容性

從上文的實現細節來看,我們利用的技巧完全是CSS規範中的浮動+定位+盒模型寬度計算,唯一存在相容性問題的在於無關痛癢的漸層實現,因此可以在大多數瀏覽器下進行嘗試。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.