:target 是 CSS 原生伪类,匹配 URL fragment(如 #section2)精确对应的 id 元素并应用样式,不触发跳转;需同时满足:URL 含 fragment、页面存在严格同名 id 元素、且该元素非 name 锚点。

什么是 :target 选择器?它不是“跳转”,而是“匹配”
:target 不负责触发页面滚动或跳转,它只在 URL 带有 fragment(即 #xxx)且该 fragment 对应一个元素的 id 时,**自动为那个元素添加样式状态**。换句话说:它不干“导航”的活,只干“高亮/响应”的活。
常见误解是以为写了 :target { color: red; } 就能让点击链接后文字变红——这确实会发生,但前提是:链接必须用 href="#xxx" 跳转到同页某个 id="xxx" 的元素,浏览器才会把该元素设为当前 :target。
怎么让 :target 生效?三个硬性条件缺一不可
只要漏掉任意一条,:target 就不会匹配:
- URL 中必须包含 fragment,例如
https://example.com/page.html#section2 - 页面中必须存在一个元素,其
id属性值**严格等于** fragment 的值(注意大小写、空格、特殊字符) - 该元素不能是
<a name="section2"></a>这种旧式锚点——:target只认id,不认name
示例有效写法:
立即学习“前端免费学习笔记(深入)”;
<a href="https://www.php.cn/link/0785d90297c165f28daa21244e98a139">常见问题</a> <h2 id="faq">常见问题</h2>
如果写成 id="FAQ" 或 id="faq?",:target 就不会匹配。
常见搭配技巧:配合 scroll-margin-top 避免标题被吸顶遮挡
现代单页应用常带固定头部,直接跳转后 id 元素会被顶部导航栏盖住。仅靠 :target 无法滚动修正,但可以配合 CSS 滚动行为:
- 给目标元素加
scroll-margin-top: 80px(值等于 header 高度),浏览器原生滚动会自动留出偏移 - 不要用
margin-top或padding-top模拟,会导致布局位移、:target样式位置错乱 - 若需兼容老浏览器(如 IE),
:target本身就不支持,得回退到 JS 监听hashchange事件
推荐写法:
h2:target {
background-color: #f0f8ff;
padding: 8px;
}
h2 {
scroll-margin-top: 72px; /* 匹配 fixed header 高度 */
}为什么点了链接没反应?排查这四点
:target 失效往往不是语法错,而是环境或细节问题:
- 检查控制台有没有
Failed to execute 'scrollIntoView' on 'Element'类错误——说明目标元素被display: none或visibility: hidden隐藏了,:target仍会匹配,但视觉不可见 - Vue/React 等框架中,动态生成的元素若未正确设置
id(比如用了v-bind:id="`item-${i}`"却漏了渲染),:target找不到对应节点 - 使用
history.pushState()或router.push()改变 hash 时,若没触发真实 DOM 插入(如组件未挂载),:target无元素可匹配 - 服务器返回的 HTML 若含多个相同
id(违反 HTML 规范),浏览器只取第一个,:target可能匹配错位
最稳的验证方式:手动改地址栏 URL 加 #xxx,看对应 id="xxx" 元素是否立刻应用样式——这能排除 JS 干扰,直击 CSS 行为本身。


















