纯css折叠区域-基于checkbox
accordion
accordion即可折叠区域,和<details>标签类似,不过更灵活些。折叠区域往常多用javascript实现,这里就纯粹用css,就想法上也是异途同归。
折叠区域重在折叠两字,既然要折叠,必然要有能记录下当前折叠状态的元素存在,思来想去<input type="checkbox">恰好就是这样的元素,正好两个值,并且还可以互相切换,可以符合要求。如此说来,既然有了input,也能很自然地想到<label>了,label可以根据for来指向特定的input元素从而无需亲自点击它就可以修改它的状态,之后根据其状态checked来标志需要显示折叠区域,否则隐藏折叠区域。
实现的方法也不难,先设置.according-body的max-height为0,然后在checkbox为checked的状态下设置其max-height为一个足够大的值就好,如下:
.accordion-body{ padding-left: $unit-2; margin-bottom: $layout-spacing; max-height: 0; overflow: hidden; transition: max-height 0.25s; } input:checked ~, &[open]{ & .accordion-body{ max-height: 100rem; } }
注意到这里指定的是max-height而非height,因为我们实际上并不知道折叠区域的高度,既然不知道高度,为何还需要特别指定一个max-height便是一个小技巧了。仔细再看一下.according-body的transition属性,它是可以根据max-height来实现过渡效果的,这样便实现了简单的动画,虽然看上去折叠的内容不能高于100rem是一个bug,但实际上很少会遇到需要折叠这么一大块区域的情况,因此并非什么大问题。
accordion的大体结构这样便可以了,另外就是一些辅助性的效果,比方说折叠动作的时候显示区域旁边的小图标可以转一下之类的,利用transform便可以很轻易做到:
input:checked ~, &[open]{ & .accordion-header{ .icon{ transform: rotate(90deg) } } } .accordion-header{ cursor: pointer; display: block; padding: $unit-1 $unit-2; .icon{ transition: transform 0.25s; } }
如此一来accordion也就完成了,不过考虑也可以在details标签中添加该类,所以需要将summary标签自带的小标志取消掉,如下:
summary.accordion-header{ &::-webkit-details-marker{ display: none !important; } }
accordion的使用便只需要添加相应的类和input就好,如下:
<div class="accordion"> <input type="checkbox" id="ac-exp0" hidden> <label for="ac-exp0" class="accordion-header"> <div class="icon icon-menu"></div>古都</label> <div class="accordion-body"> <p> ... </p> </div> </div>