CSS文本溢出省略号:text-overflow:ellipsis及firefox兼容详解
轉載自: http://ipmtea.net/css/201011/16_407.html
这个标题其实已经是一个老生常谈的问题了。很多时候,比如网站最基本的文章列表,标题会很长,而显示列表的区域宽度却没有这么宽,这时候最正常的做法就是让超出宽度的部分文字用省略号(…)来表示。通常做法是网站后台程序截取一定的字符然后输出到前台显示或者前台用javascript截取一定的字符,但是通过控制字数来截取的话还是存在一个大问题的,因为中文和英文的字符宽度问题,这个字数不好控制,而且通用性较差。那么有没有更好的方法呢,比如直接用CSS来解决的,当然是有的。
text-overflow是一个比较特殊的属性,W3C早前的文档中(目前的文档中没有包含text-overflow属性,FML!)对其的定义是:
Name: text-overflow-mode
Value: clip | ellipsis | ellipsis-word
clip : 不显示省略标记(…),而是简单的裁切
ellipsis : 当对象内文本溢出时显示省略标记(…),省略标记插入的位置是最后一个字符。
ellipsis-word : 当对象内文本溢出时显示省略标记(…),省略标记插入的位置是最后一个词(word)。
至于为什么一开始我说text-overflow是一个比较特殊的样式呢?因为我们可以用它代替我们通常所用的标题截取函数,而且这样做对搜索引擎更加友好,如:标题文件有50个汉字,而我们的列表可能只有300px的宽度。如果用标题截取函数,则标题不是完整的,如果我们用CSS样式text-overflow:ellipsis,输出的标题是完整的,只是受容器大小的局限不显示出来罢了(表现上是超出部分显示省略标记…)。
text-overflow: ellipsis属性仅是注解,当文本溢出时是否显示省略标记。并不具备其它的样式属性定义。我们想要实现溢出时产生省略号的效果。还必须定义:强制文本在一行内显示(white-space:nowrap)及溢出内容为隐藏(overflow:hidden)。只有这样才能实现溢出文本显示省略号的效果。
参考资料:http://www.52css.com/article.asp?id=602
那么,如果我们要给p标签定义text-overflow:ellipsis就可以这么写:
p { white-space: nowrap; width: 100%; /* IE6 需要定义宽度 */ overflow: hidden; -o-text-overflow: ellipsis; /* Opera */ text-overflow: ellipsis; /* IE, Safari (WebKit) */ }
使用样式前:
使用样式后:
浏览器兼容状况
Browser Lowest Version Support of
Internet Explorer 6.0 text-overflow
Firefox (Gecko) — —
Opera 9.0 -o-text-overflow
Safari (WebKit) 1.3 (312.3) text-overflow
Firefox不支持这个属性!这回,Firefox你也太另类了吧!还有别的办法么,当然有,方法还挺多的。
比如Mozilla developer center推荐的-moz-binding CSS属性。Mozilla developer center给出的理由是text-overflow没有W3C的规范…但是因为Firefox支持XUL,一种XML的用户界面语言。并且Firefox还支持XBL,一种XML绑定语言,这样我们就可以使用Mozilla developer center推荐的-moz-binding CSS属性来绑定XUL里的ellipsis属性了。
1.XUL方式
首先,我们创建XUL,它应该被保存为ellipsis.xml:
<?xml version="1.0"?> <bindings xmlns="http://www.mozilla.org/xbl" xmlns:xbl="http://www.mozilla.org/xbl" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" > <binding id="ellipsis"> <content> <xul:window> <xul:description crop="end" xbl:inherits="value=xbl:text"><children/> </xul:description> </xul:window> </content> </binding> </bindings>
然后我们需要把这个xml文件放到一个目录,原来的css需要加一条,变成这样
p { white-space: nowrap; width: 100%; /* IE6 需要定义宽度 */ overflow: hidden; -o-text-overflow: ellipsis; /* Opera */ text-overflow: ellipsis; /* IE, Safari (WebKit) */ -moz-binding: url('ellipsis.xml#ellipsis'); /* Firefox */ }
虽然Firefox通过XUL的方式实现了ellipsis,但是还是需要注意以下这些问题:
1.经过XUL处理过的文本你将不能被选中,按理说-moz-user-select: text; 属性将允许文本被选中,但是我没有试验成功。
2.如果你给父元素绑定了XUL,那么子元素的内容将变得不可见。例如:
如果你只是给p节点绑定了XUL,那么在Firefox下你将看不到haha这个内容。
它的源代码实际上是:
<p>It is a long<em> haha</em> long long long long text!</p>
参考资料:
http://www.w3.org/TR/2003/CR-css3-text-20030514/
http://www.quirksmode.org/css/contents.html
https://bugzilla.mozilla.org/show_bug.cgi?id=312156
https://developer.mozilla.org/En/XUL
https://developer.mozilla.org/En/XUL/Description
http://www.rikkertkoppes.com/thoughts/2008/6/
http://www.w3.org/TR/xbl/
http://www.w3.org/TR/css3-text/
2.Javascript方式
既然XUL无法完美解决Firefox下文字溢出显示…,那么我们就求助javascript吧,当然,并不是古老的截取一定数目的字符来实现。
这里以jQuery为例,代码如下:
(function($) { $.fn.ellipsis = function(enableUpdating){ var s = document.documentElement.style; if (!('textOverflow' in s || 'OTextOverflow' in s)) { return this.each(function(){ var el = $(this); if(el.css("overflow") == "hidden"){ var originalText = el.html(); var w = el.width(); var t = $(this.cloneNode(true)).hide().css({ 'position': 'absolute', 'width': 'auto', 'overflow': 'visible', 'max-width': 'inherit' }); el.after(t); var text = originalText; while(text.length > 0 && t.width() > el.width()){ text = text.substr(0, text.length - 1); t.html(text + "..."); } el.html(t.html()); t.remove(); if(enableUpdating == true){ var oldW = el.width(); setInterval(function(){ if(el.width() != oldW){ oldW = el.width(); el.html(originalText); el.ellipsis(); } }, 200); } } }); } else return this; }; })(jQuery);
这段js的原理很简单,就是通过不断的比较宽度值,然后逐个缩短字符宽度,当最后宽度合适的时候,停止循环,就实现了文字溢出显示…的效果。
这段js还需要一段css来配合。
.overflow { text-overflow: ellipsis; -o-text-overflow: ellipsis; white-space: nowrap; overflow: hidden; }
js里有个判断就是当样式里出现text-overflow或者-o-text-overflow的时候,便不会执行这段js。因为支持这两个属性的浏览器可以自己实现ellipsis效果。
这两种方法都可以实现Firefox下ellipsis的效果,如何取舍使用,具体还得根据你要运用到的项目的具体情况来具体分析,XUL实现的方法的不足之处在以上已经很详尽地列举了,如果你可以避免或者说这些无关你项目的大问题,那么XUL不失一个好方法。
至于其他的一些方法你可能在网上也有看到,比如用:after伪类来实现等,个人不推荐,所以我这里也不细说了。
======================================================================
文本溢出省略号兼容的一种解决方法
.textoverflow a { display:block; width:120px; margin: 0px 0px 0px 3px; white-space: nowrap; overflow: hidden; float: left; -o-text-overflow: ellipsis; /* for Opera */ text-overflow: ellipsis; /* for IE */ } .textoverflow:after{ content: “…”; }/* for Firefox */ @media all and (min-width: 0px){ .textoverflow:after{ content:”"; }/* for Opera */ }