众所周知,checkbox 有两个状态:选中与未选中。
而在我们平时的一些开发中,我们也有很多需求有两种状态来展示,例如:
- 侧边栏的展开与收起
- 菜单下级内容的显示与隐藏
- . . .
在以前,许多都是通过js来添加监听事件完成,其实呢,我们完全可以充分利用 checkbox 的两个状态来映射记录这种关系!
当选中时,我们给定一个样式;当未选中时,我们赋予另一个样式;然后通过我们的选择器组合来达到相同的效果!
这里我以菜单的手风琴样式举例,最终结果如下:
既然需要使用checkbox,那我们肯定是要在元素内部增加一个input的,只不过最终我们需要将这个input设置为隐藏。
基础布局不过多解释,这里只提一个重点:利用 :has() 选择器来筛选一些条件。
我们的HTML结构如下:
<section id="group">
<div class="tab">
<input type="checkbox" id="tagore" checked>
<label for="tagore" class="label">
Tagore
</label>
<div class="content">
<p>Sorrow is hushed into peace in my heart like the evening among the silent trees.</p>
<p>忧思在我的心里平静下去,正如暮色降临在寂静的山林中。</p>
</div>
</div>
<div class="tab">
<input type="checkbox" id="hemingway">
<label for="hemingway" class="label">
Hemingway
</label>
<div class="content">
<p>But a man is not made for defeat.A man can be destroyed but not defeated.</p>
<p>人不是生来要给打败的,你尽可把他消灭掉,可就是打不败他。</p>
</div>
</div>
</section>
我们要做的,就是让点击tab时,让其内部的 checkbox 状态改变
- 若是选中状态,则展开
.content的高度 - 若是未选中,则不做操作
注意:.content 元素默认高度我们设置为0,即隐藏起来。
写法一
使用兄弟选择器 + 和 ~
input:checked + .label::after {
transform: rotateX(-180deg);
}
input:checked ~ .content {
max-height: 300px;
}
写法二
使用 :has() 选择器来筛选条件
.tab {
// ...
&:has(input:checked) {
.label::after {
transform: rotateX(-180deg);
}
.content {
max-height: 300px;
}
}
}
最后附一个codepen的完整代码
![]()
动动小手点点赞,来年腰间缠万贯!
