CSS 如何处理文字折叠和收起

274 阅读2分钟

最近上班摸鱼有点多,既然摸鱼那么久摸高质量的鱼,突然想到这个文字折叠的效果,看好多还说需要JS二分查找计算,感觉好麻烦呀,于是乎查资料,整理一下,以备面试之需

开始

<div class="text">
   <label class="btn"></label>   
   <span>但听得蹄声如雷,十余乘马疾风般卷上山来。马上乘客一色都是玄色薄毡大氅,
   里面玄色布衣,但见人似虎,马如龙,人既矫捷,马亦雄骏,每一匹马都是高头长腿,
   通体黑毛,奔到近处,群雄眼前一亮,金光闪闪,却见每匹马的蹄铁竟然是黄金打就。
   来者一共是一十九骑,人数虽不甚多,气势之壮,却似有如千军万马一般,前面一十
   八骑奔到近处,拉马向两旁一分,最后一骑从中驰出</span>
</div>
<style>      
.text {        
  width: 475px;        
  border: aqua solid 1px;        
  color: #333;        
  font-size: 14px;      
}      
.btn {        
  color: dodgerblue;        
  cursor: pointer;      
}
</style>

这种效果很简单

但是一般又都是在右底脚,这种时候很容易考虑到 label 加个浮动再加个 margin-top, 但是设置margin 会失去文字环绕效果。

这时候我们考虑用伪元素来实现

.text::before {        
   content: '';        
   float: right;        
   height: 100%;        
   margin-bottom: -20px;      
}

但是这时候发现,浮动元素存在塌陷效果,高度设置异常,这里我们肯定没法指定高度,这时候应该想到,我们可以在外层包裹一成,这样父节点设置为flex, 高度由子节点撑开,然后伪元素在的百分比高度就生效了

<div class="content">
  <div class="text">
   <lable></label>
   <span>...</span>
  </div>
</div>

<style>
  .content {
     display: flex;
   }
 .text::before {        
   content: '';        
   float: right;        
   height: 100%;        
   margin-bottom: -20px;      
 }  
.btn {        
  float: right;        
  clear: both;        
  margin-right: 8px;   
}
</style>

这时候好像基本效果出来了,接下来该考虑交互展开折叠交互逻辑,

.text {        
  display: -webkit-box;        
  overflow: hidden;        
  -webkit-line-clamp: 3;        
  -webkit-box-orient: vertical;      
}

文字的展开与折叠

这里可以用  input type="checkbox" 控制展开与收起效果,checked 状态下用 改变文字,改变最大行数

最终代码是

<div class="content">      
  <input type="checkbox" id="exp" />    
  <div class="text">      
   <label class="btn" for="exp"></label>      
   <span>但听得蹄声如雷,十余乘马疾风般卷上山来。马上乘客一色都是玄色薄毡大氅,        
    里面玄色布衣,但见人似虎,马如龙,人既矫捷,马亦雄骏,每一匹马都是高头长腿,
    通体黑毛,奔到近处,群雄眼前一亮,金光闪闪,却见每匹马的蹄铁竟然是黄金打就。
    来者一共是一十九骑,人数虽不甚多,气势之壮,却似有如千军万马一般,前面一十八骑奔到近处,
    拉马向两旁一分,最后一骑从中驰出</span>      
  </div>    
</div>
<style>      
.content {        
 display: flex;      
}      
.text {        
 width: 475px;        
 border: aqua solid 1px;        
 color: #333;        
 font-size: 14px;        
 display: -webkit-box;        
 overflow: hidden;        
 -webkit-line-clamp: 3;        
 -webkit-box-orient: vertical;      
}      
.text::before {        
  content: '';        
  float: right;        
  height: 100%;        
  margin-bottom: -20px;      
}      
.btn {        
  color: dodgerblue;        
  cursor: pointer;        
  float: right;        
  clear: both;      
}      
#exp {        
  visibility: hidden;      
}      
#exp:checked + .text {        
  -webkit-line-clamp: 999;      
}      
.btn::after {        
  content: '展开';      
}      
#exp:checked + .text .btn::after {        
  content: '收起';      
}    
</style>