单行和多行文本省略怎么写?
单行省略要同时写 white-space: nowrap、overflow: hidden 和 text-overflow: ellipsis,元素还要有确定的宽度。多行省略目前通用写法是 display: -webkit-box、-webkit-box-orient: vertical 加 -webkit-line-clamp,再配 overflow: hidden。标准的 line-clamp 属性浏览器支持还有限。
简答
商品标题太长,列表里只显示一行,末尾用省略号。单行要写三条:
white-space: nowrap不让文字换行,overflow: hidden把超出的部分藏起来,text-overflow: ellipsis在被截断的地方显示省略号。元素本身要有确定的宽度,比如块元素或者设了width、max-width。为什么要三条一起写?MDN 的说明是,
text-overflow只负责“怎样提示内容溢出了”,它不会让文字溢出,要靠overflow和white-space让文字溢出并隐藏。而且它只处理行内方向的溢出,所以管不了多行。多行省略目前通用的写法是带
-webkit-前缀的一组:display: -webkit-box、-webkit-box-orient: vertical、-webkit-line-clamp: 2,再加overflow: hidden。MDN 说明这个旧属性只在这种组合下生效。要注意,标准的
line-clamp属性已经写进规范,但浏览器支持还有限,现在还不能只写它。另外被截断的内容要有别的方式能看到,比如详情页或展开按钮。
单行省略
.title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
为什么常见的“只写了 text-overflow 没效果”?因为默认情况下文字会换行,不会溢出,也就没什么可提示的。white-space: nowrap 让文字挤在一行里溢出,overflow: hidden 让溢出部分不显示,text-overflow 才有机会把截断处换成省略号。
在 flex 布局里,省略常常失效,原因是 flex 子项默认的最小宽度是内容宽度,不会被压缩到比文字还窄。给这个子项加上 min-width: 0,它才能缩小,省略号才会出现。用 headless Chrome 实测,100px 宽的 flex 容器里,没加 min-width: 0 的子项被撑到 261px,加了以后是 100px。
多行省略
.desc {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
这组写法来自旧版的 WebKit 弹性盒,看起来奇怪。MDN 说明这几个带前缀的属性虽然已经废弃,但它们的配合方式已经完整写进规范,会一直被支持。-webkit-line-clamp 只有在 display 是 -webkit-box 或 -webkit-inline-box、并且 -webkit-box-orient 是 vertical 时才生效。
为什么还要 overflow: hidden?MDN 提醒,大多数情况下都要加,否则省略号会出现在第二行末尾,后面的内容却照样显示出来。用 headless Chrome 156 实测,16px 字号、20px 行高时,加不加 overflow: hidden,元素高度都是 40px,也就是两行;可是不加的话,后面几行文字会溢出到元素外面。
标准 line-clamp 现在能用吗
CSS Overflow 规范定义了不带前缀的 line-clamp,MDN 把它标为浏览器支持有限。在 Chrome 156 里,CSS.supports('line-clamp', '2') 返回 false,-webkit-line-clamp 返回 true,只写 line-clamp: 2 时文字不会被截断。所以现阶段多行省略还要写带前缀的那组,可以把标准写法一起写上,等浏览器支持后自动生效。
和标题的换行美化一起用的写法,见《text-wrap: balance 和 pretty 应该怎样使用?》。
常见追问
怎么判断文字有没有真的被截断?
在 JavaScript 里比较元素尺寸。单行看
scrollWidth > clientWidth,多行看scrollHeight > clientHeight,成立就说明有内容被隐藏,可以据此决定要不要显示“展开”按钮。
省略号能放在中间吗,比如保留文件扩展名?
text-overflow只能在行尾截断。保留扩展名一般把文件名拆成两段:前一段用单行省略,扩展名放在单独的元素里不收缩。