纯CSS可滚动表格主体

3
我希望使用CSS仅滚动表格主体。我找到了一些例子,但如果表格行的长度不同,则它们效果不佳。
我从这个例子开始:

https://codepen.io/pdg/pen/MayBJK

HTML代码:

<div class="container">
  <h1>CSS only scrollable table body</h1>
  <p>by PDG</p>
<table class="table-scroll small-first-col">
  <thead>
    <tr>
    <th>Head 1</th>
    <th>Head 2</th>
    <th>Head 3</th>
    <th>Head 4</th>
    </tr>
  </thead>
  <tbody class="body-half-screen">
    <tr>
      <td>1</td>
      <td>First row</td>
      <td>3 dsad sad sad sad sad sadsadsad sadasd asdsa</td>
      <td>4 dasd sad asdsad sad sadsa dasdsad</td>
    </tr>
    <tr>
      <td>1 dasd asd sadsadsad sadsad</td>
      <td>2dsadsadsa dsad sadasd sad sad sa</td>
      <td>A very long cell content comes here, just to test it all!!!</td>
      <td>4</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2 dsad asd asd sad sad sad asdsadsad</td>
      <td>3</td>
      <td></td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>There is an empty cell above!</td>
    </tr><tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
    </tr><tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
    </tr>
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
    </tr><tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
    </tr><tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
    </tr><tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
    </tr><tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
    </tr><tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
    </tr><tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td>4</td>
    </tr><tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
      <td> Last row</td>
    </tr>
  </tbody>
</table>
  <h3>Notes</h3>
  <p>The table uses flex properties to arrange the cell sizes, however, this tends to make them the same as "fixed width". To fix that, you need to create additional classes that target the <strong>td:nth-child()</strong> and <strong>th:nth-child()</strong> with a specific <strong>flex-basis</strong> property.</p>
  <p>The <strong>height</strong> of the body also must be fixed and cannot be percentages (in the example above I use "vh")</p>
</div>

CSS代码:

.container{
  padding: 1rem;
  margin: 1rem;
}
.table-scroll{
  /*width:100%; */
  display: block;
  empty-cells: show;

  /* Decoration */
  border-spacing: 0;
  border: 1px solid;
}

.table-scroll thead{
  background-color: #f1f1f1;  
  position:relative;
  display: block;
  width:100%;
  overflow-y: scroll;
}

.table-scroll tbody{
  /* Position */
  display: block; position:relative;
  width:100%; overflow-y:scroll;
  /* Decoration */
  border-top: 1px solid rgba(0,0,0,0.2);
}

.table-scroll tr{
  width: 100%;
  display:flex;
}

.table-scroll td,.table-scroll th{
  flex-basis:100%;
  flex-grow:2;
  display: block;
  padding: 1rem;
  text-align:left;
}

/* Other options */

.table-scroll.small-first-col td:first-child,
.table-scroll.small-first-col th:first-child{
  flex-basis:20%;
  flex-grow:1;
}

.table-scroll tbody tr:nth-child(2n){
  background-color: rgba(130,130,170,0.1);
}

.body-half-screen{
  max-height: 50vh;
}

.small-col{flex-basis:10%;}

这似乎是一个好主意,在他们的演示中一切看起来都很好,但在更复杂的示例中,你可以看到列没有垂直对齐得很好。请参见下面的示例:

https://jsfiddle.net/pnfu321g/

我还尝试了另一个例子:http://jsfiddle.net/hashem/CrSpu/555/。但是在我的情况下,对于具有不同宽度的行的复杂表格,这也无法很好地工作。请建议一种只使用CSS(无JavaScript)的解决方案,使任何大小的行的表格看起来很好。
更新: 其他解决方案未能奏效的原因是我使用的是旧版Mozilla Firefox-57。这就是为什么我测试的几乎所有内容都无法正常工作的原因。我将问题标记为重复。

由于您更改了所有元素的显示类型,因此它实际上不再像表格一样运作。在普通表格中,列中的所有单元格具有相同的宽度,但是在这里,您明确地使得列中的单元格具有不同的宽度。这里的预期结果是什么?您希望单元格如何对齐? - Mathias-S
我期望得到以下结果:如果单元格宽度过长,文本将会被分成两三行并且单元格宽度将与其他单元格对齐。因此,表格行高将会增加,但单元格长度将保持相似。 - Pascut
2个回答

2
你可以在表头中的元素上使用position:sticky。
基本示例(CSS):
table.sticky-headers { width:100%; }
table.sticky-headers thead tr th { text-align:left; position:sticky; top:0; background:#fff; }

基本标记(添加更多行以获得滚动条):

原始答案翻译成“最初的回答”。

<table class="sticky-headers">
    <thead>
        <tr>
            <th>Head 1</th>
            <th>Head 2</th>
            <th>Head 3</th>
            <th>Head 4</th>
            <th>Head 5</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Content 1</td>
            <td>Content 2</td>
            <td>Content 3</td>
            <td>Content 4</td>
            <td>Content 5</td>
        </tr>
   </tbody>
</table>

这里有一个工作示例:http://jsfiddle.net/yp1xb7dj/

最初的回答

请将“sticky”位置添加到此示例中:https://jsfiddle.net/pnfu321g/。我尝试将其添加到“th”和“td”元素,但是“td”元素仍然无法垂直对齐。 - Pascut
3
你应该移除所有的display属性和与flex相关的属性,并为表格或单元格设置一个最大宽度。这样文字就会自动换行了。 - Mathias-S
我会尝试你的"max-width"建议。感谢您的建议。 - Pascut
那里有很多事情在进行,所有这些 flexbox 属性是什么意思?你需要表格正文拥有最大高度吗?我会将所有的 CSS 都删除,从我的示例作为起点重新开始设计。 - HaukurHaf
我尝试删除“display”属性并添加“max-width”属性。但是,如果我删除显示属性,“tbody”将不再可滚动。请参见此示例:https://jsfiddle.net/pnfu321g/1/ - Pascut
这个解决方案很好,我在一个旧版的Mozilla Firefox上测试过,但它表现不佳。但在最新的Chrome和Mozilla版本上,它运行得非常好!谢谢。 - Pascut

1
如果您想要固定单元格宽度,并使内容更多的单元格文字自动换行成两到三行,您可以尝试指定单元格宽度,高度将自动固定:
table.sticky-headers thead tr th {
    width: 20%;
    text-align:left; 
    position:sticky; 
    top:0; 
    background:#fff;
}

结果为:
enter image description here

1
这是我能做的最好的翻译,否则我不认为我理解你的意思。http://jsfiddle.net/q0x78yw4/1/ - liakoyras
1
请尝试访问此链接:http://jsfiddle.net/bq7d05m4/ - liakoyras
1
我在Mozilla Firefox上进行了测试,你的示例仅适用于Chrome。它运行良好,但我希望该解决方案也能在Mozilla和Safari上运行。 - Pascut
1
我刚在Mozilla上测试了一下,它运行良好。http://prntscr.com/ov156z - liakoyras
1
我正在使用较旧版本的Mozilla:57,它在最新版本上也能很好地工作。非常感谢,我已将您的答案选为最佳!感谢您的时间。 - Pascut
显示剩余9条评论

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