这里还有一个小问题,“展开”按钮在点击后应该变成“收起”,如何修改呢?
有一个技巧,凡是碰到需要动态修改内容的,都可以使用伪类 content 生成技术,具体做法就是去除或者隐藏按钮里面的文字,采用伪元素生成
<label class="btn" for="exp"></label><!--去除按钮文字-->
.btn::after{
content:'展开' /*采用content生成*/
}
添加 :checked 状态
.exp:checked .text .btn::after{
content:'收起'
}
兼容版本由于前面的省略号是模拟出来的,不能自动隐藏,所以需要额外来处理
.exp:checked .text .btn::before {
visibility: hidden; /*在展开状态下隐藏省略号*/
}
基本和本文开头的效果一致了,完整代码可以查看 codepen 多行展开收起交互,兼容版本可以查看 codepen 多行展开收起交互(全兼容)
还有一点,如果给 max-height 设置一个合适的值,注意,是合适的值,具体原理可以参考CSS 奇技淫巧:动态高度过渡动画,还能加上过渡动画
.text{
transition: .3s max-height;
}
.exp:checked .text{
max-height: 200px; /*超出最大行高度就可以了*/
}
上面的交互已经基本满足要求了,但是还是会有问题。比如当文本较少时,此时是没有发生截断,也就是没有省略号的,但是“展开”按钮却仍然位于右下角,如何隐藏呢?
通常 js 的解决方式很容易,比较一下元素的 scrollHeight 和 clientHeight 即可,然后添加相对应的类名。下面是伪代码
if (el.scrollHeight > el.clIEntHeight) {
// 文本超出了
el.classList.add('trunk')
}
那么,CSS 如何实现这类判断呢?
可以肯定的是,CSS 是没有这类逻辑判断,大多数我们都需要从别的角度,采用 “障眼法”来实现。比如在这个场景,当没有发生截断的时候,表示文本完全可见了,这时,如果在文本末尾添加一个元素(红色小方块),为了不影响原有布局,这里设置了绝对定位
.text::after {
content: '';
width: 10px;
height: 10px;
position: absolute;
background: red;
}