CSS 选择器与 input 标签的联用

2024年3月24日
2020年8月14日
CSS

CSS 的选择器与 <input> 标签的联用可以代替 JS 实现一些简单功能,如标签筛选、可折叠菜单栏等。

主要想法

利用 checkboxradio 等控件的 :checked 伪类,配合 CSS 的选择器切换目标的 display 属性实现。

<style>
    .item {display: none;}
    #tagall:checked~.item, #tag1:checked~.tag1,
    #tag2:checked~.tag2, #tag3:checked~.tag3
    {display: unset;}
</style>
<input type="radio" name="filter" id="tagall" checked hidden>
<input type="radio" name="filter" id="tag1" hidden>
<input type="radio" name="filter" id="tag2" hidden>
<label for="tagall">all</label>
<label for="tag1">tag1</label>
<label for="tag2">tag2</label>
<div class="item tag1">item with tag1</div>
<div class="item tag2">item with tag2</div>
<div class="item tag1 tag2">item with tag1 tag2</div>
item with tag1
item with tag2
item with tag3
item with tag1, tag3
item with tag2, tag3
item with tag1, tag2, tag3

拓展

<label> 元素也可以根据 :checked 显示或隐藏,从而实现类似 radiocheckbox 相结合的效果。

item with tag1
item with tag2
item with tag3
item with tag1, tag2
item with tag2, tag3
item with tag1, tag2, tag3

当然,这种作法是不推荐用于实际情况的,n 个标签就需要 2^nradio 记录状态和 n2^n 个label控制状态的转移。这会导致代码十分冗长,而且标签的切换需要频繁地重排页面,以及伪类选择器的大量使用(属性选择器可以预先展开为 id 选择器),都会降低页面的性能。

根据这个原理,只要是可以抽象为有限状态机模型的理论上都是可以利用用 CSS 实现的,此外利用 animation 产生时间差切换显示不同的label还可以模拟出伪随机的状态游走(效果会受限于浏览器的时间精度和刷新策略)。

HTML + CSS3 是被认为图灵完备的,因为它可以实现元胞自动机 Rule 110,这里有一个实现的例子。因为无论是 HTML 还是 CSS 都无法自行改变元素的属性,所以每一步计算都需要人为介入,十分繁琐。

而且这已经超出了 CSS 设计初衷的应用范围,前面的只是一些小技巧,后面的几个就是奇技淫巧了。