如何用CSS实现多行文本的省略号显示

简介:

本文翻译自CSS Ellipsis: How to Manage Multi-Line Ellipsis in Pure CSS,文中某些部分有些许改动,并添加译者的一些感想,请各位读者谅解。

合理的截断多行文本是件不容易的事情,我们通常采用几种方法解决:

  • 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规范中的几种情形,不明白的读者自行查阅。这段代码实现很简单,就是三个子元素和包含块的高度及浮动设置:


 
 
  1. <div class="wrap"
  2.  
  3.   <div class="prop">1.prop<br>float:left</div> 
  4.  
  5.   <div class="main">2.main<br>float:right<br>Fairly short text</div> 
  6.  
  7.   <div class="end">3.end<br>float:right</div> 
  8.  
  9. </div> 
  10.  
  11.   
  12.  
  13. .wrap { 
  14.  
  15.   width: 400px; height: 200px; 
  16.  
  17.     margin: 20px 20px 50px; 
  18.  
  19.     border: 5px solid #AAA; 
  20.  
  21.     line-height: 25px; 
  22.  
  23.  
  24.   
  25.  
  26. .prop { 
  27.  
  28.     floatleft
  29.  
  30.     width: 100px; height: 200px; 
  31.  
  32.     background: #FAF; } 
  33.  
  34. .main { 
  35.  
  36.     floatright
  37.  
  38.     width: 300px; 
  39.  
  40.     background: #AFF; } 
  41.  
  42. .end { 
  43.  
  44.     floatright
  45.  
  46.     width: 100px; 
  47.  
  48.     background: #FFA; }  

2nd 模拟场景

我们通过创建一个子元素来替代将要显示的省略号,当文本溢出的情形下该元素显示在正确的位置上。在接下来的实现中,我们创建了一个realend元素,并利用上一节end元素浮动后的位置来实现realend元素的定位。


 
 
  1. <div class="wrap"
  2.  
  3.   <div class="prop"
  4.  
  5.    1.prop<br> 
  6.  
  7.    float:right</div> 
  8.  
  9.   <div class="main"
  10.  
  11.    2.main<br> 
  12.  
  13.    float:left<br> 
  14.  
  15.    Fairly short text</div> 
  16.  
  17.   <div class="end"
  18.  
  19.    <div class="realend"
  20.  
  21.      4.realend<br> 
  22.  
  23.      position:absolute</div> 
  24.  
  25.   3.end<br>float:right 
  26.  
  27.   </div> 
  28.  
  29. </div> 
  30.  
  31.   
  32.  
  33. .end { 
  34.  
  35.     floatright; position: relative
  36.  
  37.     width: 100px; 
  38.  
  39.     background: #FFA; } 
  40.  
  41. .realend { 
  42.  
  43.     position: absolute
  44.  
  45.     width: 100%; 
  46.  
  47.     top: -50px; 
  48.  
  49.     left: 300px; 
  50.  
  51.     background: #FAA; font-size: 13px; }  

这一步中,我们主要关心的是realend元素的定位,基于浮动后的end元素设置偏移量,当end元素浮动到第一节第二章图的位置时(即在prop元素的下方),此时realend元素正好处在end元素的上方50px,右侧300px-100px=200px处,而该位置正是父包含框wrap元素的右下角,此时正是我们期待的结果:

若父元素并没有溢出,那么realend元素会出现在其右侧

这种情况解决很简单,请看下文之第七节,此处仅作实例说明。

3rd 优化定位模型

在第二节中,我们针对end元素设置了相对定位,对realend元素设置绝对定位。但是我们可以采用更为简单的代码来实现,即只使用相对定位。熟悉定位模型的同学应该知道,相对定位的元素仍然占据文本流,同时仍可针对元素设置偏移。这样,就可以去掉end元素,仅针对realend元素设置相对定位。


 
 
  1. <div class="wrap"
  2.  
  3.   <div class="prop">1.prop<br>float:right</div> 
  4.  
  5.   <div class="main">2.main<br>float:left<br>Fairly short text</div> 
  6.  
  7.   <div class="realend"
  8.  
  9.   3.realend<br>position:relative</div> 
  10.  
  11. </div> 
  12.  
  13.   
  14.  
  15. .realend { 
  16.  
  17.     floatright
  18.  
  19.         position: relative
  20.  
  21.     width: 100px; 
  22.  
  23.     top: -50px; left: 300px; 
  24.  
  25.     background: #FAA; font-size: 14px; }  

其他的属性并不改变,效果一样。

4th 削窄prop元素

目前,最左侧的prop元素的作用在于让realend元素在文本溢出时处在其正下方,在前几节的示例代码中为了直观的演示,设置prop元素的宽度为100px,那么现在为了更好的模拟实际的效果,我们缩小逐渐缩小prop元素的宽度。


 
 
  1. <div class="wrap"
  2.  
  3.   <div class="prop">1.prop<br>float:right</div> 
  4.  
  5.   <div class="main">2.main<br>float:left<br>Fairly short text</div> 
  6.  
  7.   <div class="realend"
  8.  
  9.   3.realend<br>position:relative</div> 
  10.  
  11. </div> 
  12.  
  13.   
  14.  
  15.   
  16.  
  17. .prop { 
  18.  
  19.   floatleft
  20.  
  21.   width: 5px; 
  22.  
  23.   height: 200px; 
  24.  
  25.   background: #F0F; } 
  26.  
  27. .main { 
  28.  
  29.     floatright
  30.  
  31.     width: 300px; 
  32.  
  33.     margin-left: -5px; 
  34.  
  35.     background: #AFF; } 
  36.  
  37. .realend { 
  38.  
  39.     floatright
  40.  
  41.         position: relative
  42.  
  43.     top: -50px; 
  44.  
  45.         left: 300px; 
  46.  
  47.     width: 100px; 
  48.  
  49.         margin-left: -100px; 
  50.  
  51.     padding-right: 5px; 
  52.  
  53.     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。


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

具体可参考我之前的文章负margin的原理以及应用一文。

由于CSS规范规定padding的值不可以为负数,因此只有设置margind-left为负值,且等于其宽度。这样做的最终目的就是保证realend元素处在prop元素的下方,保证在文本溢出的情况下定位准确性:

5th 继续优化:流式布局+伪元素

目前,realend元素的相关属性仍采用px度量,为了更好的扩展性,可以改用%替代。

同时,prop元素和realend元素可以采用伪元素来实现,减少额外标签的使用。


 
 
  1. <div class="ellipsis"
  2.  
  3.   <div>2.main<br>float:left<br>Fairly short text 
  4.  
  5.   </div> 
  6.  
  7. </div> 
  8.  
  9.   
  10.  
  11. /*相当于之前的prop元素*/ 
  12.  
  13. .ellipsis:before { 
  14.  
  15.     content: ""
  16.  
  17.     floatleft
  18.  
  19.     width: 5px; height: 200px; 
  20.  
  21.     background: #F0F; } 
  22.  
  23. /*相当于之前的main元素*/ 
  24.  
  25. .ellipsis > *:first-child { 
  26.  
  27.     floatright
  28.  
  29.     width: 100%; 
  30.  
  31.     margin-left: -5px; 
  32.  
  33.     background: #AFF; } 
  34.  
  35. /*相当于之前的realend元素*/ 
  36.  
  37. .ellipsis:after { 
  38.  
  39.     content: "realend"
  40.  
  41.     floatright; position: relative
  42.  
  43.     top: -25px; left: 100%; 
  44.  
  45.     width: 100px; margin-left: -100px; 
  46.  
  47.     padding-right: 5px; 
  48.  
  49.     background: #FAA; font-size: 14px; }  

效果图和上节一样。

6th 隐藏

之前的实现中在文本未溢出的情况下,realend元素会出现在父元素的右侧,正如。

解决此问题很简单,急需要设置:


 
 
  1. .ellipsis{ 
  2.  
  3.     overflow:hidden; 
  4.  
  5. }  

即可解决问题。

7th 大功告成

现在我们离完结就差一步了,即去掉各元素的背景色,并且用“…”替换文本。最后为了优化体验,采用渐变来隐藏“…”覆盖的文本,并设置了一些兼容性的属性。

到了此处,相信现在关心的只是CSS的代码了:


 
 
  1. .ellipsis { 
  2.  
  3.   overflow: hidden; 
  4.  
  5.   height: 200px; 
  6.  
  7.     line-height: 25px; 
  8.  
  9.     margin: 20px; 
  10.  
  11.     border: 5px solid #AAA; } 
  12.  
  13.   
  14.  
  15. .ellipsis:before { 
  16.  
  17.     content:""
  18.  
  19.     floatleft
  20.  
  21.     width: 5px; height: 200px; } 
  22.  
  23.   
  24.  
  25. .ellipsis > *:first-child { 
  26.  
  27.     floatright
  28.  
  29.     width: 100%; 
  30.  
  31.     margin-left: -5px; }         
  32.  
  33.   
  34.  
  35. .ellipsis:after { 
  36.  
  37.     content: "\02026";   
  38.  
  39.   
  40.  
  41.     box-sizing: content-box; 
  42.  
  43.     -webkit-box-sizing: content-box; 
  44.  
  45.     -moz-box-sizing: content-box; 
  46.  
  47.   
  48.  
  49.     floatright; position: relative
  50.  
  51.     top: -25px; left: 100%; 
  52.  
  53.     width: 3em; margin-left: -3em; 
  54.  
  55.     padding-right: 5px; 
  56.  
  57.      
  58.  
  59.     text-align: right
  60.  
  61.   
  62.  
  63.    
  64.  
  65.         background-size: 100% 100%; 
  66.  
  67.   /* 512x1 image, gradient for IE9. Transparent at 0% -> white at 50% -> white at 100%.*/ 
  68.  
  69. 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); 
  70.  
  71.    
  72.  
  73.     background: -webkit-gradient(linear, left topright top
  74.  
  75.         from(rgba(255, 255, 255, 0)), to(white), color-stop(50%, white)); 
  76.  
  77.     background: -moz-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);           
  78.  
  79.     background: -o-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white); 
  80.  
  81.     background: -ms-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white); 
  82.  
  83.     background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white); 
  84.  

总结之兼容性

从上文的实现细节来看,我们利用的技巧完全是CSS规范中的浮动+定位+盒模型宽度计算,唯一存在兼容性问题的在于无关痛痒的渐变实现,因此可以在大多数浏览器下进行尝试。


作者:伯乐在线

来源:51CTO

相关文章
|
10月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
继承 我们的CSS中很多的属性也是可以继承的,其中相当一部分是跟文字的相关的,比如说颜色、字体、字号。 当然还有一部分是不能继承的。 例如边框、内外边距。 层叠 层叠是CSS的核心机制。 层叠的工作机制: 当元素的同一个样式属性有多种样式值的时候,CSS就是靠层叠机制来决定最终应用哪种样式。 层叠规则: 层叠规则一:找到应用给每个元素和属性的声明。 说明:浏览器在加载每个页面时,都会据此查找到每条CSS规则, 并标识出所有受到影响的HTML元素。
327 1
|
自然语言处理 前端开发 JavaScript
Playwright系列课(2) | 元素定位四大法宝:CSS/文本/XPath/语义化定位实战指南
本文是Playwright系列第二课,详解元素定位四大核心技术:CSS选择器、文本定位、XPath和语义化定位,结合实战演示各方法应用场景。重点解析Playwright智能定位器(Locator)的独特优势——自动等待与重试机制,通过预检元素可操作性(可见/可点击)有效规避网络延迟导致的脚本失效,显著提升自动化测试稳定性。
|
前端开发
css中的多行省略和单行省略
css中的多行省略和单行省略
379 126
|
前端开发
Css实现文本超出长度隐藏并用三个点结尾
Css实现文本超出长度隐藏并用三个点结尾
444 17
|
前端开发
前端基础(五)_CSS文本文字属性、背景颜色属性
本文详细介绍了CSS中关于文本和背景颜色的样式属性。包括字体大小、字体族、字体加粗、字体样式、文本行高、`font`属性、文本颜色、文本对齐方式、文本装饰线、首行缩进等文本属性,以及背景颜色、背景图片、背景重复、背景位置等背景属性。文章通过示例代码展示了这些属性的具体应用和效果。
913 3
前端基础(五)_CSS文本文字属性、背景颜色属性
|
前端开发
【前端web入门第三天】02 CSS字体和文本
本文详细介绍了CSS中字体和文本的相关属性。字体部分涵盖字体大小、粗细、样式、行高、字体族及`font`复合属性,通过具体示例展示了如何设置和使用这些属性。文本部分则讲解了文本缩进、对齐方式、修饰线及文字颜色等属性,并提供了实用的代码示例。此外,还简要介绍了调试工具中的一些细节,如错误属性标识和属性生效状态的控制。
464 28
CSS3几何透明层文本悬停变色源码
CSS3几何透明层文本悬停变色源码是一款基于css3 svg制作的背景图片鼠标悬停几何形状透明层变色显示文本内容
197 0
CSS3几何透明层文本悬停变色源码
|
前端开发
css中的多行省略和单行省略
css中的多行省略和单行省略
|
Web App开发 前端开发 iOS开发
CSS文字省略号
CSS文字省略号
|
前端开发
使用CSS样式化占位文本
使用CSS样式化占位文本
217 0

热门文章

最新文章

  • 1
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
    596
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
    455
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
    455
  • 4
    (CSS)使用Flex布局,帮助你快速了解各种基本的Flex布局属性以及帮你让元素快速达到布局中的指定位置!
    300
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
    578
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
    754
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
    1476
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
    327
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
    1200
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
    535