先记住这个答案
text-overflow: ellipsis 本身没有问题,问题是 inline-block 元素没设宽度时是「包裹内容」的,文字有多长盒子就有多宽,文字不会超出盒子,也就没有可省略的部分。要让省略号出现,得同时满足四个条件:盒子宽度有上限,white-space: nowrap 不换行,overflow 不是 visible,text-overflow: ellipsis 写在这个盒子自己身上。所以 inline-block 元素补上 max-width 或 width,三件套就能生效。
- 省略号的前提:盒子比文字窄,并且溢出被裁剪
inline-block宽度随内容走,不限宽就不会溢出- 设宽度上限后再裁剪单行文字
- 纯
inline的width不生效
一个标签,省略号为什么不出来
常见写法是给用户名、标签这类短文本做成 inline-block,然后希望过长时省略。
<span class="tag">这是一个很长很长很长很长很长的标签名称</span>
<style>
.tag {
display: inline-block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis; /* 不出省略号:盒子和文字一样宽 */
}
/* 加上宽度上限后生效,短文本仍然按实际宽度显示 */
.tag { max-width: 120px; vertical-align: bottom; }
</style>第一段样式里,.tag 的宽度是按内容算出来的「收缩适应」宽度。只要父容器够宽,它就和文字一样长;父容器不够宽时,nowrap 的文字会让它继续变长,直接溢出父容器,而不是自己溢出。两种情况下 .tag 自身都没有溢出,所以不画省略号。
加了 max-width: 120px,文字超过 120px 时盒子停在 120px,文字从盒子里溢出,被 overflow: hidden 裁掉,省略号出现。用 max-width 而不是 width 的好处是短标签不会被撑成固定宽度。
vertical-align: bottom 是另一个小坑:overflow 不是 visible 的 inline-block,基线会变成下外边距边缘,和旁边文字对不齐,改一下对齐方式就好。
纯 inline 元素为什么完全不行
如果连 display: inline-block 都没写,span 是 inline 元素,情况更糟。inline 元素不是块容器,text-overflow 对它根本不生效,而且 width、max-width 对它也无效,想限宽都限不了。
所以对 span、a 这类行内元素,第一步是把 display 改成 inline-block 或 block,让它变成能设宽度、能裁剪溢出的块容器,然后才谈省略号。
- 父元素上写省略号也不行
- 另一种常见错误是把三件套写在外层
div上,溢出的却是里面一个inline-block子元素。text-overflow不继承,外层只把这个inline-block当成一个不可拆开的整体。按规范,外层为了放下省略号,会把行尾放不下的整个子元素藏起来,而不是截掉子元素里的半截文字。结果常常是标签整个消失、只剩一个省略号。想让标签里的文字自己省略,样式要写在这个标签元素上。
容易答错的地方
- 以为是
inline-block不支持text-overflow inline-block是块容器,完全支持。不出省略号是因为它没溢出,不是属性不支持。加上宽度上限立刻就能看到效果。- 只写了
text-overflow: ellipsis - 单独写没有任何效果。少了
overflow: hidden,溢出的文字直接显示出来;少了white-space: nowrap,文字会换行,也不会横向溢出。三个属性加一个宽度上限,缺一不可。 - 在表格单元格里只给
td设宽度 - 表格默认是自动布局,列宽会被内容撑开,
td上写width常常不起作用。要么给table加table-layout: fixed并设宽度,要么在td里放一个设了max-width的块元素来做省略。
面试官还会怎么问?
多行文本怎么省略?
用 display: -webkit-box、-webkit-box-orient: vertical、-webkit-line-clamp: 2 配合 overflow: hidden。虽然带 -webkit- 前缀,主流浏览器都支持。它同样需要宽度约束,文字要真的超过两行才会出现省略号。
按钮里的文字要省略,但按钮宽度要自适应,怎么写?
给按钮设 max-width,按钮内部的文字放一个 span,span 设 display: block 或 inline-block,再写三件套。如果按钮本身是 display: inline-flex,内部 span 是 Flex 子项,还要记得给它加 min-width: 0。
怎么判断文字是否被省略了,从而显示 tooltip?
用 JavaScript 比较元素的 scrollWidth 和 clientWidth。scrollWidth 大于 clientWidth 说明内容溢出了,也就是省略号正在显示,这时再挂 title 或 tooltip。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。