合理的截断多行文本是件不容易的事情,我们通常采用几种方法解决:
直接隐藏多余的文本
- overflow: hidden
只适用于单行文本的处理
- text-overflow: ellipsis
我们把实现的细节划分为 7 个步骤,在这个实现过程中最简单的就是截断文本,而最难的部分则是让一个元素处在其父包含块溢出时的右下方,并且当父元素未溢出时该元素消失不可见。为了去难避易,我们先从比较简单的地方开始 -- 当父包含框比较小时,将子元素布局到父包含框的右下角。
其实这个实现完全利用了元素浮动的基本规则。在这里不详细讲解 CSS2.1 规范中的几种情形,不明白的读者自行查阅。这段代码实现很简单,就是三个子元素和包含块的高度及浮动设置:
- <div class="wrap">
- <div class="prop">1.prop<br>float:left</div>
- <div class="main">2.main<br>float:right<br>Fairly short text</div>
- <div class="end">3.end<br>float:right</div>
- </div>
- .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; }
我们通过创建一个子元素来替代将要显示的省略号,当文本溢出的情形下该元素显示在正确的位置上。在接下来的实现中,我们创建了一个 realend 元素,并利用上一节 end 元素浮动后的位置来实现 realend 元素的定位。
- <div class="wrap">
- <div class="prop">
- 1.prop
- <br>
- float:right
- </div>
- <div class="main">
- 2.main
- <br>
- float:left
- <br>
- Fairly short text
- </div>
- <div class="end">
- <div class="realend">
- 4.realend
- <br>
- position:absolute
- </div>
- 3.end
- <br>
- float:right
- </div>
- </div>
- .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 元素会出现在其右侧
这种情况解决很简单,请看下文之第七节,此处仅作实例说明。
在第二节中,我们针对 end 元素设置了相对定位,对 realend 元素设置绝对定位。但是我们可以采用更为简单的代码来实现,即只使用相对定位。熟悉定位模型的同学应该知道,相对定位的元素仍然占据文本流,同时仍可针对元素设置偏移。这样,就可以去掉 end 元素,仅针对 realend 元素设置相对定位。
- <div class="wrap">
- <div class="prop">
- 1.prop
- <br>
- float:right
- </div>
- <div class="main">
- 2.main
- <br>
- float:left
- <br>
- Fairly short text
- </div>
- <div class="realend">
- 3.realend
- <br>
- position:relative
- </div>
- </div>
- .realend { float: right; position: relative; width: 100px; top: -50px;
- left: 300px; background: #FAA; font-size: 14px; }
其他的属性并不改变,效果一样。
目前,最左侧的 prop 元素的作用在于让 realend 元素在文本溢出时处在其正下方,在前几节的示例代码中为了直观的演示,设置 prop 元素的宽度为 100px,那么现在为了更好的模拟实际的效果,我们缩小逐渐缩小 prop 元素的宽度。
- <div class="wrap">
- <div class="prop">1.prop<br>float:right</div>
- <div class="main">2.main<br>float:left<br>Fairly short text</div>
- <div class="realend">
- 3.realend<br>position:relative</div>
- </div>
- .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
则是为了让 realend 元素的盒模型的最终宽度计算为 5px。
- padding-right: 5px
- BoxWidth = ChildMarginLeft + ChildBorderLeftWidth + ChildPaddingLeft + ChildWidth + ChildPaddingLeft + ChildBorderRightWidth + ChildMarginRightWidth;
具体可参考我之前的文章一文。
由于 CSS 规范规定 padding 的值不可以为负数,因此只有设置 margind-left 为负值,且等于其宽度。这样做的最终目的就是保证 realend 元素处在 prop 元素的下方,保证在文本溢出的情况下定位准确性:
目前,realend 元素的相关属性仍采用 px 度量,为了更好的扩展性,可以改用 % 替代。
同时,prop 元素和 realend 元素可以采用伪元素来实现,减少额外标签的使用。
- <div class="ellipsis">
- <div>2.main<br>float:left<br>Fairly short text
- </div>
- </div>
- /*相当于之前的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; }
效果图和上节一样。
之前的实现中在文本未溢出的情况下,realend 元素会出现在父元素的右侧,正如。解决此问题很简单,急需要设置:
- .ellipsis{
- overflow:hidden;
- }
即可解决问题。
现在我们离结完就差一步了,即去掉各元素的背景色,并且用 "..." 替换文本。最后为了优化体验,采用渐变来隐藏 "..." 覆盖的文本,并设置了一些兼容性的属性。
到了此处,相信现在关心的只是 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 规范中的浮动 + 定位 + 盒模型宽度计算,唯一存在兼容性问题的在于无关痛痒的渐变实现,因此可以在大多数浏览器下进行尝试。
来源: http://www.cnblogs.com/accordion/p/6507320.html