在日常网页开发中,Cookie 同意横幅已成为标配组件。通常使用 position: fixed; bottom: 0 将其固定在视口底部,但随之而来一个恼人问题:页面内容不足时,横幅会紧贴底部,遮挡页脚,用户无法看到;而当页面内容足够长,用户滚动至底部时,又需为页脚“腾出空间”——即动态添加底部外边距,例如 margin-bottom: 50px。
传统做法通常使用 JavaScript 监听 scroll 事件,编写判断逻辑:滚动到底部时增加边距,离开时移除。虽然可行,但性能开销与重绘抖动的风险始终存在。有没有更优雅、更声明式的解决方案?其实 CSS 滚动驱动动画(Scroll-Driven Animations)正是为此场景量身定制——它允许动画进度直接绑定到滚动位置,完全无需 JavaScript 干预。
下面直接上代码(需要 Chrome 115+ 或支持 animation-timeline 的浏览器):
#cookie-section {
min-height: 50px;
width: 100%;
position: fixed;
bottom: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(38, 38, 38, 0.9);
color: #fff;
padding: 0 20px;
/* 滚动驱动动画控制 margin-bottom */
animation: addMargin 1s forwards;
animation-timeline: scroll(root);
animation-range-start: 90%; /* 滚动至页面底部前10%时开始 */
animation-range-end: 100%; /* 完全抵达底部时完成 */
}
@keyframes addMargin {
from { margin-bottom: 0; }
to { margin-bottom: 50px; }
}
/* 演示用:保证页面有足够高度触发滚动 */
body {
min-height: 300vh;
margin: 0;
}
关键要点需单独说明:
animation-timeline: scroll(root)将动画时间轴绑定至整个文档的滚动进度(即document.scrollingElement);animation-range-start: 90%表示当滚动进度达到 90%(即还差最后 10% 高度)时动画才启动,避免过早出现边距;forwards保证动画结束后样式停留在to状态(即margin-bottom: 50px持续生效),不会回弹;- 另外,用
inset替代top/right/bottom/left是现代写法,比如inset: auto 0 0等价于top: auto; right: 0; bottom: 0; left: 0,语义更清晰。
⚠️ 需注意,滚动驱动动画目前仍为实验性特性,Firefox 和 Safari 尚未支持。生产环境建议配合 @supports 特性检测,或直接降级为 JavaScript 方案——例如监听 scroll 事件与 getBoundingClientRect() 判断触底:
const cookieBar = document.getElementById('cookie-section');
window.addEventListener('scroll', () => {
const isAtBottom = window.innerHeight + window.scrollY >= document.body.scrollHeight - 10;
cookieBar.style.marginBottom = isAtBottom ? '50px' : '0';
});
使用 CSS 滚动驱动动画实现底部留白,既响应式又高性能,用户体验显著提升。这也是现代 CSS 表达力的一个缩影——以声明式方式解决过去需要 JavaScript 反复计算的问题,值得投入精力掌握。
