首页 > 解决方案 > '类别'更改的flexbox表中的粘性左侧单元格

问题描述

我有一个在 flexbox 表中展示的项目列表。我的实际显示有更多列,但在这个问题中,我将只使用 2 个 - “类别”和“项目”名称。数据按类别顺序显示。如果某个类别的项目重复,则只有该类别的第一个项目应该列出该类别,对于后续项目,我希望类别单元格为空。由于这可以滚动到屏幕顶部,我想让这个单元格变得粘稠,就像我对标题所做的那样。

但是,由于单元格是行的子项,而不是表格的容器,它会随行向上滚动。您可以在下面示例的第一个表中看到这一点,'.first_item' CSS 类没有将标题保留在适当的位置。

我得出的结论是,实现此目的的唯一方法是在行前插入一个 div 以呈现类别并使其具有粘性 - 在下面的示例中的第二个表中的类 cat_head。这可行,但是,它将第一个项目击倒并且没有对齐我想要的位置。因此,我将其高度设置为 0px,这会使项目行重新对齐,但随后必须将文本放在其中的绝对定位 div 中,以便我可以设置背景颜色以阻止类别的文本相互重叠。

它工作得非常好,这正是我希望它的操作方式 - 除了因为高度设置为 0px,绝对 div 延伸到表格底部下方,因为它从屏幕顶部滚动并覆盖了什么在它下面 - 您可以在示例中看到它覆盖了“下面的文本”。

我还必须在备用行上手动添加一个 'alt' 类名来获得背景颜色,而不是依赖于 ':nth-child(even)' - 但我可以忍受这一点。

有没有人有任何建议阻止它从容器底部掉出来,或者确实有更好的方法?谢谢。

.pad {
  height: 50px;
  background-color: yellow;
}

.fill {
  height: 120vh;
  background-color: yellow;
}

.container {
  background-color:#ffffff;
}

.row {
  display: flex;
  flex-flow:row wrap;
}

.head {
  position: sticky;
  top: 0px;
  background-color: #e0e0e0;
  font-weight: bold;
  border-bottom: 1px solid #000000;
  height: 24px;
  z-index: 3;
}

.cell {
 flex: 0 0 100px;
 padding: 5px;
}

.first_item {
  position: sticky;
  top: 25px;
  z-index: 2;
}

.table_1 .row:nth-child(even),
.table_2 .alt {
  background-color: #f0f0f0;
}

.cat_head {
  position: sticky;
  top: 25px;
  height:0px;
  overflow: visible;
  z-index: 2;
}

.cat_text {
  position: absolute;
  width: 80px;
  padding: 0;
  background-color: rgba(8,156,213,1);
  color: #ffffff;
  border: 1px solid #000000;
  border-radius:5px;
  margin:2px 0 0 4px;
  text-align:center;
}
  <div class="pad"></div>
  <div class="container table_1">
    <div class="row head">
      <div class="cell">Category</div>
      <div class="cell">Item</div>
    </div>
    <div class="row cat">
      <div class="cell first_item">Category 1</div>
      <div class="cell">Item 1-1</div>
    </div>
    <div class="row">
      <div class="cell"></div>
      <div class="cell">Item 1-2</div>
    </div>
    <div class="row">
      <div class="cell"></div>
      <div class="cell">Item 1-3</div>
    </div>
    <div class="row cat">
      <div class="cell first_item">Category 2</div>
      <div class="cell">Item 2-1</div>
    </div>
    <div class="row">
      <div class="cell"></div>
      <div class="cell">Item 2-2</div>
    </div>
  </div>

  <div class="pad">Text below</div>

  <div class="container table_2">
    <div class="row head">
      <div class="cell">Category</div>
      <div class="cell">Item</div>
    </div>
    <div class="cat_head">
      <div class="cat_text">Category 1</div>
    </div>
    <div class="row alt">
      <div class="cell"></div>
      <div class="cell">Item 1-1</div>
    </div>
    <div class="row">
      <div class="cell"></div>
      <div class="cell">Item 1-2</div>
    </div>
    <div class="row alt">
      <div class="cell"></div>
      <div class="cell">Item 1-3</div>
    </div>
    <div class="cat_head">
      <div class="cat_text">Category 2</div>
    </div>
    <div class="row">
      <div class="cell"></div>
      <div class="cell">Item 2-1</div>
    </div>
    <div class="row alt">
      <div class="cell"></div>
      <div class="cell">Item 2-2</div>
    </div>
  </div>
  <div class="fill">Text below</div>

标签: cssflexboxsticky

解决方案


好的。所以我睡在上面,意识到滚动离开视口顶部时的粘性定位是基于其 div 的底部。因此,我需要将 div 移到它所在的行下方 - 因为它的 0px 高,这就是它的“底部”应该在的位置。

我还需要将包含的绝对 div 移动到其上方而不是下方,以便其底部与其对齐。我最初在绝对 div 上放置了一个 -24px 的上边距,但由于某种原因,这停止了其父级的粘性定位。因此,我在粘性 div 上放置了 -24px 的上边距,这很有效。但是,它也向上拖动了下一行,所以我还添加了一个 24px 的底部边距来解决这个问题。

我还在每个类别的行周围添加了一个包含 div,这样当下一个类别到达顶部时,粘性标题会滚动到屏幕外。

一切正常。

.pad {
  height: 50px;
  background-color: yellow;
}

.fill {
  height: 120vh;
  background-color: yellow;
}

.container {
  background-color:#ffffff;
}

.row {
  display: flex;
  flex-flow:row wrap;
}

.head {
  position: sticky;
  top: 0px;
  background-color: #e0e0e0;
  font-weight: bold;
  border-bottom: 1px solid #000000;
  height: 24px;
  z-index: 3;
}

.cell {
 flex: 0 0 100px;
 padding: 5px;
}

.alt {
  background-color: #f0f0f0;
}

.cat_head {
  position: sticky;
  top: 27px;
  height:0px;
  margin: -24px 0 24px 4px;
  overflow: visible;
  z-index: 2;
}

.cat_text {
  position: absolute;
  width: 80px;
  padding: 0;
  background-color: rgba(8,156,213,1);
  color: #ffffff;
  border: 1px solid #000000;
  border-radius:5px;
  text-align:center;
}
  <div class="pad"></div>

  <div class="container">
    <div class="row head">
      <div class="cell">Category</div>
      <div class="cell">Item</div>
    </div>
    <div>
      <div class="row alt">
        <div class="cell"></div>
        <div class="cell">Item 1-1</div>
      </div>
      <div class="cat_head">
        <div class="cat_text">Category 1</div>
      </div>
      <div class="row">
        <div class="cell"></div>
        <div class="cell">Item 1-2</div>
      </div>
      <div class="row alt">
        <div class="cell"></div>
        <div class="cell">Item 1-3</div>
      </div>
    </div>
    <div>
      <div class="row">
        <div class="cell"></div>
        <div class="cell">Item 2-1</div>
      </div>
      <div class="cat_head">
        <div class="cat_text">Category 2</div>
      </div>
      <div class="row alt">
        <div class="cell"></div>
        <div class="cell">Item 2-2</div>
      </div>
    </div>
  </div>
  <div class="fill">Text below</div>


推荐阅读