纯css标签页切换需用单选按钮(radio)配合:checked伪类实现,通过相邻/兄弟选择器控制内容显隐,隐藏radio时须保障可访问性,动画禁用display而改用opacity或max-height过渡。

用 :checked + <input type="radio"> 控制标签页显隐
纯CSS实现标签页切换,核心是把「当前选中状态」交给表单控件承载,:checked 伪类就是唯一触发器。不用JS,不依赖框架,浏览器原生支持稳定。
常见错误是直接用 <div> 或 <code><button></button> 做开关——它们没有可被 :checked 捕获的状态,结果只能写JS补救。
- 必须用
<input type="radio">(不能用checkbox),确保单选互斥 - 每个
input需带name属性且值相同,否则无法联动 - 标签页内容区要用相邻兄弟选择器(
~)或通用兄弟选择器(+)匹配到对应section,不能靠嵌套结构硬连 - 初始状态靠给第一个
input加checked属性控制,默认显示第一项
隐藏 radio 按钮但保留可访问性
视觉上要「极简」,就得藏掉原生单选按钮,但不能用 display: none 或 visibility: hidden——这会让屏幕阅读器完全忽略它,破坏可访问性。
正确做法是用定位+尺寸归零+透明度控制,让控件物理存在、逻辑可用,只是不可见:
input[type="radio"] {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
这样键盘 Tab 仍能聚焦,Space 可切换,屏幕阅读器也能读出 label 文本。
用 label[for] 绑定点击区域,避免错位
用户实际点击的是文字标签,不是看不见的 radio。如果 label 和 input 没正确绑定,点击无效,或者只在极小区域生效。
-
label必须有for属性,值等于对应input的id - 不要依赖隐式嵌套(
<label><input>文本</label>),某些旧版 Safari 对隐式 label 的:checked响应不一致 - 标签文字本身要设
display: inline-block或block,否则padding可能失效,点击热区变窄
切换动画卡顿?别用 display 控制显隐
想加淡入淡出效果,有人会写 display: none → block 配合 transition,结果动画根本不动——display 是离散属性,无法过渡。
可行方案只有两个:
- 用
opacity+pointer-events:默认opacity: 0; pointer-events: none;,激活时设为1和auto,再加transition: opacity 0.2s - 用
max-height+overflow: hidden做高度过渡(适合内容高度固定或可预估) - 绝对禁止在
:checked ~ section规则里写display: none,否则动画断掉还可能引发重排抖动
极简风格真正难的不是删东西,是删完之后状态链不断、语义不丢、动画不崩——所有控制都得落在 CSS 可过渡、可响应、可访问的交集里。











