:target伪类匹配url中#后片段标识符对应的id元素,通过浏览器原生锚点跳转触发css样式切换,从而实现无js标签页;它不执行逻辑、不改历史、仅响应url变化。

什么是 :target 伪类,它为什么能替代 JavaScript 切换标签页
:target 匹配 URL 中 fragment(即 # 后的部分)所指向的元素。当用户点击 <a href="#tab1"></a>,浏览器会滚动到 id="tab1" 的元素,并让该元素成为 :target。这本身不触发 JS,但 CSS 可据此控制显示/隐藏——本质是利用浏览器原生导航行为驱动样式变化。
基础 HTML 结构必须满足的三个条件
结构松散或 ID 不匹配,:target 就不会生效:
-
<a></a>的href值(如#overview)必须与目标元素的id完全一致(区分大小写、无空格) - 被切换的内容块必须是具有
id的块级元素(<section></section>、<div> 等),不能是 <code><span></span>或无id的容器 - 所有标签页内容需默认隐藏,仅当前
:target显示——否则首次加载时会全部可见 - 用
visibility: hidden+opacity: 0替代display: none,避免布局重排影响其他元素 - 为每个 tab 设置固定高度或最小高度,防止
:target元素因内容为空而塌陷 - 添加过渡动画时,只对
opacity和visibility动画,display无法过渡 - 如果页面有多个
:target(比如嵌套锚点),浏览器只认最外层匹配项,不要依赖多 target 同时生效
关键 CSS 写法与常见失效原因
错误写法:section { display: none; } section:target { display: block; } 看似合理,但容易因继承、盒模型或父容器 overflow 导致内容不可见。更稳妥的方式是:
示例:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
section {
visibility: hidden;
opacity: 0;
position: absolute;
left: -9999px;
}
section:target {
visibility: visible;
opacity: 1;
position: static;
left: auto;
}
如何处理默认选中第一个标签页
URL 没有 fragment 时,:target 不匹配任何元素,所有 tab 都隐藏。解决方法只有两个可行路径:
- 在 HTML 中让首个 tab 的
id与页面初始 URL fragment 一致,例如直接访问page.html#tab1 - 用
:not(:target)配合默认显示逻辑:给所有 tab 设display: none,再用section:first-of-type强制默认显示——但这不是纯:target方案,属于混合策略 - 完全规避默认态问题:把首页内容放在一个无
id的常驻区域,其余 tab 用:target控制,这样“默认”就天然存在
没有 JS 时,无法在加载后自动跳转到 #tab1,所以初始状态必须靠 HTML 或 URL 设计兜底。
真正麻烦的不是切换逻辑,而是 fragment 变化不触发 history.pushState,导致前进/后退键行为受限,且无法监听状态变更——这些才是无 JS 标签页的硬边界。










