纯 css 标签切换推荐用 input[type="radio"] + label + .tab-content 结构,核心是同名 name、label[for] 严格匹配 input[id],.tab-content 需位于同级后续位置,用 :checked ~ .tab-content 控制显隐;避免 for 拼错、漏 name、结构错位或 input 被隐藏失效。

用 :target 实现纯 CSS 标签切换,为什么不用 JavaScript 更稳?
因为不需要监听点击、不依赖 DOM 操作、无 JS 加载失败风险,且浏览器原生支持(IE9+)。但前提是每个标签页内容必须有唯一 id,且触发元素得是带 href="#id" 的链接或 label 关联的 input[type="radio"] —— 后者才是真·无 JS 切换的核心。
input[type="radio"] + label + .tab-content 结构怎么写才不翻车?
关键在「同一 name」和「for/id 匹配」。radio 本身不可见,靠 label 触发,再用相邻/兄弟选择器控制内容显隐。常见错误是漏掉 name 或 for 值拼错,导致点不动。
-
input必须有name(如name="tab"),否则无法互斥 -
label的for值必须严格等于对应input的id(不是name) -
.tab-content元素需紧跟在input后面,或用~选中后续同级元素 - 初始状态建议给第一个
input加checked,否则可能全黑
<input type="radio" name="tab" id="tab1" checked><label for="tab1">首页</label> <div class="tab-content">...</div> <input type="radio" name="tab" id="tab2"><label for="tab2">关于</label> <div class="tab-content">...</div>
:checked ~ .tab-content 为什么有时不生效?
因为 CSS 选择器只支持向后查找,不支持父级或前驱。如果 .tab-content 不在 input 同级之后(比如被包在 div 里、或位置在 input 前面),~ 就找不到它。此时要么调整 HTML 结构,要么改用 label + :target 组合——但后者要求 URL 变化,体验略硬。
- 结构错位:把
.tab-content放到input外层容器里 →~失效 - 用了
+却隔了其他元素 → 改用~ - 多个
tab-content共享类名,却没加「仅显示当前选中项」逻辑 → 需配合:not(:checked) ~ .tab-content隐藏其余项
移动端点击区域小、iOS Safari 不响应?
radio 默认尺寸极小,iOS Safari 对 label 点击识别率低,尤其当 label 内只有文字时。不加样式几乎点不中。
- 给
label加display: block或inline-block,并设padding(至少8px) - 避免
label内嵌span或其他包裹,直接放文字最稳 - 不要对
input设visibility: hidden(会禁用部分浏览器的关联逻辑),改用position: absolute; left: -9999px - Android WebView 旧版本可能忽略
for,确保label和input在同一 DOM 树层级
label 和 input 当成一个可点击整体 —— 这个关联一旦断开,整个机制就静默失效,还不好 debug。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











