关于文字内容溢出用点点点(…)省略号表示

这篇文章发布于 2009年09月5日,星期六,18:08,归类于 Web综合。 阅读 483284 次, 今日 3 次 119 条评论

 

// 关于多行文字点点点…显示见文末

文字打点前言

在实际的项目中,由于文字内容的长度不确定性和页面布局的固定性,难免会出现文字内容超过div(或其他标签,下同)区域的情况,此时比较好的做法就是当文字超过限定的div宽度后自动以省略号(…)显示,这样,按照习惯,人们都会知道这儿有文字被省略了。css中有个属性叫做text-overflow:ellipsis;配合其他一些属性可以实现IE,chrome,safria浏览器下文字溢出点点点省略号显示,在加上opera浏览器的私有属性-o-text-overflow:ellipsis;就目前而言,可以实现Firefox浏览器以外的所有主流浏览器的文字溢出点点点省略号显示。

而本文将提供多种兼容性上佳的文字溢出点点点省略号显示的方法,而里面不少方法就是自己想出来的。有使用外部辅助文件的,有纯粹的css方法的,还有使用jQuery方法的。每种方法都提供各个浏览器下的截图验证,提供实例页面,提供部分源文件,都是值得信赖的方法,希望对您有所帮助。文章中穿插了些牢骚,您可以跳过,与本文主体不是很相关。

您可以事先单击这里:本文各类方法的demo实例页面,两个页面对比或许更有助于理解和认识。

目录

1、常规css方法——使Firefox以外主流浏览器文字溢出省略号表示
2、使用ellipsis.xml文件使Firefox支持文字溢出后点点点省略号表示
3、我对网上些文章和网站的不满
4、我自己想出来的方法——margin负值定位法
5、jQuery限制字符字数的方法
6、jQuery自动判断宽度是否超出的方法

1、常规css方法——使Firefox以外主流浏览器文字溢出省略号表示

下图为此常用方法在各个浏览器下的表现:

IE6浏览器下

IE6浏览器下

IE7浏览器下

IE7浏览器下

chrome谷歌浏览器下

chrome谷歌浏览器下

Safari浏览器下

Safari浏览器下

opera浏览器下

opera浏览器下

Firefox火狐浏览器下

Firefox火狐浏览器下

可以看到,仅在Firefox火狐浏览器下无法实现文字溢出省略号表示,其文字直接从中间咔掉了。综合考虑代码成本,表现效果,我个人觉得这样子已经算是不错的了,追求完美和实际效益之间要追求一定的平衡。如果页面上很多文字都溢出,则需要寻求更兼容的方法,要是偶尔会出现文字溢出的情况,就是用这类css代码就足够了,单层标签,简单实用:

.zxx_text_overflow{width:27em; white-space:nowrap; text-overflow:ellipsis; -o-text-overflow:ellipsis; overflow:hidden;}

2、使用ellipsis.xml文件使Firefox支持文字溢出后点点点省略号表示

这是老外提供的一种方法,使用Firefox的私有属性调用一个XML文件,可以使Firefox火狐浏览器下文字溢出后以省略号的形式显示。
右键另存为下载:ellipsis.xml
调用方法如下:

-moz-binding:url('ellipsis.xml#ellipsis');

跟css样式写法一致。
需要注意的是:此XML文件不支持向上路径的访问,也不支持绝对路径的访问。也就是说此XML文件需要放在调用文件(css文件,或HTML文件)的同目录下或下一级目录下,不能向上访问。原因我是不清楚的,我反复试验,都证明如此。

下图为使用此XML文件后Firefox浏览器下的表现:

Firefox火狐浏览器下

Firefox火狐浏览器下

可以清除地看到溢出的文字部分用点点点省略号表示了。再结合上面的css样式,就可以实现所有主流浏览器下的单行文字溢出用省略号表示了。css表示如下:

.zxx_text_overflow{width:27em; white-space:nowrap; text-overflow:ellipsis; -o-text-overflow:ellipsis; -moz-binding:url('ellipsis.xml#ellipsis'); overflow:hidden;}

例如在实例页面中,此段css是写在页面上的,所以ellipsis.xml文件是放在HTML文件同目录下的。

3、我对网上些文章和网站的不满

昨天编写demo实例页面,想找之前看过的一个同仁提过的图片显示省略号的方法,结果发现很多打着称号兼容“IE,FF”的文章,不错啊,于是我看看是什么方法。结果一肚子的火。

所谓的兼容IE,FF的文章

所谓的兼容IE,FF的文章

图中显示的是Google搜索后的前五项,其中有四个是所谓的建站教程网站,这四个又是同一篇文章。
这篇文章很不负责,居然是我很久之前就想过且测过,由于兼容性等等问题而不采用的方法。用:after伪类和content在文字后面加省略号。这个方法可以说是完全行不通。

首先,标题就是个大大的错误,什么兼容“IE,FF”?第一、chrome不算浏览器吗?看这文章时间,chrome已经出来了,Safari,opera不算浏览器吗?就只要兼容IE,FF就可以了吗?第二、你兼容IE,FF吗?什么叫兼容,就是要表现一样。两个浏览器下表现一致吗?差远了!第三、你兼容IE吗?IE6和IE7下都天差地别的,还说什么兼容呢!

看这文章的意思,这世界上就只有两种浏览器,IE6和Firefox,我不知道作者是个很大的草包还是上世纪时空转移过来的程序员,用句赤壁里的话说就是“你过时了!”

其次,方法缺陷很多:1、说是兼容,其实反而大大破坏了兼容性,IE6和IE7下的表现就不一样,一句IE“不支持max-width”就让我想给作者扇个耳光,IE7不支持吗,别告诉我你写这文章时还没有IE7浏览器。2、本来chrome浏览器,Safari还有opera可以实现文字溢出省略号显示的,现在受限与:aftercontent,就会一处理不当,文字直接被截,就很丑了。3、多套用了一层标签,css也多了好几行,没有必要,资源消耗高。4、当文字很短时后面也还跟着个省略号,没有溢出为什么还要显示省略号呢?

无论是兼容性,资源占用,逻辑表现都是很屎的,是个完全不能用的方法。

我不是愤慨作者技术不行,而是不满没有一点道义和科研素养。睁着眼睛说瞎话,都是没有经过验证的东西,凭感觉大放厥词。我更鄙视那些所谓的教程网站,这些网站什么教程都拿来的,它只管点击率,不管是否正确实用,n年前淘汰的东西它也拿来,误人子弟啊!我就很纳闷,这些网站无论设计,还是布局,或是页面的兼容性都差的跟坨酝酿很久的猪屎一样,还教别人怎么做网站。我是看穿了,其实这篇文章不行他们是知道的,可以没有办法啊,“兼容IE,FF”,多诱人的关键词啊!不管怎样,得拿篇文章来占住这几个关键词啊!流量给了别人可不行啊!这些唯利是图的网站,将一篇完全不行的文章传来传去,就为了点破点击率。这跟三鹿有什么区别,做教程的,是教人的,随便拿一些错误的东西糊弄人,害了多少人啊,真是太没有道义了!

4、我自己想出来的方法——margin负值定位法

这里先上代码,HTML部分:

<div class="zxx_text_overflow" >
     <div class="zxx_con" >这是一段比较长的文字,用来测试是否文字溢出时会用省略号显示。</div>
     <div class="zxx_dotted" >…</div>
 </div>

css部分:

.zxx_text_overflow{width:24em; height:1.3em; overflow:hidden; zoom:1;}
.zxx_text_overflow .text_con{float:left; height:1.3em; margin-right:3em; overflow:hidden;}
.zxx_text_overflow .text_dotted{width:3em; height:1.31em; float:right; margin-top:-1.3em;}

结果在不同浏览器下的表现如下(IE6,IE7以IE6示例,Firefox和chrome以Firefox示例):

IE6下,IE7同类型,表现一致

IE6下,IE7同类型,表现一致

Firefox浏览器下表现

Firefox浏览器下表现

opera浏览器下表现

opera浏览器下表现

Safari浏览器下表现

Safari浏览器下表现

简要说明:此方法兼容IE6,IE7(IE8未测过),Firefox,chrome,Safari,opera浏览器。没有hack,没有生僻的css样式。文字短时,没有省略号,文字溢出时就出现省略号。可以说是相当不错的一个方法。原理也很简单:当文字内容足够长时就把隐藏在上面的省略号层给挤下来了。关键就是点点点所在div层的高度的绝对值要比其margin的绝对值大那么一点点。 如果您不习惯用em做单位,直接换作px就可以了,效果是一样的。

5、jQuery限制字符字数的方法

代码很简单,使用也很方便,如下:

//限制字符个数
$(".zxx_text_overflow").each(function(){
  var maxwidth=23;
  if($(this).text().length > maxwidth){
    $(this).text($(this).text().substring(0,maxwidth));
    $(this).html($(this).html()+'...');
  }
});

所产生的结果是:页面中class"zxx_text_overflow"的标签内部字符的个数将最多显示23个,如果原本字符个数大于23,则会在后面添加点点点省略号(...),如下图所示的:

jQuery限制字符个数实现溢出省略号表示

jQuery限制字符个数实现溢出省略号表示

6、jQuery自动判断宽度是否超出的方法

相比较前面一种方法,这个js实现的方法更加智能些(也更占用资源),通过复制节点(就是需要判断是否文字溢出省略号显示的标签层),获取其宽度,再判断其宽度是否大于样式中给定的宽度限值,大于则去掉尾部字符,添加省略号,循环,直到复制的层的宽度小于css给定值。
js代码如下:

var wordLimit=function(){
  $(".zxx_text_overflow").each(function(){
    var copyThis = $(this.cloneNode(true)).hide().css({
      'position': 'absolute',
      'width': 'auto',
      'overflow': 'visible'
    });
    $(this).after(copyThis);
    if (copyThis.width()>$(this).width()) {
      $(this).text($(this).text().substring(0, $(this).html().length-4));
      $(this).html($(this).html()+'...');
      copyThis.remove();
      wordLimit();
    } else {
      //清除复制
      copyThis.remove(); 
    }
  });
}
wordLimit();

css部分需要给定一个宽度值,例如:

.zxx_text_overflow { width: 400px; }

结果如下:

jQuery宽度判定实现溢出省略号表示

jQuery宽度判定实现溢出省略号表示

狠狠地点击这里:本文各类方法的demo实例页面

最后补充:
我抽了一会儿时间把上面两个jQuery的方法结合起来,写了个小小的jQuery插件,方便对jQuery感兴趣的人直接使用了。
这个单行文字溢出用点点点省略号显示的jQuery插件的使用很简单。例如:

$(".test1").wordLimit();

自动获取css宽度进行处理,如果css中未对.test1给定宽度,则不起作用

$(".test2").wordLimit(24);

截取字符数,值为大于0的整数,这里表示class为test2的标签内字符数最多24个

$.wordLimit()里面为空则根据宽度自动截取,有值的话就按照字符数进行截取了。

此插件js下载(右键,另存为)
源文件打包下载(zip 18.6K)

狠狠地点击这里:文字溢出省略号显示jQuery插件使用demo实例页面

文字溢出点点点结语

css,js等前端技术博大精深,肯定还有其他更好的解决方法,这里只是把我所知道的写下来,希望对其他人有所帮助。技术的进步是永不停息的,或许一两年后,我的这个文章里所提到的些方法会成为过时的东西的。希望如此!

更新于2010-04-16
有不少同行询问当含有a标签链接的时候如何解决点点点显示的问题,在本文的评论9,我提出了解决方案,您要是遇到同样的问题,可以在评论9处查看。

更新于2013-04-22
早在去年,所有浏览器都已经支持text-overflow:ellipsis;方法,因此,本文很多内容out了!

更新于2015-10-08
对于现代浏览器,例如webkit内核的浏览器,或者移动端,是可以实现多行文本内容超出点点点…最后一行显示的,典型的CSS组合如下:

.box {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
}

其中-webkit-line-clamp就是控制行数的,是3就是显示3行,3行结束点点点,如果是2则最多2行。

您可以狠狠地点击这里:多行文字溢出点点点…显示demo

你就会看到你想要的!

(本篇完)

分享到:


发表评论(目前119 条评论)

  1. yan说道:

    在多层嵌套flex布局的情况下就不起作用了,不知道是什么原因

  2. hupoo说道:

    更新于2015-10-08 这一条 在万恶的IE浏览器下 不支持display: -webkit-box;
    这个属性 所以没有达到预期效果。

  3. 张鑫旭3号说道:

    如果是一个容器里很多文字,最后的效果是要容器最后除了点点点还有操作文字例如(…更多),怎么破?

  4. zeig说道:

    鑫大你好,在提供的demo中,line-height设置为1的时候,dom的实际高度总是会多一个像素,想请教下什么原因造成的

  5. LISir说道:

    感谢提供的方法!!!

  6. zzz说道:

    用第一个方法为什么height是lineheight5倍,效果却是四行省略(。。。)呢

  7. Eric说道:

    鑫大,有没有什么方法能够隐藏一段文本前面的文字然后显示省略号?假如有这么一个例子,一段文本,有可能超长,一旦超长需要隐藏,但是用户最关心的是后半段文字,所以需要隐藏前半段文字。这个思考了很久,没有得到解决方案。求鑫大解答一番。

    • 张 鑫旭说道:

      《CSS世界》这本书P317有介绍,可以使用direction属性。

    • gahing说道:

      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      direction: rtl; //定义方向
      text-align: left;//防止父元素宽度足够的时候文字靠右右边
      unicode-bidi: plaintext; //防止尾部特殊字符显示在前面

  8. czy0729说道:

    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    word-wrap: break-word;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    line-height: 40px;

    一个p这样
    但是当这个p超过了触发了。。。的时候,高度只剩下36px,到底是为什么

  9. 笑口常开说道:

    微信下有的时候3个点会被截断,就剩一个或两个点,不知道什么原因?

    • 前端多烦恼说道:

      我也碰到这问题了,只剩下2个点,还是超到排版之外了,有什么解决办法吗

  10. 张鑫旭2号说道:

    鑫旭大神果然厉害!haha

  11. 小姐姐说道:

    男神,对于非webkit内核的浏览器,想要多行文本点点点,有没有解决方案呢?

  12. 更新于2015-10-08的方法说道:

    更新于2015-10-08的方法,为什么不需要text-overflow属性就显示点点点了呢?

  13. johansson说道:

    看着作者的说法就感觉他是个草包

  14. beqiang说道:

    第四个margin负值定位法:如果说文字的个数正好大于父盒子宽度-内容盒子右外边距-点点点的宽度。例如父盒子宽度17em 内容盒子右外边距3em 点点点3em,那么当文字为12个的时候,内容盒子占了15em,右边只剩下2em了,点点点会被挤下去,同时会因为margin-top:-1.3em展示在右边。 此时的效果就是文字和点点点之间隔了2em。

  15. 前端小虎说道:

    鑫鑫大神永远都是混乱的技术博客里的一股清流
    不过你这篇文章没有占住这几个关键字啊,我还是加上你名字才搜索出来的。

  16. Anne说道:

    多行溢出显示点点点 如何只用 CSS 使 firefox 也能实现 -webkit-line-clamp实现的样式? 还是只能js hack?

  17. 小崔说道:

    大神。看了你的不少的文章。很有启发,膜拜!!!

  18. chris说道:

    测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字
    测试文字测试文字测试文字测试文字测试文字测试文字测试文字测试文字

    css:
    .box{
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    }
    发现这样写就不会出现超过2行隐藏内容出现省略号;
    只有在设置p标签p{display:inline;}才会正常

  19. 流丽说道:

    Document

    *{margin:0;padding:0;}
    .main{width: 500px;margin:10px auto;}

    /* .zxx_text_overflow_4{width:256.25px; height:36px; overflow:hidden; zoom:1;background: red;}
    .zxx_text_overflow_4 .text_con{float:left; height:36px; margin-right:15px; overflow:hidden;line-height: 18px;font-size: 14px;}
    .zxx_text_overflow_4 .text_dotted{width:15px; height:15px; float:right; margin-top:-15px;} */
    .zxx_text_overflow_4{width:256px; height:36px; overflow:hidden; zoom:1;background: red;line-height:18px;font-size: 14px;}
    .zxx_text_overflow_4 .text_con{float:left; height:36px; margin-right:15px; overflow:hidden; }
    .zxx_text_overflow_4 .text_dotted{width:15px; height:18px; float:right; margin-top:-16px;}

    .zxx_text_overflow_4 .text_dotted{position: relative;top:-5px;}

    有你有我生活更精彩有你有我生活更精彩

    .zxx_text_overflow_4{width:256px; height:36px; overflow:hidden; zoom:1;background: red;line-height:18px;}

    .zxx_text_overflow_4 .text_con{float:left; height:36px; margin-right:15px; overflow:hidden; }

    .zxx_text_overflow_4 .text_dotted{width:15px; height:18px; float:right; margin-top:-16px;}

    大神,为什么我这里还没超出两行就显示点点点呢?

  20. vendor说道:

    第4点(4、我自己想出来的方法——margin负值定位法)中的示例Class对不上

  21. 有疑问说道:

    额,张大神,帮帮忙,,为什么我的省略号在2行的中间显示呢。。。然后后面还是文字,帮帮忙。

  22. 张大神说道:

    张大神,能问你个移动端line-height的问题吗。移动端按钮无论我是设置height,line-height相同还是直接用padding:1rem 2rem;这种写法。在安卓端无法垂直居中,总是偏向中上位置。因为根元素font-size是根据设备宽度给定文字大小,所以像比ipone6 plus屏幕小的手机根元素font-size会小于12px,出现该问题。用缩放transform:scale()也不行。还有其他的办法解决安卓的垂直居中问题吗?多谢了

  23. 张大神说道:

    真棒,解决了我两行文字省略号的问题,在手机端安卓上面,css两行文字省略号有bug,省略号出现在第二行文字中,但ios显示正常。还是用jq限制字数好了

  24. 博主V5说道:

    好几次问题都是在你这的文章里找到答案解决的,十分感谢,都是好文啊,收藏了站点,没事看看你写的文章学习学习,博主V5,感谢解惑。

  25. mango说道:

    大神,我有一个疑问啊。你写的这种情况是针对纯汉字的,可如果我文字中出现了数字或者字母怎么解决呢。
    比如,我限制两行文字,超出显示省略号。两行文字自测19个汉字正好,大于19个汉字显示省略号,一个汉字按照两个字符,我可以算长度,截取字符串,可如果有数字字母汉字混合的话,这字符串怎么截取呢,取多多长合适

  26. 鑫哥粉丝说道:

    刚好用到,谢谢大哥。
    百度出来的为了流量的破烂站点是太多了,方法都很不靠谱

  27. 业界大牛说道:

    如果我只要1.9行出省略号
    最后0.1是给 more用的
    这样怎么来呢

  28. bzksx2说道:

    margin负值定位法,对于全部是英文字符的无效怎么破呢?

  29. ff说道:

    这里为什么要这么写?
    $(this).text($(this).text().substring(0,maxwidth));
    $(this).html($(this).html()+’…’);

    不是可以更简便地这样写吗?
    $(this).text($(this).text().substring(0,maxwidth)+’…’);

  30. huaidan5859说道:

    2015-10-08的方法 在safari中行数能行 但是省略号在文字中间,而不是末尾。

  31. 呵呵哒说道:

    非常感谢,按照您2015-10-08更新的方法操作成功了。

  32. 哈哈哈说道:

    赞同

  33. playboyanta123说道:

    是line-height,打字都手抖

  34. playboyanta123说道:

    margin负值定位法的demo中的html的类名与css中的不一致,还有,这个例子如果不加line-heightz:1.3em,在IE9和chorme下会有多余的字显示出来,楼主可以自己测试。总的来说方法不错,值得借鉴。

  35. 扬帆说道:

    话说对于多行的省略怎么处理啊,能用css实现吗,不想用JS。

  36. 岩前剑客说道:

    不错的文章,不过现在可以用jquery插件dotdotdot来实现了。

  37. J.ruiF说道:

    受教了,举一反三,我辈楷模啊,还有一篇关于css的transform的matrix解析,突然感觉我的高中没白读啊

  38. Sigma说道:

    max-height: 4em;
    overflow: hidden;
    text-overflow: ellipsis;

    多行,如果是高度超出,可以实现加点吗?

  39. nanamikon说道:

    感谢博主分享,想了一下,width不宜设太大,不然当文案长度刚好将点点点挤下来的时候, 点点点离文案太远了,而且整个页面可能会不统一, 所以margin-right和width差一点点就好了.

    .zxx_text_overflow{width:24em; height:1.3em; overflow:hidden; zoom:1;}
    .zxx_text_overflow .zxx_con{float:left;height:1.3em; margin-right:1.1em; overflow:hidden;}
    .zxx_text_overflow .zxx_dotted{width:1em; float:right; margin-top:-1.3em;}

    这是一段比较长的文字,用来测试是否文字溢出时会用省略号显示。

  40. iupliu说道:

    用到了博主的方法。谢谢

  41. viki说道:

    edm里有没有办法实现呢

  42. 自民说道:

    为什么我的IE9始终都是截断显示,而不是省略号呢~

    苦闷中~

  43. lingpeiyong说道:

    我修改了一下楼主的源码,提高了截字的速度和兼容性,有个缺点是必须用span包容被截字的内容。
    /**
    * copyright c by zhangxinxu v1.0 2009-09-05
    * http://www.zhangxinxu.com
    * 用于截取字符串,被截取的字符串后后面加3个英文省略号
    * tips: 此插件会自动给截取的字符串外套一个span标签,
    * @param num 截取的字符串的个数,如果没有定义,则根据字符串所在的dom组件的显示宽度进行截取
    * @param addtitle 是否给截取的字符串加一个title(没有被截取的不会加),使得鼠标移上去时,显示所有的内容 true:是(默认) false:否
    * @example:
    * 1)$(“.f_word_limit”).wordLimit();
    * 2)$(“.f_word_limit”).wordLimit({num:20,addtitle:false});
    */
    (function($){
    $.fn.wordLimit = function(options){
    var theOptions = jQuery.extend ({
    addtitle:true, //鼠标在上面时,是否出现title
    }, options);
    this.each(function(){
    $(this).wrapInner(“”);
    this_span = $(this).children(‘span’)[0];
    if(!theOptions.num){
    var copyThis = $(this_span.cloneNode(true)).hide().css({
    ‘position’: ‘absolute’,
    ‘width’: ‘auto’,
    ‘overflow’: ‘visible’,
    });
    $(this_span).after(copyThis);
    if(copyThis.width()>$(this_span).width()){
    addTitle(this_span,theOptions);
    sublength = $(this_span).text().length * $(this_span).width()/copyThis.width();
    $(this_span).text($(this_span).text().substring(0,sublength-1));
    $(this_span).html($(this_span).html()+’…’);
    copyThis.remove();
    exactSetLength(this_span);
    }else{
    copyThis.remove(); //清除复制
    return;
    }
    }else{
    var maxwidth=theOptions.num;
    if($(this_span).text().length>maxwidth){
    addTitle(this_span,theOptions);
    $(this_span).text($(this_span).text().substring(0,maxwidth));
    $(this_span).html($(this_span).html()+’…’);
    }
    }
    });
    };
    function addTitle(this_span,theOptions){
    if(theOptions.addtitle){
    $(this_span).attr(“title”,$(this_span).text());
    }
    }

    function exactSetLength(this_dom){
    var copyThis = $(this_dom.cloneNode(true)).hide().css({
    ‘position’: ‘absolute’,
    ‘width’: ‘auto’,
    ‘overflow’: ‘visible’
    });
    $(this_dom).after(copyThis);
    if(copyThis.width()>$(this_dom).width()){
    $(this_dom).text($(this_dom).text().substring(0,$(this_dom).text().length-4));
    $(this_dom).html($(this_dom).html()+’…’);
    copyThis.remove();
    exactSetLength(this_dom);
    }else{
    copyThis.remove(); //清除复制
    return;
    }
    }
    })(jQuery);

  44. dxfan5说道:

    楼主很强大。想请问下,就是如果用jquery限制字数的方法可以用于在多行文字上,不仅限于单行文字?其实我是在找这个问题来着。。。

  45. 棉花冰杯说道:

    CSS实现截串的方式,在FF7.0以上的版本是支持的…截串的方式也可以用JS实现,用不了几行代码吧…