基于用户滚动的应用效果指的是页面元素随着用户的滚动操作,动态发生样式变化,比如位置移动、透明度改变、尺寸缩放等。这类效果以往大多需要通过JavaScript监听滚动事件来实现,但现在CSS已经提供了原生的能力支持,无需脚本就能完成很多常见的滚动交互需求。
核心实现原理
CSS实现滚动相关效果主要依赖两个核心特性,一个是position: sticky粘性定位,另一个是CSS滚动驱动动画。粘性定位可以让元素在滚动到指定阈值时切换定位方式,而滚动驱动动画则能直接将滚动位置映射为动画进度,实现样式的平滑过渡。
粘性定位的基础用法
粘性定位是position属性的一个取值,它会在元素滚动到设定的阈值前表现为相对定位,到达阈值后表现为固定定位,非常适合实现导航栏滚动后固定的效果。
/* 粘性导航栏样式 */
.sticky-nav {
position: sticky;
top: 0; /* 滚动到距离视口顶部0px时触发粘性定位 */
background-color: #fff;
padding: 16px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
transition: background-color 0.3s ease;
}
/* 页面滚动后改变导航栏背景色 */
body:has(.scroll-content:scroll(nearest)) .sticky-nav {
background-color: #f0f0f0;
}
滚动驱动动画实现元素淡入
CSS滚动驱动动画可以将元素的动画进度和页面的滚动位置绑定,当元素进入视口时自动触发动画,不需要额外的滚动监听逻辑。我们可以通过animation-timeline属性指定动画的时间轴为滚动进度。
/* 需要淡入的元素基础样式 */
.fade-in-element {
opacity: 0;
transform: translateY(20px);
animation: fadeInUp 0.6s ease forwards;
/* 指定动画时间轴为元素的滚动进度 */
animation-timeline: view();
/* 动画在元素进入视口10%时开始,完全进入时结束 */
animation-range: entry 10% entry 100%;
}
/* 定义淡入动画 */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
完整示例:滚动时导航栏变色+卡片依次淡入
下面是一个完整的页面示例,同时实现了导航栏滚动后背景变化,以及卡片元素进入视口时依次淡入的效果,所有逻辑都由CSS完成。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS滚动效果示例</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: sans-serif;
line-height: 1.6;
}
/* 粘性导航栏样式 */
.nav {
position: sticky;
top: 0;
background-color: transparent;
padding: 20px 40px;
display: flex;
gap: 20px;
transition: background-color 0.3s ease, box-shadow 0.3s ease;
z-index: 100;
}
/* 滚动后导航栏样式变化 */
body:has(.main:scroll(nearest)) .nav {
background-color: #ffffff;
box-shadow: 0 2px 10px rgba(0,0,0,0.08);
}
.nav a {
text-decoration: none;
color: #333;
font-weight: 500;
}
/* 头部区域样式 */
.header {
height: 300px;
background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 32px;
}
/* 主内容区域 */
.main {
max-width: 1200px;
margin: 40px auto;
padding: 0 20px;
}
/* 卡片容器 */
.card-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 24px;
margin-top: 40px;
}
/* 卡片基础样式 */
.card {
background-color: #fff;
border-radius: 8px;
padding: 24px;
box-shadow: 0 4px 12px rgba(0,0,0,0.05);
opacity: 0;
transform: translateY(30px);
animation: cardFadeIn 0.5s ease forwards;
animation-timeline: view();
animation-range: entry 0% entry 80%;
}
/* 为每个卡片设置不同的动画延迟,实现依次淡入 */
.card:nth-child(1) { animation-delay: 0s; }
.card:nth-child(2) { animation-delay: 0.1s; }
.card:nth-child(3) { animation-delay: 0.2s; }
.card:nth-child(4) { animation-delay: 0.3s; }
/* 卡片淡入动画 */
@keyframes cardFadeIn {
to {
opacity: 1;
transform: translateY(0);
}
}
/* 底部区域 */
.footer {
height: 200px;
background-color: #f5f5f5;
display: flex;
align-items: center;
justify-content: center;
margin-top: 60px;
color: #666;
}
</style>
</head>
<body>
<nav class="nav">
<a href="#">首页</a>
<a href="#">产品</a>
<a href="#">关于我们</a>
<a href="#">联系我们</a>
</nav>
<div class="header">
滚动查看CSS效果
</div>
<div class="main">
<h2>内容区域</h2>
<p>向下滚动页面,可以看到导航栏背景变化,同时卡片会依次淡入显示。</p>
<div class="card-container">
<div class="card">
<h3>卡片1</h3>
<p>这是第一个卡片的内容,滚动进入视口时会触发淡入动画。</p>
</div>
<div class="card">
<h3>卡片2</h3>
<p>这是第二个卡片的内容,滚动进入视口时会触发淡入动画。</p>
</div>
<div class="card">
<h3>卡片3</h3>
<p>这是第三个卡片的内容,滚动进入视口时会触发淡入动画。</p>
</div>
<div class="card">
<h3>卡片4</h3>
<p>这是第四个卡片的内容,滚动进入视口时会触发淡入动画。</p>
</div>
</div>
</div>
<div class="footer">
页面底部
</div>
</body>
</html>
注意事项
- CSS滚动驱动动画目前属于较新的特性,部分旧版本浏览器可能不支持,生产环境使用需要做好兼容性判断。
- 粘性定位的父元素不能设置
overflow: hidden或者overflow: auto属性,否则粘性效果会失效。 - 如果页面需要兼容不支持滚动驱动动画的浏览器,可以搭配少量的JavaScript作为降级方案,优先使用CSS实现以提升性能。
CSS滚动监听transformtransitionopacity修改时间:2026-06-22 16:16:16