粘性Header滚动收缩优化:纯CSS替代calc()方案问询
纯CSS动态高度Sticky Header收缩优化方案
核心思路
放弃给父header设置固定top值,转而让两个固定高度子元素独立使用position: sticky,通过CSS变量+滚动驱动动画动态控制间距与定位偏移,替代冗长的calc()表达式,同时避免父元素随子元素移出视口。
实现代码
HTML结构
<header class="site-header"> <div class="header-bar header-top">固定高度顶部栏</div> <div class="header-image-wrap"> <img src="your-image-url" alt="自适应图片" class="header-image"> </div> <div class="header-bar header-nav">固定高度导航栏</div> </header>
CSS样式
/* 定义全局变量,统一管理固定值与间距 */ :root { --bar-height: 60px; /* 两个固定高度div的高度 */ --initial-gap: 20px; /* 初始元素间距 */ --current-gap: var(--initial-gap); } .site-header { width: 100%; /* 绑定滚动驱动动画,跟踪视口滚动进度 */ animation: shrink-header linear; animation-timeline: scroll(root); /* 动画触发范围:从顶部到图片+间距完全移出视口 */ animation-range: 0 calc(var(--initial-gap) + var(--image-height)); } /* 动态获取图片高度并赋值给变量 */ .header-image-wrap { width: 100%; --image-height: 100%; } .header-image { width: 100%; height: auto; display: block; } .header-bar { height: var(--bar-height); background: #2c3e50; color: #fff; display: flex; align-items: center; justify-content: center; position: sticky; z-index: 100; } .header-top { top: 0; margin-bottom: var(--current-gap); } .header-nav { /* 用变量简化定位计算,替代冗长calc */ top: calc(var(--bar-height) + var(--current-gap) + var(--image-height)); margin-top: var(--current-gap); } /* 滚动时触发的动画:将间距从初始值变为0 */ @keyframes shrink-header { to { --current-gap: 0; } } /* 兼容不支持滚动驱动动画的浏览器(可选降级) */ @supports not (animation-timeline: scroll(root)) { .header-nav { top: calc(var(--bar-height) + var(--initial-gap)); } .header-top { margin-bottom: 0; } }
关键优化点
- 变量复用:用
--bar-height、--initial-gap等变量替代硬编码数值,让calc()表达式更简洁易维护 - 滚动驱动动画:无需JavaScript,纯CSS跟踪滚动进度,动态调整间距变量,实现平滑收缩效果
- 子元素独立粘性:父
header不设置position: sticky,避免其随子元素移出视口;仅给两个固定高度栏设置粘性,确保它们始终固定在视口内 - 动态图片高度适配:通过图片容器的
--image-height变量自动获取自适应高度,无需手动计算
内容的提问来源于stack exchange,提问作者Shadow of eagle
相关产品推荐
相关产品推荐

