CSS中怎么实现多行省略,有哪些方案
发布时间:2023-10-20 15:31:37 所属栏目:语言 来源:
导读:这是个老掉牙的需求啦,不过仍然有很多人在网上找解决方案,特别是搜索结果排名靠前的那些,都是些只会介绍兼容性不好的使用 -webkit-line-clamp 的方案。
如果你看到这篇文章,可能代表你正是从那么多千篇一律的
如果你看到这篇文章,可能代表你正是从那么多千篇一律的
这是个老掉牙的需求啦,不过仍然有很多人在网上找解决方案,特别是搜索结果排名靠前的那些,都是些只会介绍兼容性不好的使用 -webkit-line-clamp 的方案。 如果你看到这篇文章,可能代表你正是从那么多千篇一律的文章中跳转过来的,想找更好地方案的。那恭喜你,没有更好的,只有更合不合适的,当然,前提是我的文章流量够多,能被顶上去你才有机会看到。 这里介绍三种多行文本截断的方法,当然第一种就是你看到想吐的 -webkit-line-clamp 方案,不想看就直接跳到第二种方法开始看啦。 使用-webkit-line-clamp 对多行文本的容器应用如下样式 div { display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; -webkit-line-clamp: 2; } 除了 -webkit-line-clamp 其他属性固定不变,主要是将对象作为弹性伸缩盒子模型显示,并设置伸缩盒对象的子元素的排列方式。 而 -webkit-line-clamp 是用来控制多少行进行省略 优点: 浏览器原生支持的省略行为,样式看起来很舒服 简单方便使用 缺点: 看属性的前缀就知道,这是 webkit 内核的浏览器支持的,兼容性不是广泛。 使用场景 如果你只针对webkit内核浏览器或者移动端(移动端浏览器多数是webkit内核),那么使用该方案是最好的了。 利用绝对定位 这个方案其实很好理解的,首先我们对于一个装内容的容器右边预留一个空间用来放省略号,用 padding-right: 1em; 来预留空间,为啥是1em呢,一个省略号差不多就是1em啦,用em单位是为了响应字体大小。 用绝对定位把省略号定位在这个预留的空间右下角。 html <div class="wrap">内容</div> css .wrap3 { position: relative; padding-right: 1em; /*max-height是line-height的几倍,想最多显示多少行就几倍*/ max-height: 3.6em; line-height: 1.2em; text-align: justify; overflow: hidden; } .wrap3:before { position: absolute; right: 0; bottom: 0; content: '...'; } 这样的话,省略号永远都会存在的。所以要解决这个问题,我们用一个跟背景颜色一样的方块遮住省略号,那么关键点就是,怎么知道何时要遮住,何时不遮住呢? 思路: 用于挡住省略号的方块也是绝对定位,靠右定为, right: 0 ,但是 bottom 值就不要设置了,如果不设置的话,该方块会跟着文本内容的实际高度移动,而不是 max-height 的高度。这样的话,当不需要省略时(即不超过 max-height )时,就刚好是 bottom: 0 的情况,就会挡住省略号。当要进行省略时(即超过 max-height )就会挡不住省略号了,它自己也会被 overflow: hidden 给隐藏掉了。 所以最终方案是: html <div class="wrap">内容</div> css .wrap { position: relative; /*line-height和height要相互配合,显示多少行就省略,就是line-height多少倍数*/ line-height: 1.2em; max-height: 3.6em; /*此属性看需求来判断是否设置,因为设置了padding-right,多腾出了点位置,该值一般为padding-right的值的负值*/ /*margin-left: -1em;*/ /*此值写死成1em就好,因为省略号大概就是占用1em的空间*/ padding-right: 1em; text-align: justify; overflow: hidden; } .wrap:before { position: absolute; right: 0; bottom: 0; content: '...'; } .wrap:after { position: absolute; right: 0; /*宽高写死1em就好,因为省略号大概就是占用1em的空间,用来遮挡住省略号,也基本上跟wrap的padding-right一致*/ width: 1em; /*与wrap的行高实际值保持一致*/ height: 1.2em; content: ''; /*要跟所在背景颜色一致才能遮挡住省略号后觉得没异样*/ background-color: #fff; } 优点 兼容性好,各大浏览器支持 自适应高度,不用写死高度,设定超过多少行才需要进行省略显示 自适应宽度 自适应字体大小,字体大小不会影响到原本的需求,即要求多少行省略就多少行才省略 缺点 文字右边会故意留空一些位置给省略号放置 需要考虑所在的背景颜色,因为after伪类要用背景颜色来遮挡住省略号 利用float布局 这个方案对于基础知识不扎实的童鞋们,可能不太好理解,如果仅是想找个解决方案不想知道原理的话,可以直接去里看 在说该方案之前,要先理解这么一个现象: 有这么一段html <div class="wrap"> <div class="left">左浮动</div> <div class="right1">右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1右浮动1</div> <div class="right2">右浮动2</div> </div> 应用这么一段样式 .wrap { height: 100px; } .left { float: left; width: 60px; height: 100%; background: pink; } .right1 { float: right; /*占满wrap除left剩余宽度*/ width: calc(100% - 60px); background: #95d9f8; } .right2 { float: right; background: yellow; } 正常情况下会显示成这样,这也是大家一般所能想象的预期情况: 出现这个正常现象的条件是: .right1 的高度不超过 .left 的高度(即内容少) .right2 的宽度少于 .right1 的宽度 好了,这个情况大家理解了吧。那么接下来,我们对 .right1 的内容增多至超出左浮动的高度,会发生接下来的一幕 右浮动2卡在左下角了。 要问我为什么会这样?额...看来你对float的基础知识不扎实呀,建议夯实一下基础知识,其实我也解释不了,我只知道这是float的一个正常表现。 出现这个现象的条件是: .right1 的高度超过 .left 的高度(即内容多) .right2 的宽度少于或等于 .left 的宽度 知识转化成需求实现 在理解了上述两个情景后,我们应该怎么利用这些知识来匹配对应的需求呢? 假设右浮动1的文本内容就是我们要进行多行省略的内容,右浮动2的内容就是省略号(...)。这样当内容少时,省略号就是上述的第一个情况,内容多的时候就是第二个情况。 这种动态变化,是不是像“文本少时不省略,文本多时进行省略”这种需求变化呢。在这个基础上,我们要解决的是 在第一种情况右浮动2隐藏掉,第二种情况下右浮动2出现在 .wrap 的右下角,超出高度的内容隐藏掉。 要解决上述问题,只要使用 position: relative; 进行相对定位即可。 .wrap 父容器应用 overflow: hidden; 。 第一种情况下,定位到父容器外部,就隐藏掉了。而第二种情况,就定位到父容器右下角。 好了,现在该解决方案的焦点,就放在如何准确定位的问题上了(下一小节)。在处理定位问题前,先把目前掌握的情况转化为实际的需求代码: <!--把左浮动和右浮动2采用伪类元素替换掉实际标签--> <div class="wrap"> <div class="text">右浮动1</div> </div> .wrap { height: 100px; /*line-height用来控制最多显示多少行文本*/ line-height: 20px; overflow: hidden; } .wrap:before { float: left; /*要大于或等于after元素宽度*/ width: 1.5em; height: 100%; content: ''; } .text { float: right; /*用负值的marginLeft来避免由before产生的空白空间*/ /*因为实际需求上你的父容器里不可能左边是一片空白吧*/ margin-left: -1.5em; /*既然采用了负值marginLeft,那么文本容器宽度就可以100%占满父容器宽度了*/ width: 100%; } .wrap:after { float: right; /*一般三个点就差不多1em宽,用em作单位能自适应字体大小*/ width: 1em; content: '...'; } 如果你这时候好奇,为什么 .text 都设置了 width: 100%; 了,内容多时 :after 还是会卡在 :before 底下呢?是因为即使 .text 设置了 margin-left: -1.5em; ,但是实际上并不会影响到原本的文档流情况,原本该是怎样的就是怎样,设置了负值的margin,影响的只是 .text 自身的呈现样式。 如何定位 解决定位问题是基于上小节的代码基础上。目前暴露的问题有: 内容少即不需要做省略时,省略号显示出来了 内容多即需要省略时,省略号隐藏了 先解决第二个问题 思路:要把这个 :after 向右移动到 .wrap 右边,向上移动到最后一行的位置。 用 position: relative; 来控制的话, top 值好取,取 .wrap 的 line-height 实际值一样,取负值就好了。关键是left值,怎么取才能刚好在右下角呈现出来。 如果你能明确知道 .text 的宽度的话(如100px),其实设置 left: 100px; 即可,但是这样的话只能针对固定宽的情况,不能自适应宽度。要想实现自适应,left的值取百分比就行了,那么到底是百分之多少呢?这是纠结的。索性就取100%吧,会发现会移出到父容器外。 那要刚好出现在右下角的话,省略号的初始位置就必须要在 .wrap 的左侧,紧挨着 .wrap ,才能 left: 100% 后出现在右下角。 现在问题就变成如何让 :after 刚好出现在 .wrap 的左侧了。 以下代码对于基础不扎实的人,可能有些难理解了(新增部分在注释处): .wrap:after { float: right; /*因为下面设置了margin,所以这里的宽度值大小没有要求*/ width: 1em; content: '...'; /*这两个属性是设置紧挨着.wrap左侧*/ /*此值要跟自身宽度一样,取负值*/ margin-left: -1em; /*此值要跟before宽度一样*/ padding-right: 1.5em; /*这是定位省略号的位置*/ position: relative; left: 100%; /*与父元素wrap的行高实际值一样,取负值*/ top: -20px; } 关于设置margin和padding值那里,如果你能理解就最好了,不能理解的话,我尽量解释一下,其实这也真不好说。 首先是应用 margin-left: 1em; 的时候,由于 :after 的宽度比 :before 的要小,所以按照原本的float布局的话,在一行里 粉红色为左浮动,蓝色红色为右浮动,如果红色的宽度不断增大至除粉红色剩余空间,由于一行的空间不够,蓝色会被挤到换行右浮动了。但是如果设置蓝色的margin-left为本身宽度的负值,那么这时候一行的空间还是有位置给它的,就变成了如下这样了 按照上述原理,设置了 margin-left: 1em; 后, :after 就变回到父容器的第一行上了,紧挨着父容器左侧。但是我们不能让它回到第一行上呀,所以设置 padding-right: 1.5em; 让它实际占的空间变大到第一行容不下它,就变回到原本的卡在 :before 下的位置,只是padding值让它移动到左侧了 好了我解释完了,能不能看懂,只能看你的造化了哈哈。 值得留意的是,上面代码里关于width的注释写着“因为下面设置了margin,所以这里的宽度值大小没有要求”,之前都要求小于等于 :before 宽度,但是现在由于采用margin-left负值抵消了本身的宽度,所以这个要求转化对 padding-right 了,这时是等于 小结 到目前位置,所有问题都解决了。针对上述所有讨论的问题,总结为以下代码(具体优化有注释说明): css样式 .wrap { /*需要定高*/ height: 100px; /*用来设置显示多少行才省略,值一般为wrap的height值/行数求得,但是这个行数会受到字体大小的限制*/ /*字体太大了,设置显示很多行也会很丑,都挤一块了,所以这个实际值,要看具体需求和实践*/ line-height: 25px; /*加上此属性显示效果更佳,就算部分浏览器不支持也影响不大*/ text-align: justify; overflow: hidden; } .wrap:before { float: left; /*这个值可以随意设定,不论单位还是什么*/ width: 1em; height: 100%; content: ''; } .wrap:after { float: right; /*大小随意,设置em单位最好,可随字体大小变化而自适应*/ /*如果要采用以下渐变效果,那么这个值要大于before里的width值效果会比较好点*/ /*值越大,渐变的效果越明显影响的范围越大。*/ width: 2.5em; /*与父元素wrap的行高实际px值一样*/ height: 25px; /*此值要跟自身宽度一样,取负值*/ margin-left: -2.5em; /*此值要跟before宽度一样*/ padding-right: 1em; content: '...'; text-align: right; /*这里开始利用在float布局的基础上进行定位移动了*/ position: relative; /*与父元素wrap的行高实际值一样,取负值*/ top: -25px; left: 100%; /*设置渐变效果是为了省略号和内容衔接得自然点,没那么突兀,要注意要跟文字所在的背景的颜色搭配(把white替换成背景色)*/ background: #fff; background: -webkit-gradient(linear, left top, right top, from(rgba(255, 255, 255, 0)), to(white), color-stop(50%, white)); background: -moz-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white); background: -o-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white); background: -ms-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white); background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white); } .wrap .text { float: right; /*该值要等于wrap:before的width值*/ margin-left: -1em; width: 100%; } html文件: <div class="wrap"> <span class="text"> 示例2: 散发设解决看手机啦开发交 </span> </div> 优点 兼容性好,满足不是webkit内核的浏览器都能支持 自适应宽度 缺点 固定高度,不能自适应高度,因此显示多少行还要受字体大小限制 需要为文字包裹一个标签用以设置样式 从读样式代码上来看,理解起来不是很好理解 如果省略号所在元素不用渐变色背景,偶尔会截断得突兀,如果要用渐变色背景,要注意与文字所在的背景下的颜色搭配 (编辑:聊城站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐