溢出文本省略号表示的css实现及polyfill

 需求经常有需要对文字溢出进行处理,通常是在文字显示部分的末尾添加“...”等。如下:

这种处理可以放在服务器当中做,通过截取特定长度文字来达到。

但是效果不好

一是截取的长度不好控制,尤其是中英文混排或者字体非等宽的情况

二是显示逻辑放到服务器做,日后维护很不方便

三是对 SEO 也有影响

好在 css 当中有专门处理这种问题的属性

 

一:css处理单行

对于单行文本而言,使用 “text-overflow” 。IE6+都支持,真幸福。

但不是什么元素添加上这个都能立刻有效。

它要求元素必须是bfc,也就是有明确的宽度;再有其中的文字不能换行

p {  overflow: hidden;            /* 除了visible以外的值 */
  white-space: nowrap;         /* 文字不换行 */
  text-overflow: ellipsis;     
}

 

组合使用上述属性才能让元素有正确的效果。如下:

demo:http://runjs.cn/code/c3bfbze3

 

text-overflow 的可选值有三种

    clip:默认值。直接截断。

    ellipsis:三个点儿(...)

    (string):自定义文字。如果这个问题太长,也会被截断

text-overflow 还可以设置两个值,对应左右分别采用不同的处理方式,这里的左右貌似和文字方向没什么关系。如下:

  text-overflow: clip ellipsis

 

只有firefox支持,没多大意义。我自己没有试出来效果。详见:https://developer.mozilla.org/zh-CN/docs/Web/CSS/text-overflow

 

二:css处理多行文本

上面说的只能处理单行,你也看到了,它要求文字不能换行。

如果遇到多行文本的溢出处理,就需要 line-clamp 出马了

p {
  overflow: hidden;               /* 非必须,但是不设置效果不对 */
  display: -webkit-box;           /* 必须是webkit-box */
  -webkit-line-clamp: 3;          /* 文本行数 */
  -webkit-box-orient: vertical;   /* webkit-box的纵轴方向 */
}

 

demo:http://runjs.cn/code/2qdpzcoi

注意,元素必须声明成webkit-box,真的好奇怪,这会导致一系列问题(比如元素高度和宽度的计算会不同),需要特别注意

声明为 "display: flex" 不起作用。可能需要添加其他辅助属性。就不实验了。flex和-webkit-box的互换性还是糊里糊涂的。

 

如果不写 "overflow:hidden" 效果还是有的,但明显不是你想要的

 

opera有自己的实现方式,但不是web标准,所以作用不大。

不过这种方式跟以前的属性更有传承,而且貌似更符合一般人的直觉。

.last-line {
  height: 3.6em;                        /* 需要指定高度 */
  text-overflow: -o-ellipsis-lastline;
}

 

 

三:js polyfill

css 不够, js 凑。

是的,就这样。

上面说的处理多行的方法兼容性太差了,用在实际项目上的机会恐怕不多(除非是直接使用 webkit 做 App)

真正可行的还是各种polyfill。

clamp.js : https://github.com/josephschmitt/Clamp.js     看文档提不错的,优先推荐。可以不指定行数,可以指定动画
ftellipsis : https://github.com/ftlabs/ftellipsis                   备选
succinct : http://micjamking.github.io/succinct                不怎么样,截取字符串来实现的

 

四:纯 css 实现的 polyfill

纯 css 实现的 ellipsis 效果。

 

demo:http://codepen.io/romanrudenko/pen/zhweq

原理就是:

外围包裹容器 wrap

    需要有明确的宽高

    overflow: hidden 

使用 ::before 创建 prop 元素,目的是给 realend 定位

    向左浮动

    需要与外围的大容器(wrap)等高

    需要有一定的宽度,目的是为了让 realend 被 main 挤开后能排在正确的位置上。

文字容器 main 元素

    向右浮动

    负的左外边距(margin-left)抵消 prop 的宽度对 main造成的影响

使用 ::after 创建 realend

    向右浮动

    负的左外边距(margin-left)与自身宽度相等,抵消自身的宽度。元素实际的宽度为0

    设置 padding-left 的值与 prop 相等。当 main 高度比prop高时,realend 被挤压到prop下方,这也是 prop为什么需要跟外围大容器(wrap)等高的原因

    设置为相对定位,使其能停留在相对大容器(wrap)的正确位置上

根据浮动原理,浮动元素会到达他能到达的最靠近上方的地方

当 main 中的文字没有溢出时,realend 在同为右浮动的 main 的下方,由于在大容器外,所以不会被显示出来

当文字使得 main 的高度大于 wrap 时,realend 被挤压到 prop 的下方,再设置相对定位,则会固定显示在 wrap 的右下角

设计还是非常精妙的,值得学习。

详见:http://www.mobify.com/blog/multiline-ellipsis-in-pure-css/

 

posted on 2014-03-24 11:23  yuanpeng  阅读(1071)  评论(0编辑  收藏  举报

导航