
用 vh 做垂直方向渐变,关键在背景尺寸和起点终点对齐
直接说结论:仅靠 background: linear-gradient(...) + 100vh 不会自动“随屏幕高度拉伸渐变”,因为渐变默认按容器尺寸平铺,不是按视口单位缩放。你看到的“渐变变短/变长”,其实是背景重复或裁剪导致的错觉。
真正可控的做法是把渐变当背景图,用 background-size 和 background-position 锁定它与视口的对应关系:
-
background: linear-gradient(to bottom, #f0f, #0ff)—— 方向必须明确写to bottom,别省略 -
background-size: 100% 100vh—— 这步最关键:让渐变图的高度严格等于视口高度 -
background-attachment: fixed(可选)—— 防止滚动时渐变跟着内容动,造成断裂感 - 容器本身得撑满视口:
min-height: 100vh,否则100vh在子元素上没意义
为什么 height: 100vh + linear-gradient 经常失效
常见错误是这样写:
div {<br> height: 100vh;<br> background: linear-gradient(#f0f, #0ff);<br>}
问题出在:CSS 渐变默认作为「背景图像」渲染,其尺寸由 background-size 决定,默认是 auto,即按容器宽高等比缩放——但等比缩放后,渐变色带的物理长度并不等于 100vh,尤其在宽高比变化时,颜色过渡会压缩或拉稀。
立即学习“前端免费学习笔记(深入)”;
典型现象:
- 手机横屏时渐变突然“变快”,颜色块挤在一起
- 桌面端大屏下渐变带拉得太开,中间一大段单色
- 滚动页面时,渐变位置飘移,像没固定住
background-size: 100% 100vh 的兼容性和边界注意点
这个写法在现代浏览器(Chrome 26+、Firefox 16+、Safari 6.1+)都支持,但有两点容易被忽略:
-
100vh在 iOS Safari 中可能包含地址栏高度,导致实际可用高度小于预期(尤其是地址栏收起/展开时),建议加min-height: 100vh保底 - 如果父容器有
transform或perspective,某些旧版 Android WebView 会重置vh计算,此时应避免嵌套 transform -
background-size的第二个值设为100vh时,第一个值写100%比auto更稳——确保横向铺满,不因内容宽度变化而裁剪渐变
响应式微调:不同屏幕高度用不同渐变节奏
如果想让小屏(比如 600px 高)的渐变更紧凑、大屏(900px+)更舒展,不能只靠 vh,得结合媒体查询或 clamp():
- 用
clamp()动态控制渐变高度:background-size: 100% clamp(40vh, 60vh, 80vh),小屏用 40vh,大屏上限 80vh - 避免用
em或rem控制渐变尺寸——它们依赖字体大小,和视口高度无关,容易脱节 - 若需精确到像素级过渡(比如设计稿要求 200px 内完成从红到蓝),就别用
vh,改用固定px值 +background-attachment: local配合容器滚动
最麻烦的其实是滚动锚点和渐变交界——一旦容器内有 overflow: scroll,background-attachment: fixed 就会失效,这时只能用伪元素 + position: sticky 模拟,那是另一层复杂度了。










