6

拜托,css这样实现多行文本“展开收起” 超酷的好吧

 2 years ago
source link: https://juejin.cn/post/7065207121175904264
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

拜托,css这样实现多行文本“展开收起” 超酷的好吧

2022年02月16日 07:33 ·  阅读 3501
拜托,css这样实现多行文本“展开收起” 超酷的好吧

那天午后,我站在你家门口,再次遇见了你,他又来牵起你的手

无法言语,我是什么,这样傻傻的我怎么守护你

这次我静静哭了选择放弃,我好想好想把记忆折叠起

可惜,记忆不能像之前那个需求一样自由展开与折叠起

前段时间接到一个需求,关于文字展开和收起的,走了很多路,踩了很多坑。

在这个夜深人静,想你想到泪流的时候,决定记录分享一下。

需求如下所述:

  1. 未满两行时
  1. 超过两行,少于7行时
  1. 超过7行时

就如上面所述,我倒是第一次做这种需求,于是就网上搜索下案例,然后就搜出下面这篇文章:

文章链接:juejin.cn/post/696390…

点赞和评论都挺多的,于是就用他的方案来实现了。

但是后面发现有些问题,其实他的文章后面的评论区也有读者提出来了问题。

其实我觉得问题也不大,于是问哦下设计大佬

显然,就收到了拒绝。

被拒绝是十分正常不过的事情了,不过这比被发好人卡杀伤力少太多了,不信你听听:

"你真的挺好的,人也很优秀,但是配不上我"

这矫情的措辞结构

经历过的人会懂

可能是孤独让情绪变得脆弱,毫无头绪的我,开始寻求网友的帮助。

群里就有大佬提供了这个

codepen.io/xboxyan/pen…

这个跟方法跟 上面介绍的那篇文章的方法差不多

不同点在于这个方法是利用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;
  });
},
复制代码

完美,收获了一帮小迷妹。

  1. 跟在文字后面的按钮可以不设置定位
  2. 处于文字行数末尾的按钮可以设置绝对定位然后
  3. 行数的判断可以用scrollHeight属性
  4. 利用伪元素来模拟省略号...
安装掘金浏览器插件
多内容聚合浏览、多引擎快捷搜索、多工具便捷提效、多模式随心畅享,你想要的,这里都有!
前往安装

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK