位置固定的滚动仍在移动元素。

14

我有一个要求,需要显示类似于具有水平滚动功能的固定第一列的表格。

该列在一段时间内保持固定,但当您滚动太多时,它会开始随其他内容移动:

.wrapper {
  width: 250px;
  overflow: auto;
  display: flex;
  flex-direction: column;
  position: relative;
}

.header-container, .row-data {
  display: flex;
  position: relative;
}

.header, .data {
  flex: 0 0 80px;
  padding: 1rem;
  background-color: lightblue;
}

.fullname {
  position: sticky;
  left: 0;
  background-color: orange;
}
<div class="container">
  <div class="wrapper">

    <div class="header-container">
      <div class="header fullname">Full Name</div>
      <div class="header">Test 1</div>
      <div class="header">Test 2</div>
      <div class="header">Test 3</div>
      <div class="header">Test 4</div>
    </div>
    
    <div class="data-container">
      <div class="row-data">
        <div class="data fullname">Full Name</div>
        <div class="data">Test 1</div>
        <div class="data">Test 2</div>
        <div class="data">Test 3</div>
        <div class="data">Test 4</div>
      </div>

      <div class="row-data">
        <div class="data fullname">Full Name</div>
        <div class="data">Test 1</div>
        <div class="data">Test 2</div>
        <div class="data">Test 3</div>
        <div class="data">Test 4</div>
      </div>
    </div>
  </div>
</div>

如何在不使用带来自身问题的<table>标签的情况下将第一个“Full Name”列固定?

3个回答

10
问题似乎出在 row-data 上,它的宽度没有达到行的末端,这影响了粘性元素的行为。基本上,fullname 停止 "黏住" 是因为它的父元素宽度的原因。
根据文档:
“黏性定位元素是其计算位置值为黏性的元素。它被视为相对定位,直到其包含块穿过其流根 (或它滚动的容器)内的指定阈值(例如将 top 设置为除 auto 以外的值),此时它会被视为 '黏住' 直到满足其包含块的相反边缘。”
要了解更多,请参考:https://developer.mozilla.org/en-US/docs/Web/CSS/position
添加以下内容以更好地理解:
.row-data {
  border: 1px solid red;
}

问题在于header-containerdata-container从父元素wrapper继承了宽度为250px。
我的解决方案是添加一个固定宽度的新元素wrapper2,如下所示:

.wrapper {
  width: 250px;
  overflow: auto;
}
.wrapper2 {
  display: flex;
  flex-direction: column;
  position: relative;
  width: 600px;
}

.header-container, .row-data {
  display: flex;
  position: relative;
}

.header, .data {
  flex: 0 0 80px;
  padding: 1rem;
  background-color: lightblue;
}

.fullname {
  position: sticky;
  left: 0;
  background-color: orange;
}
.row-data {
  border:1px solid red;
}
.header-container {
  border:1px solid green;
}
<div class="container">
  <div class="wrapper">
  <div class="wrapper2">

    <div class="header-container">
      <div class="header fullname">Full Name 1a</div>
      <div class="header">Test 1a</div>
      <div class="header">Test 2a</div>
      <div class="header">Test 3a</div>
      <div class="header">Test 4a</div>
    </div>
    
    <div class="data-container">
      <div class="row-data">
        <div class="data fullname">Full Name 2b</div>
        <div class="data">Test 1b</div>
        <div class="data">Test 2b</div>
        <div class="data">Test 3b</div>
        <div class="data">Test 4b</div>
      </div>

      <div class="row-data">
        <div class="data fullname">Full Name 3c</div>
        <div class="data">Test 1c</div>
        <div class="data">Test 2c</div>
        <div class="data">Test 3c</div>
        <div class="data">Test 4c</div>
      </div>
    </div>
    </div>
  </div>
</div>

您可以在这里查看它的实际效果https://jsfiddle.net/noke7jc5/18/


3

根据August所说,我认为position: sticky不是解决您问题的最佳方案。

我使用绝对定位进行了类似的方法。使用伪元素和数据属性将标题放在行之前。

.wrapper {
  width: 250px;
  padding-left: 120px;
  position: relative;
  background-color: orange;
}

.inner {
  display: flex;
  flex-direction: column;
  overflow: auto;
}

.header-container,
.row-data {
  display: flex;
}

.header, .data {
  flex: 0 0 80px;
  padding: 1rem;
  background-color: lightblue;
}

.header-container::before,
.row-data::before{
  content: attr(data-title);
  left: 0px;
  padding: 1rem;
  position: absolute;
}
<div class="container">
  <div class="wrapper">
    <div class="inner">
      <div class="header-container" data-title="Fullname">
        <div class="header">Test 1</div>
        <div class="header">Test 2</div>
        <div class="header">Test 3</div>
        <div class="header">Test 4</div>
      </div>
    
      <div class="data-container">
        <div class="row-data" data-title="Fullname">
          <div class="data">Test 1</div>
          <div class="data">Test 2</div>
          <div class="data">Test 3</div>
          <div class="data">Test 4</div>
        </div>
        <div class="row-data" data-title="Fullname">
          <div class="data">Test 1</div>
          <div class="data">Test 2</div>
          <div class="data">Test 3</div>
          <div class="data">Test 4</div>
        </div>
      </div>
    </div>
  </div>
</div>


1
我喜欢这个解决方案,但不幸的是可能无法使用它,因为行也有一个编辑模式,显示每个单元格中的下拉列表。但这是一个好的解决方案,我会记在心里。我已经找到了我下面发布的问题的解决方案。 - LanFeusT

1

弄清了问题...使用sticky时,需要为容器指定宽度。

在我的情况下,一旦我通过将所有列的宽度相加来为.row-data和.header-container指定宽度,它就可以正常工作。


1
这与我在答案中发布的类似。 - August

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接