如何让position: sticky元素重叠而非挤压?(仿iOS16天气APP滚动效果)
仅用CSS实现iOS 16天气APP的重叠粘性标题效果
我想复刻iOS 16天气APP的滚动效果,核心是实现顶部可互相重叠的粘性标题。默认的position: sticky会在新标题滚动到顶部时把旧标题顶出去,但我需要的是新标题直接覆盖旧标题的效果,就像这样:

我之前用position: sticky实现类似效果,但它的表现是顶出前一个标题,而非重叠,示例代码如下:
原CSS代码
section { padding-bottom: 10px; } .content { height: 300px; width: 300px; background-color: lightblue; } .header { height: 40px; width: 300px; background-color: coral; position: sticky; top: 0; }
原HTML代码
<section> <div class="header"> Title 1 </div> <div class="content"></div> </section> <section> <div class="header"> Title 2 </div> <div class="content"></div> </section> <section> <div class="header"> Title 3 </div> <div class="content"></div> </section>
解决方案:负margin + z-index层级控制
完全可以仅用CSS实现这个效果,核心思路是通过负margin让section向上偏移,结合z-index控制标题的覆盖层级:
修改后的CSS代码
section { padding-bottom: 10px; margin-top: -40px; /* 等于header的高度,让section向上偏移实现重叠 */ padding-top: 40px; /* 补偿负margin,避免内容被标题遮挡 */ } .content { height: 300px; width: 300px; background-color: lightblue; } .header { height: 40px; width: 300px; background-color: coral; position: sticky; top: 0; } /* 给后续标题设置更高的z-index,确保新标题覆盖旧标题 */ section:nth-child(1) .header { z-index: 1; } section:nth-child(2) .header { z-index: 2; } section:nth-child(3) .header { z-index: 3; }
修改后的HTML代码(结构无需改动)
<section> <div class="header"> Title 1 </div> <div class="content"></div> </section> <section> <div class="header"> Title 2 </div> <div class="content"></div> </section> <section> <div class="header"> Title 3 </div> <div class="content"></div> </section>
效果原理
- 负margin-top:让每个section向上移动等于标题高度的距离,这样当滚动时,下一个标题会和上一个标题在顶部区域重叠,而不是把旧标题顶开
- 递增z-index:确保后面的标题层级高于前面的,所以新标题滚动到顶部时会直接覆盖在旧标题上方,完全匹配iOS天气APP的滚动效果
- padding-top:抵消负margin对内容区域的影响,避免内容被顶部的粘性标题遮挡
内容的提问来源于stack exchange,提问作者pgr3931
相关产品推荐
相关产品推荐

