正确做法是html { scroll-behavior: smooth; },因锚点跳转滚动容器是html;目标元素需加scroll-margin-top修正固定导航遮挡;js调用scrollintoview须显式传behavior: 'smooth'。

直接加 class="scroll-smooth" 没用——Tailwind 官方根本没提供这个类,浏览器也完全不识别它。真正起效的只有一条原生 CSS 规则:html { scroll-behavior: smooth; },且必须写在 html 元素上。
为什么 scroll-behavior: smooth 必须加在 html 上?
页面级锚点跳转(比如 a[href="#faq"])的滚动容器是 html,不是 body,也不是某个 div。加在 body 上,Chrome 可能勉强工作,但 Safari 会静默忽略;加在局部容器(如 div.overflow-y-auto)上,只影响该容器内 scrollIntoView() 的行为,和点击链接跳转无关。
- ✅ 正确做法:在 CSS 文件中用
@layer base声明:html { scroll-behavior: smooth; } - ❌ 错误写法:
body { scroll-behavior: smooth; }或.content { scroll-behavior: smooth; } - ⚠️ 如果页面用了
height: 100vh; overflow: hidden;,html实际不可滚动,这条规则直接失效
固定导航栏遮住目标元素怎么办?
滚动后 <h2 id="faq"></h2> 被顶部 position: fixed 导航栏盖住,不是 JS 算错了,是浏览器默认把目标元素顶部对齐视口顶部。修正方式是给目标元素自身加 scroll-margin-top,而不是给它的父容器。
- ✅ 正确写法:
<h2 id="faq" class="-scroll-mt-20"></h2>(值建议匹配导航栏高度) - ❌ 错误做法:把
-scroll-mt-20加在<section></section>上,而id="faq"在内部<h2></h2>—— 浏览器只认带id的那个元素 - 响应式可用
scroll-mt-[clamp(50px,8vh,80px)],但 Tailwind 默认不支持clamp(),需自定义或启用插件
动态渲染(React/Vue)下锚点跳转失效?
路由加载时带 #contact,但目标区块由 v-if 或 useState 控制,初始未挂载,:target 无法匹配,scroll-behavior 再准也没用。
- 必须等 DOM 渲染完成后再手动调用:
element.scrollIntoView({ behavior: 'smooth', block: 'start' }) - 即使全局设了
html { scroll-behavior: smooth; },JS 调用时仍需显式传{ behavior: 'smooth' },否则默认是'auto' - ID 必须合法:不能以数字开头(
id="1section"非法),不能含空格或特殊字符
最容易被忽略的是「滚动容器是否真正可滚动」——html 上的 scroll-behavior: smooth 不是开关,而是对一个已存在滚动行为的修饰。如果布局锁死了高度、内容没溢出、或目标 ID 在首次渲染时不存在,平滑效果就根本不会触发。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











