拜托,css这样实现多行文本“展开收起” 超酷的好吧
点击上方 前端阳光,关注公众号
回复加群,加入技术交流群交流群
前言
2022.02.14的午后,我站在你家门口,再次遇见了你,他又来牵起你的手
无法言语,我是什么,这样傻傻的我怎么守护你
这次我静静哭了选择放弃,我好想好想把记忆折叠起
可惜,记忆不能像之前那个需求一样自由展开与折叠
前段时间接到一个需求,关于文字展开和收起的,走了很多路,踩了很多坑。
在这个夜深人静,想你想到泪流的时候,决定记录分享一下。
需求如下所述:
-
「未满两行时」
-
「超过两行,少于7行时」
未展开
展开
-
「超过7行时」
未展开
展开
就如上面所述,我倒是第一次做这种需求,于是就网上搜索下案例,然后就搜出下面这篇文章:
❝文章链接:https://juejin.cn/post/6963904955262435336#comment
❞
点赞和评论都挺多的,于是就用他的方案来实现了。
但是后面发现有些问题,其实他的文章后面的评论区也有读者提出来了问题。
其实我觉得问题也不大,于是问哦下设计大佬
显然,就收到了拒绝。
被拒绝是十分正常不过的事情了,不过这比被发好人卡杀伤力少太多了,不信你听听:
"你真的挺好的,人也很优秀,但是配不上我"
这矫情的措辞结构
经历过的人会懂
可能是孤独让情绪变得脆弱,毫无头绪的我,开始寻求网友的帮助。
群里就有大佬提供了这个
https://codepen.io/xboxyan/pen/LYWpWzK
这个跟方法跟 上面介绍的那篇文章的方法差不多
不同点在于这个方法是利用div高度来限制文字显示的行数的。
上面文章里是利用-webkit-line-clamp来限制行数。
然后它的省略号也是在label按钮里模拟出来的。
上面文章里的方法的缺点上面已经说了,那么群里推荐的方法是否也能解决问题呢?
其实不行,本来在pc上看确实是没问题了,但是在安卓和ios看发现不太行。
发现在ios上限制7行的时候,显示除了7.5行,就是多了半行。或者 总有一个手机对不齐(我们要适配各种安卓机和低端ios)
虽说两个方法都有缺点,但是都有优点,于是结合两者的优点就进行了我的方案的实现。
我的方案
<div class="activity-desc-wrapper">
<input
type="checkbox"
class="toggleInput"
id="toggleInput"
v-model="isUnFold"
/>
<div class="activity-desc" ref="descBox" id="descBox">
<label
class="btn"
for="toggleInput"
v-if="isMoreThan2Line && (!isUnFold || isMoreThan7Line)"
>{{ isUnFold ? '展开' : '收起' }}</label
>
概述文字概述文字概述文字概述文字概
述文字概述文字概述文字概述文字概述文字概述文字
<label
class="btn-no-absolute"
for="toggleInput"
v-if="isUnFold && !isMoreThan7Line"
>收起</label
>
</div>
</div>
首先,跟上面那篇文章里介绍的一样,用input来记录当前是展开还是收起状态,
不同点是我用了两个label按钮。
一个label
是不用定位的,直接跟在文字的末尾。这种是作为文字超过两行,但是未超过七行,展开的状态。
前面的label则是绝对定位到文字盒子的末尾。作为 文字超过两行未展开,展开后文字超过七行的情况。
可以看下css的实现
.activity-desc-wrapper {
display: flex;
.toggleInput {
display: none;
}
.toggleInput:checked + .activity-desc {
-webkit-line-clamp: 7;
}
.activity-desc {
padding: 0;
position: relative;
margin-top: 7px;
font-size: 24px;
font-weight: 400;
color: #8a8f99;
line-height: 1.2;
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
.btn {
position: absolute;
padding: 0 3px 0 7px;
font-weight: 400;
bottom: 0px;
right: 0;
line-height: 1.2;
font-size: 24px;
color: #939fe1;
background: #f5f7fa;
&::before {
content: '...';
color: #8a8f99;
transform: translateX(-100%);
}
}
.btn-no-absolute {
float: none;
font-size: 24px;
font-weight: 400;
color: #939fe1;
}
}
}
我的方案的另一个重点在于「判断文字是否超过2行和七行」,这个就在于获取文字的实际高度是多少,一开始以为是没办法获取的,只能获取到省略后的文字高度,在随便调试了一下之后,发现「scrollHeight」属性就可以获取到盒子的实际高度了,
mounted() {
// 判断文案实际行数
this.$nextTick(() => {
const height = this.$refs.descBox.scrollHeight;
const lineHeight = +window
.getComputedStyle(this.$refs.descBox)
.lineHeight.match(/\d+\.*\d+/g)[0];
this.isMoreThan7Line = height / lineHeight > 7;
this.isMoreThan2Line = height / lineHeight > 2;
});
},
完美,收获了一帮小迷妹。
总结
-
跟在文字后面的按钮可以不设置定位 -
处于文字行数末尾的按钮可以设置绝对定位然后 -
行数的判断可以用scrollHeight属性 -
利用伪元素来模拟省略号...
回忆起从前,我的心总是默默的等候
你曾经说你 想找一个依靠
等了好几天 等你的留言 却发现是空白一片
站在镜子前 是不是我的样子有点丑
我组建了技术交流群,里面有很多 大佬,欢迎进来交流、学习、共建。回复加群即可。
“分享、点赞、在看” 支持一波👍