欢送关注我的公众号:前端侦探
在平时开发中,常常会碰到一些须要判断高度的场景,比方当超过肯定高度后,须要主动呈现开展折叠按钮,如下
传统的思路必定是通过JS
去动静计算容器的高度,但这样就波及到加载机会的问题,获取早了可能元素还没渲染好,晚了又会有显著的卡顿感,或者会引起页面的闪动。
那有没有仅通过CSS
的办法呢?
当然也是有的!要实现下面这个例子的成果,须要解决以下几个问题:
- 如何判断不同的高度?
- 如何在不同的高度下展现暗藏点击按钮?
- 如何点击切换?
花几分钟一起看看吧
一、先思考一下布局
明确来讲,CSS
当初曾经有相干办法能够判断高度了,那就是CSS容器查问。不过这个个性太高级了,目前简直还不能实战,咱们这次介绍一种更加传统的形式。
如何判断不同的高度?换句话来说,什么样的布局在不同的高度下会有截然不同的成果?
思考一下
相对定位?地位齐全固定了,不行。
flex
布局?如同也只能管制程度方向上
grid
布局?这个水太深,没来得及钻研(可能也行?)
等等,除了以上,还有一个当初都避而不谈的浮动布局,为啥当初都很少用了呢,起因在于浮动布局十分软弱,细小的尺寸变动都能引起整个布局的坍塌。我记得以前用浮动布局的时候,都须要尺寸准确,略微出一点过错就导致浮动元素不晓得跑哪去了...
既然对尺寸十分敏感,是不是和本文的临界高度有肯定分割呢?
没错,明天要用到的形式就是浮动布局。
二、浮动布局的奥秘
一步一步,来搭建咱们所须要的页面雏形。
咱们先来看一个乏味的景象,这里有一个容器,外面有3
个子节点,别离为A
、B
、C
,其中A
左浮动,B
、C
右浮动
<div class="box"> <div class="a">A</div> <div class="b">B</div> <div class="c">C</div></div>
.a{ width: 100px; height: 100px; float: left; background-color: cadetblue;}.b{ width: 300px; height: 100px; float: right; background-color: coral;}.c{ width: 50px; height: 100px; float: right; background-color: darkgreen;}
当横向空间足够时,成果是这样的
此时,A
贴近右边,B
贴近左边,C
贴着B
如果横向空间有余,那么C
就会换行
当初C
看似如同跑到了B
的下方,其实是因为B
的高度还没有超过A
当B
的高度超过A
时,那么C
会有如下体现
此时,C
贴在B
的左侧,A
的下方
是不是很神奇?除了浮动布局,没有什么办法能够实现这样的成果了吧。那么,这和本文的例子有什么关系呢?
别急,其实这是一种极其状况,接着往下看
三、极其状况下的浮动体现
咱们能够设置一个极限状态,比方A
的高度充斥容器,B
的宽度充斥容器,此时B
必定会掉下来,咱们用负的margin
让B
仍放弃在一行,如下
.a{ width: 50px; height: 100%;}.b{ width; 100%; margin-left: -50px;}
此时,B
的高度不高于A
,所以C
依然是贴在B
的下方,并且靠右。当初让B
的高度超过A
,也就是超出容器高度,就变成了这样
此时,C
位于A
的下方。也就是,仅仅因为高度超过了一个临界值,C
就失去了两种截然不同的地位,如下
上面是动静演示(动静扭转B的高度)
试想一下,把C
当做是“开展折叠”按钮,在这个根底上移动一下C
的绝对地位,移到正下方,是不是就是咱们须要的成果了呢?上面的虚线框示意挪动后的地位,这样在视区范畴内,虚线框在高度有余时就是不可见的,只有在超过固定高度后才可见,示意如下(察看虚线框的地位)
残缺 demo 能够查看以下任意链接
- float demo (codepen.io)
- float demo (runjs.work)
整个原理就是这样了,上面来看具体实现
四、CSS 具体实现
当初回到最结尾的例子,依据后面的 demo 原型,能够革新成以下构造
<div class="content"> <pre class="text"> 很多内容... 很多内容... </pre> <label for="c1" class="btn"></label></div>
这里.text
就相当于B
,.btn
就相当于C
,至于A
齐全能够用伪元素::before
来代替
因为有点击切换的交互,所以须要用到input checkbox
,和label
关联起来,所以构造最终革新成这样
<div class="section"> <input class="content-check" type="checkbox" id="c1" hidden> <div class="content"> <pre class="text"> 很多内容... 很多内容... </pre> <label for="c1" class="btn"></label> </div></div>
而后加点款式丑化一下吧,因为原理和后面是完全一致的,这里就不反复展现具体细节了
.content{ width: 400px; max-height: 200px; overflow: hidden; border-radius: 4px; outline: 2px dashed royalblue;}.section{ display: flex;}pre{ white-space: pre-wrap;}.content::before{ content: ''; width: 100px; height: 100%; float: left;}.btn{ float: right; width: 100px; text-align: center; position: relative; left: calc(50% - 50px); transform: translateY(-100%); cursor: pointer;}.btn::after{ content: ''; display: block; height: 34px; background-color: #666; transition: .2s background-color; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 512'%3E %3Cpath d='M143 352.3L7 216.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.2 9.4-24.4 9.4-33.8 0z'%3E%3C/path%3E %3C/svg%3E") center/ 24px 24px no-repeat;}.btn:hover::after{ background-color: royalblue;}.btn::before{ content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 34px;}.text{ box-sizing: border-box; width: 100%; padding: 10px 15px; float: right; line-height: 1.5; margin: 0; margin-left: -100px; font-size: 18px; color: #232323;}
成果如下:
而后是点击切换成果,能够用:checked
来管制
.content-check:checked+.content{ max-height: fit-content;}.content-check:checked+.content .btn{ left: auto; right: calc(50% - 50px);}.content-check:checked+.content .btn::after{ transform: scaleY(-1);}
这样就能够管制不同的状态了
还能够加点遮罩,让点击处有一种淡出弱化的成果,示意别急,上面还有内容
.text{ /* */ -webkit-mask: linear-gradient(red 150px, transparent 200px);}
成果如下
残缺 demo 能够拜访以下任意链接
- CSS auto height expansion (codepen.io)
- CSS auto height expansion (runjs.work)
五、最初总结一下
想不到浮动布局还能实现这样的性能,总的来说,这是一种老本低廉但须要点想象力的实现形式,适应性和兼容性也都不错,上面总结一下
- 布局有很多种,浮动布局比拟非凡
- 浮动布局十分软弱,细小的尺寸都能引起整个布局的坍塌
- 超过指定高度后,因为浮动布局引起的坍塌,正好能够辨别两种状况
- 通过扭转按钮自身的绝对地位,能够让案例在超出指定高度后才可见
- 点击切换能够用
input:check
和label
相关联实现 - 淡出弱化成果能够增加一层蒙版
mask
,示意上面还有内容
最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤
欢送关注我的公众号:前端侦探
本文参加了SegmentFault 思否写作挑战赛,欢送正在浏览的你也退出。