:target 仅标记状态,实现点击跳转+平滑滚动+焦点高亮需三者协同:html{scroll-behavior:smooth}、:target、@keyframes缺一不可;scroll-behavior必须设在html上,旧版Safari需html,body同设;:target只匹配合法id,不支持class或动态延迟渲染;动画须用transform+opacity+@keyframes,避免重排;SPA中需手动触发location.hash重置以激活:target。

:target 本身不滚动,也不平滑,它只是个状态标记;要实现「点击跳转 + 平滑滚动 + 焦点高亮」三者协同,必须组合 html { scroll-behavior: smooth; }、:target 和 @keyframes,缺一不可。
为什么点了锚点链接却没平滑滚动?
根本原因不是 JS 没写对,而是 CSS 缺了关键声明:scroll-behavior: smooth 必须作用在 html 元素上(设在 body 无效)。旧版 Safari 还要求同时加 html, body { scroll-behavior: smooth; } 才稳定。
-
scroll-behavior: smooth是浏览器原生滚动动画开关,不是 JS 补丁 - 如果页面已有自定义
scrollIntoView({ behavior: 'smooth' }),需统一收口,否则和 CSS 行为冲突 - 移动端部分 iOS Safari(≤15.4)对
scroll-margin-top支持弱,可改用padding-top+margin-top: -Xpx模拟偏移
为什么 URL 带 #section2 但 :target 样式不生效?
最常见原因是目标元素的 id 不合法或不匹配。:target 只认标准 HTML id:大小写敏感、不能以数字开头、全局唯一、且必须是真实渲染的 DOM 节点。
-
<section id="2faq"></section>是非法 id,浏览器直接忽略,:target 不会匹配 <div class="faq"> 再怎么写 <code>a[href="#faq"]都没用——:target 不看class,只找id- React/Vue 动态渲染时,若
id="faq"的节点在初始 hash 加载后才挂载,:target 不会回溯触发;需确保 DOM 存在后再设 hash - 别对
height、margin、padding做动画——它们影响布局,易卡顿 - 推荐组合:
transform(缩放/位移)+opacity,硬件加速友好 - 动画时长控制在
0.3s–0.45s之间,超过 0.5s 用户会觉得响应滞后 - iOS Safari 在
overflow: hidden或启用-webkit-overflow-scrolling: touch的容器里,:target 动画容易被截断,需测试真机 - 跳转后手动触发一次 hash 设置:
location.hash = location.hash(或先清空再重设),强制激活 :target - 不要把 :target 当作核心交互状态(比如 Tab 激活态),它只是视觉增强;关键状态请用 JS 控制
is-active类 - 若需滚动定位,优先用
document.getElementById(hash.slice(1))?.scrollIntoView(),而不是依赖 :target 自带滚动
:target 高亮动画为什么卡顿或一闪而过?
:target 是瞬时状态切换,不支持 transition 直接作用于自身(没有中间帧),必须用 @keyframes。而且动画属性选错会触发重排,尤其在移动端更明显。
立即学习“前端免费学习笔记(深入)”;
SPA 中路由跳转后 :target 失效怎么办?
React Router v6、Vue Router 等库用 history.pushState 更新 URL,但浏览器不会因此触发 :target 计算——它只响应原生 anchor 点击或 location.hash = "xxx" 赋值。
真正容易被忽略的是::target 的行为完全由浏览器解析 fragment 的时机决定,它不感知框架生命周期,也不等待异步内容加载。动态 ID、服务端渲染遗漏、首屏未 hydrate 完成——这些都会让 :target “看起来失效”,其实只是它压根没机会匹配。


















