You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现可堆叠粘性标题?解决滚动溢出异常问题

问题描述

我想创建一个包含多个子板块的区域,每个子板块有标题和内容。滚动这个区域时,所有标题要固定在视口内——第一个标题固定在视口顶部,后续标题依次堆叠在之前的标题下方。

目前我给每个子板块设置position: sticky,并根据前面标题的高度设置top值来实现,但当整个区域滚出视口时,固定的标题不会跟着最后一个板块一起滚出,反而最后一个标题会覆盖在前面的标题上方并滚过去。

请问怎么实现才能让所有标题在末尾时一同滚出视口?

原实现代码

CSS

body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 0;
}

.section {
  border-bottom: 1px solid #ccc;
}

.section.placeholder {
  height: 30rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: rgb(131,58,180);
  background: linear-gradient(90deg, rgba(131,58,180,1) 0%, rgba(253,29,29,1) 50%, rgba(252,176,69,1) 100%);
}

.category-component {
  position: sticky;
  background: white;
}

.category-component:nth-child(1) {
  top: 0rem;
}

.category-component:nth-child(2) {
  top: 3rem;
}

.category-component:nth-child(3) {
  top: 6rem;
}

.category-title {
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 3rem;
  background-color: lightgrey;
  z-index: 1000;
  padding: 10px;
  font-weight: bold;
}

.category-content {
  padding: 20px;
  margin-top: 0;
  /* Reset margin */
}

HTML

<html>
<div class="section placeholder">
  Placeholder Section
</div>
<div class="section">
  <div class="category-component">
    <div class="category-title">Heading 1</div>
    <div class="category-content">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed imperdiet urna et hendrerit convallis. Nunc quis volutpat arcu. Nulla facilisi. Integer vestibulum sollicitudin justo, a vehicula purus tempus in. Mauris auctor libero id dui eleifend,
        ut fringilla velit elementum. Nam eu convallis velit. Quisque nec pharetra lectus. Duis condimentum tristique ligula id pellentesque. Mauris eu justo sed eros feugiat tempus.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed imperdiet
        urna et hendrerit convallis. Nunc quis volutpat arcu. Nulla facilisi. Integer vestibulum sollicitudin justo, a vehicula purus tempus in. Mauris auctor libero id dui eleifend, ut fringilla velit elementum. Nam eu convallis velit. Quisque nec pharetra
        lectus. Duis condimentum tristique ligula id pellentesque. Mauris eu justo sed eros feugiat tempus.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed imperdiet urna et hendrerit convallis. Nunc quis volutpat arcu. Nulla facilisi. Integer
        vestibulum sollicitudin justo, a vehicula purus tempus in. Mauris auctor libero id dui eleifend, ut fringilla velit elementum. Nam eu convallis velit. Quisque nec pharetra lectus. Duis condimentum tristique ligula id pellentesque. Mauris eu justo
        sed eros feugiat tempus.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed imperdiet urna et hendrerit convallis. Nunc quis volutpat arcu. Nulla facilisi. Integer vestibulum sollicitudin justo, a vehicula purus tempus in. Mauris auctor
        libero id dui eleifend, ut fringilla velit elementum. Nam eu convallis velit. Quisque nec pharetra lectus. Duis condimentum tristique ligula id pellentesque. Mauris eu justo sed eros feugiat tempus.</p>
    </div>
  </div>

  <div class="category-component">
    <div class="category-title">Heading 2</div>
    <div class="category-content">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed imperdiet urna et hendrerit convallis. Nunc quis volutpat arcu. Nulla facilisi. Integer vestibulum sollicitudin justo, a vehicula purus tempus in. Mauris auctor libero id dui eleifend,
        ut fringilla velit elementum. Nam eu convallis velit. Quisque nec pharetra lectus. Duis condimentum tristique ligula id pellentesque. Mauris eu justo sed eros feugiat tempus.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed imperdiet
        urna et hendrerit convallis. Nunc quis volutpat arcu. Nulla facilisi. Integer vestibulum sollicitudin justo, a vehicula purus tempus in. Mauris auctor libero id dui eleifend, ut fringilla velit elementum. Nam eu convallis velit. Quisque nec pharetra
        lectus. Duis condimentum tristique ligula id pellentesque. Mauris eu justo sed eros feugiat tempus.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed imperdiet urna et hendrerit convallis. Nunc quis volutpat arcu. Nulla facilisi. Integer
        vestibulum sollicitudin justo, a vehicula purus tempus in. Mauris auctor libero id dui eleifend, ut fringilla velit elementum. Nam eu convallis velit. Quisque nec pharetra lectus. Duis condimentum tristique ligula id pellentesque. Mauris eu justo
        sed eros feugiat tempus.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed imperdiet urna et hendrerit convallis. Nunc quis volutpat arcu. Nulla facilisi. Integer vestibulum sollicitudin justo, a vehicula purus tempus in. Mauris auctor
        libero id dui eleifend, ut fringilla velit elementum. Nam eu convallis velit. Quisque nec pharetra lectus. Duis condimentum tristique ligula id pellentesque. Mauris eu justo sed eros feugiat tempus.</p>
    </div>
  </div>

  <div class="category-component">
    <div class="category-title">Heading 3</div>
    <div class="category-content">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed imperdiet urna et hendrerit convallis. Nunc quis volutpat arcu. Nulla facilisi. Integer vestibulum sollicitudin justo, a vehicula purus tempus in. Mauris auctor libero id dui eleifend,
        ut fringilla velit elementum. Nam eu convallis velit. Quisque nec pharetra lectus. Duis condimentum tristique ligula id pellentesque. Mauris eu justo sed eros feugiat tempus.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed imperdiet
        urna et hendrerit convallis. Nunc quis volutpat arcu. Nulla facilisi. Integer vestibulum sollicitudin justo, a vehicula purus tempus in. Mauris auctor libero id dui eleifend, ut fringilla velit elementum. Nam eu convallis velit. Quisque nec pharetra
        lectus. Duis condimentum tristique ligula id pellentesque. Mauris eu justo sed eros feugiat tempus.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed imperdiet urna et hendrerit convallis. Nunc quis volutpat arcu. Nulla facilisi. Integer
        vestibulum sollicitudin justo, a vehicula purus tempus in. Mauris auctor libero id dui eleifend, ut fringilla velit elementum. Nam eu convallis velit. Quisque nec pharetra lectus. Duis condimentum tristique ligula id pellentesque. Mauris eu justo
        sed eros feugiat tempus.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed imperdiet urna et hendrerit convallis. Nunc quis volutpat arcu. Nulla facilisi. Integer vestibulum sollicitudin justo, a vehicula purus tempus in. Mauris auctor
        libero id dui eleifend, ut fringilla velit elementum. Nam eu convallis velit. Quisque nec pharetra lectus. Duis condimentum tristique ligula id pellentesque. Mauris eu justo sed eros feugiat tempus.</p>
    </div>
  </div>
</div>

<div class="section placeholder">
  Placeholder Section
</div>

</html>

解决方案

问题核心是每个category-component作为独立的sticky元素,仅以自身位置为参考,不会同步父容器的底部边界。要让所有标题一起滚出,需将它们的sticky行为绑定到同一个父容器的底部。

修改后的CSS代码

body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 0;
}

.section {
  border-bottom: 1px solid #ccc;
  /* 设置相对定位,作为sticky元素的参考容器 */
  position: relative;
  /* 底部内边距等于所有标题总高度,确保标题能同步滚出 */
  padding-bottom: 9rem;
}

.section.placeholder {
  height: 30rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: rgb(131,58,180);
  background: linear-gradient(90deg, rgba(131,58,180,1) 0%, rgba(253,29,29,1) 50%, rgba(252,176,69,1) 100%);
}

.category-component {
  position: sticky;
  background: white;
  /* 设置bottom值,让元素到达父容器底部边界时停止sticky */
  bottom: 9rem;
}

.category-component:nth-child(1) {
  top: 0rem;
}

.category-component:nth-child(2) {
  top: 3rem;
}

.category-component:nth-child(3) {
  top: 6rem;
}

.category-title {
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 3rem;
  background-color: lightgrey;
  z-index: 1000;
  padding: 10px;
  font-weight: bold;
}

.category-content {
  padding: 20px;
  margin-top: 0;
}

原理说明

  1. 父容器.section添加position: relative,让所有sticky元素以它为边界参考;
  2. padding-bottom: 9rem(3个标题各3rem的总高度)为父容器底部预留空间,确保所有标题能同时到达底部;
  3. 每个category-component设置bottom: 9rem,当滚动到距离父容器底部9rem的位置时,元素不再保持sticky,会跟随父容器一起滚出视口。

这样就能实现滚动时标题堆叠固定,整个区域滚出时所有标题同步离开视口的效果。

内容的提问来源于stack exchange,提问作者JuicyDisorder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 08:57:01