:checked + .target不生效是因为.target未紧邻input,中间不能有空格或标签;display:none无法过渡,visibility:hidden配合opacity可实现淡入淡出;移动端需用.overlay防点击穿透;选项卡用radio(自动互斥),筛选用checkbox(多条件独立)。

为什么:checked + .target不生效?
最常见的情况是 HTML 结构没对齐::checked + .target 要求 .target 必须**紧挨在 <input type="checkbox"> 后面**,中间不能有换行、空格或任何其他标签。浏览器会严格按 DOM 顺序匹配,哪怕只多一个 <span> 或文本节点,选择器就失效。
解决办法只有两个:
- 把
.target元素直接写在<input>后面,中间零间隔 - 改用
:checked ~ .target,它能匹配后面所有同级的.target,容错性更高
但要注意:~ 会“穿透”中间的其他元素,如果页面里有多个 .target,可能误中无关区块——建议加父容器 class 限定范围,比如 .sidebar :checked ~ .panel。
display: none 和 visibility: hidden 哪个更适合动画?
display: none 无法参与 CSS transition,设了 transition: all .3s 也白搭;而 visibility: hidden 可以配合 opacity 实现淡入淡出。
立即学习“前端免费学习笔记(深入)”;
推荐组合写法:
.target {
opacity: 0;
visibility: hidden;
transition: opacity .2s, visibility 0s .2s;
}
#toggle:checked ~ .target {
opacity: 1;
visibility: visible;
transition-delay: 0s;
}
这样能避免布局跳动,又保证动画平滑。别忘了给 <input> 加 position: absolute; opacity: 0; width: 0; 隐藏它,否则原生控件会干扰视觉。
移动端点击穿透怎么防?
纯 CSS 方案里,<input> 是透明不可见的,但它的点击区域仍在。如果侧边栏遮住了下面的内容,用户可能误点到背后的按钮或链接——这就是点击穿透。
必须加一层遮罩:
- 用
<div class="overlay">跟侧边栏同级,位置固定、全屏、背景半透 - CSS 里设
.overlay { display: none; },再写#toggle:checked ~ .overlay { display: block; } - 遮罩层 z-index 要高于侧边栏内容,但低于触发按钮(比如汉堡图标)
否则用户点了遮罩外的空白区,侧边栏关不了,体验直接断裂。
radio 和 checkbox 在选项卡和筛选里怎么选?
选项卡必须用 <input type="radio">,因为浏览器会自动取消同 name 下其他项的选中态;用 checkbox 就得靠 JS 同步状态,纯 CSS 做不到互斥。
数据筛选则相反:
- 单条件筛选(如“只看热门”)→ 用
radio - 多条件组合(如“iOS + 视频 + 付费”)→ 用
checkbox,每个勾选独立影响对应[data-category="ios"]等元素
结构上,所有 radio 必须共享 name 属性,且每个都要紧跟自己的 <label> 和目标内容块,否则 :checked + .panel 找不到对应面板。
:checked 本身没问题,问题永远出在 HTML 顺序、CSS 作用域或 display 的硬切换上。


















