纯 CSS 可实现标签页切换,但仅限静态场景::target 方案支持 URL 锚点但需 HTML 静态声明;radio+:checked 方案体验接近 JS 但结构约束强且无法响应 JS 修改的 checked 状态;:hover 方案仅适用于悬停演示。所有方案均无法响应外部状态变更,状态管理必须交由 JavaScript。

纯 CSS 能实现标签页切换,但“动态”二字要小心——它不支持运行时新增 tab、无法监听切换事件、不能读取 URL 参数触发默认选中,所有逻辑必须在 HTML 结构中静态声明。
用 :target 实现带 URL 锚点的切换
适合静态页面,点击链接跳转并高亮对应内容,浏览器地址栏会变化,可被书签收藏或后退恢复。
- HTML 中每个内容块需有唯一
id,链接用href="#id" -
.tab-content { display: none; }+.tab-content:target { display: block; }即可生效 - 首次加载无
:target,所有内容都隐藏;加一句#tab1:not(:target) { display: block; }让第一个默认显示 - 注意:若内容块不在文档流末尾(比如被
position: absolute移走),:target仍能匹配,但滚动行为可能异常
用 radio + :checked 实现无 URL 变化的切换
这是最常用、体验最接近 JS 的纯 CSS 方案,依赖兄弟选择器 ~ 控制显示,结构约束强但稳定。
- 所有
<input type="radio">必须和对应<div class="tab-content">在同一父容器内,且input必须在label和内容块之前 - 用
#tab1:checked ~ #content1这类规则控制显示,不能跨父级、不能用+(因为label在中间) - 默认选中靠
checked属性,别漏写;若想用 JS 后续控制,此方案就失效了——CSS 无法响应 JS 修改的checked状态 - 可加
transition到.tab-content,但只对opacity或transform有效,display无法过渡
用 :hover 实现悬停即显的简易切换
仅适合演示、原型或鼠标常驻场景,移开即消失,不保留状态,不适合正式产品。
立即学习“前端免费学习笔记(深入)”;
- 结构必须严格线性:
<li>标签 →<div class="tab-content">→ 多个<div class="tab-pane"> - 靠
li:hover ~ .tab-content .tab-pane:nth-child(1)这类选择器定位,但nth-child易受 DOM 变动影响,增删标签会错位 - 不支持键盘操作(
Tab+Enter),无障碍支持差 - 移动端基本不可用——没有 hover 触发机制
真正容易被忽略的是:所有纯 CSS 方案都无法响应外部状态变更。比如从另一个组件传参控制当前 tab、根据 localStorage 恢复上次选择、或配合路由系统同步激活态——这些必须交还给 JavaScript。CSS 只负责“呈现”,不负责“状态管理”。


















