由《CSS世界》中利用max-height属性结合checkbox标签得到的启发
先说明,该方案本身就不支持显示指定行,但它对我后面实现该功能提供了方向,所以先带大家看看张鑫旭大神是如何实现 仅利用CSS实现隐藏多余内容,且展开收起支持动画 的吧
html代码:
该方案是摘抄自张鑫旭--《CSS世界》其具体实现是:将多余的文案放入另一个容器(more-content)中,
在初始化的时候,more-content设置max-height: 0; overflow: hidden; transition: max-height .3s;
点击展开时,再配合checkbox的checked属性,more-content设置max-height: /*一个足够大的最大高度值*/
class="more-content"
的标签里面放的就是初始要隐藏的内容,可以看到,这里是需要将要隐藏的内容和初始要展示的内容分在两个容器中放置的,我想这不是一个理想的方案,但是这不影响我们学习它,后面我会尝试给出更好的方案。
checkbox
用在这里是很巧妙的,CSS可以通过:checked
属性处理当checkbox
被勾选时的特定样式,这里当checkbox
被勾选时,代表“展开”,取消勾选时,代表“隐藏”
接下来我们为html设置一些样式:
.box {
max-width: 300px;
margin: auto;
}
.show-less { //初始时隐藏该选项
display: none;
}
.show-more {
display: block;
}
input[type='checkbox'] {
opacity: 0;
}
给more-content
设置的初始样式是关键:
.more-content {
max-height: 0; //初始高度设置为0,约等于设置了display:none
overflow: hidden;
transition: max-height .5s;
}
好了,接下来是勾选了checkbox
的样式:
input[type='checkbox']:checked ~ .show-less {
display: block;
}
input[type='checkbox']:checked ~ .show-more {
display: none;
}
input[type='checkbox']:checked ~ .more-content {
max-height: 600px; /*设置一个足够大的最大高度*/
}
解释一下代码中的max-height: 600px
, 这里的最大高度一定是要大于more-content
的文案高度的,但它是“足够大”不是“最大”,因为太大了动画切换会很奇怪。
可以看到,我们非常依赖兄弟选择器~
,如果你尝试将移到
more-content
, show-more
, show-less
任何一个元素的后面,你会发现这个选择器失效了。我对兄弟选择器使用甚少,我想这个原因还是DOM树的渲染顺序问题吧。
我的想法:结合line-height做到指定行数
总结一下上面的方案还存在的问题:
将多余行的内容放在了单独的容器里,前端仍然需要通过JS切分外露的内容和隐藏的内容,而切分有一个很大的问题,就是只能切指定数量的字符,无法控制行数,同样数量的字符,当外部容器宽度不一样、字体大小不一样、字符类型不一样(汉字、英文字母)等等,展示的行数都会不一样的
我在《CSS世界》中看到了对line-height
的介绍:
对于像文本这样的纯内联元素,
line-height
就是高度计算的基石,比如,line-height
设置为16px,则一行文字高度是16px,两行就是32px,三行就是48px,所有浏览器渲染解析都是这个值,1像素都不会差。
既然都这么说了,那是不是只要我将文本的容器设置为内联元素,然后设置其line-height
为某个值,设此时要求外露n行,那么外层容器的最大高度就是n * line-height
,当点击“展开“时,再把它的最大高度设置为“一个足够大的最大高度值”不就可以了吗?这样我也不用再有什么more-content
的容器了,而且还能指定行数!!
html代码:
该方案是摘抄自张鑫旭--《CSS世界》其具体实现是:将多余的文案放入另一个容器(more-content)中,
在初始化的时候,more-content设置max-height: 0; overflow: hidden; transition: max-height .3s;
点击展开时,再配合checkbox的checked属性,more-content设置max-height: /*一个足够大的最大高度值*/
CSS样式:
.box {
max-width: 300px;
margin: auto;
max-height: 48px;
overflow: hidden;
transition: max-height .5s;
}
.content {
display: inline; /*很重要!!*/
line-height: 24px;
}
.show-less {
display: none;
}
.show-more {
display: block;
}
input[type='checkbox'] {
opacity: 0;
}
input[type='checkbox']:checked ~ .box .show-less {
display: block;
}
input[type='checkbox']:checked ~ .box .show-more {
display: none;
}
input[type='checkbox']:checked ~ .box {
max-height: 600px;
}
注意:一定不要忘记将p标签设置为display: inline; 让它变成内联元素
这是我认为一个比较方便且完美的实现多行文字的显示与隐藏了,我在百度上搜索关键字,前面的文章全都是使用-webkit-line-clamp
属性的,这个属性的兼容性嘛,看看吧:
大家酌情参考,是否可以直接用这个属性吧。
另外:checked
选择器也有局限,第一是只能用于单选按钮和复选框,第二是也有兼容性问题:
改用js动态添加类名也是一个不错的选择:
//html
//js
var showMoreOrLess = document.getElementById('showMoreOrLess')
function showMoreOrLessChange() {
showMoreOrLess.setAttribute('class', showMoreOrLess.checked ? 'checked' : '')
}
关于line-height和font-size对内联元素高度的影响
其实我在看到line-height
完全决定了像文本元素这种内联元素的高度时,就有所疑问了,在我的印象里,font-size
同样也会影响,所以我也做了一个实验,将font-size
的值设置得比line-height
更大,然后看效果
.content {
display: inline; /*很重要!!*/
line-height: 24px;
font-size: 30px;
}
发现文字会被截断:
所以,使用这种方案时,一定要保证,font-size值比line-height小,否则显示会有问题。