带有水平滚动条的HTML表格(第一列固定)

80

我一直在思考如何制作一个带有固定第一列的表格(并且表格的剩余部分具有水平溢出)。我看到了一个类似的问题的帖子,但是固定列位好像没有得到解决。请帮忙?


我想稍微扩展一下这个问题:我的一个朋友想制作一张表格,它不会超过页面的100%,但是有两列以上,如果需要更多的水平空间,则应该可以滚动。实际上,这应该类似于MS Excel中的冻结列。这可能吗? - Rimas Kudelis
请参考我在类似问题上的回答:https://dev59.com/vHM_5IYBdhLWcg3wmkQK#17557830 - Marcin Raczyński
7个回答

125
如何:

table {
  table-layout: fixed; 
  width: 100%;
  *margin-left: -100px; /*ie7*/
}
td, th {
  vertical-align: top;
  border-top: 1px solid #ccc;
  padding: 10px;
  width: 100px;
}
.fix {
  position: absolute;
  *position: relative; /*ie7*/
  margin-left: -100px;
  width: 100px;
}
.outer {
  position: relative;
}
.inner {
  overflow-x: scroll;
  overflow-y: visible;
  width: 400px; 
  margin-left: 100px;
}
<div class="outer">
  <div class="inner">
    <table>
      <tr>
        <th class=fix></th>
        <th>Col 1</th>
        <th>Col 2</th>
        <th>Col 3</th>
        <th>Col 4</th>
        <th class="fix">Col 5</th>
      </tr>
      <tr>
        <th class=fix>Header A</th>
        <td>col 1 - A</td>
        <td>col 2 - A (WITH LONGER CONTENT)</td>
        <td>col 3 - A</td>
        <td>col 4 - A</td>
        <td class=fix>col 5 - A</td>
      </tr>
      <tr>
        <th class=fix>Header B</th>
        <td>col 1 - B</td>
        <td>col 2 - B</td>
        <td>col 3 - B</td>
        <td>col 4 - B</td>
        <td class=fix>col 5 - B</td>
      </tr>
      <tr>
        <th class=fix>Header C</th>
        <td>col 1 - C</td>
        <td>col 2 - C</td>
        <td>col 3 - C</td>
        <td>col 4 - C</td>
        <td class=fix>col 5 - C</td>
      </tr>
    </table>
  </div>
</div>

您可以在这个 jsbin 上进行测试:http://jsbin.com/uxecel/4/edit


这基本上对我有用,但我想从滚动div的最右侧列开始。我的列标题是日期,最近的日期在最右边,我希望在首次显示<table>时可见。有没有办法以编程方式实现这一点?是否有办法以编程方式将水平滚动条向左或向右移动?我想在表格顶部始终提供“向左滚动”和“向右滚动”按钮,因为浏览器支持的滚动条位于底部,不总是立即可见。 - Kras
当我设置表格宽度>所有数据列宽度时,我发现标题列和数据列之间有很大的间隙,请问有人知道为什么以及如何解决吗?请参见此处:http://jsbin.com/sesurutojo/edit?output - Justin
2
这似乎只在不需要垂直滚动时有效。对于我的情况,有许多行,因此垂直滚动只会滚动行数据,而不是使用绝对位置固定的行标题。 - Bruce
如果有分页呢? - Jigar7521
@w00t 我在使用 rowspan,但一旦我使用了这段代码,我的 rowspan 就不再起作用了。你知道是否内部或外部类会影响 rowspan 吗? - lisa_rao007
显示剩余5条评论

21

我有一张类似如下样式的表格:

<table style="width:100%; table-layout:fixed">
    <tr>
        <td style="width: 150px">Hello, World!</td>
        <td>
            <div>
                <pre style="margin:0; overflow:scroll">My preformatted content</pre>
            </div>
        </td>
    </tr>
</table>

3
这个答案会受益于一个演示。 - M H
JSFIDDLE演示,以便更清楚地了解这里发生了什么。 - Erenor Paz
21
那仅滚动单个单元格... - w00t
5
我不知道为什么这个答案被接受了。问题是:“还有表格的其余部分”,在我看来这包括超过一列... - Jean-Pierre Bécotte
列应该与标题同步,例如如果列滚动,则标题也应该随着列滚动。但我认为在实施此解决方案后它们两者不会同步。 - Kunal Tyagi
这是最好的选择。 - undefined

21

基于 skube 的方法,我发现我需要的最小 CSS 集合是:

.horizontal-scroll-except-first-column {
  width: 100%;
  overflow: auto;
}

.horizontal-scroll-except-first-column > table {
  margin-left: 8em;
}

.horizontal-scroll-except-first-column > table > * > tr > th:first-child,
.horizontal-scroll-except-first-column > table > * > tr > td:first-child {
  position: absolute;
  width: 8em;
  margin-left: -8em;
  background: #ccc;
}

.horizontal-scroll-except-first-column > table > * > tr > th,
.horizontal-scroll-except-first-column > table > * > tr > td {
  /* Without this, if a cell wraps onto two lines, the first column
   * will look bad, and may need padding. */
  white-space: nowrap;
}
<div class="horizontal-scroll-except-first-column">
  <table>
    <tbody>
      <tr>
        <td>FIXED</td> <td>22222</td> <td>33333</td> <td>44444</td> <td>55555</td> <td>66666</td> <td>77777</td> <td>88888</td> <td>99999</td> <td>AAAAA</td> <td>BBBBB</td> <td>CCCCC</td> <td>DDDDD</td> <td>EEEEE</td> <td>FFFFF</td>
      </tr>
    </tbody>
  </table>
</div>


伟大且易懂,不错。 - Ced

8
你可以使用下面的表格样式,将第一列固定并实现横向滚动表格。
<style type="text/css">
    table, th, td {
        border: 1px solid black;
    }    
    .table-style {
        overflow-x: auto;
    }
    .table-style tr th:first-child {
        position: sticky;
        left: 0;
        z-index: 2;
        background-color: white;
    }
</style>

<div class="table-style">
<table>
    <thead>
        <tr>
            <th>_col1_row1_</th>
            <th>_col2_row1_</th>
            <th>_col3_row1_</th>
            <th>_col4_row1_</th>
            <th>_col5_row1_</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th>_col1_row2_</th>
            <td>_col2_row2_</td>
            <td>_col3_row2_</td>
            <td>_col4_row2_</td>
            <td>_col5_row2_</td>
        </tr>
        <tr>
            <th>_col1_row3_</th>
            <td>_col2_row3_</td>
            <td>_col3_row3_</td>
            <td>_col4_row3_</td>
            <td>_col5_row3_</td>
        </tr>
        <tr>
            <th>_col1_row4_</th>
            <td>_col2_row4_</td>
            <td>_col3_row4_</td>
            <td>_col4_row4_</td>
            <td>_col5_row4_</td>
        </tr>
        <tr>
            <th>_col1_row5_</th>
            <td>_col2_row5_</td>
            <td>_col3_row5_</td>
            <td>_col4_row5_</td>
            <td>_col5_row5_</td>
        </tr>
    </tbody>
</table>

8

通过使用leftColumns初始化参数来修复左侧列。此链接有效http://www.datatables.net/extensions/fixedcolumns/(今天) - jpkeisala

4
这是一个固定第一列和最后一列的示例。当单元格内容更多时,粘性效果比绝对定位更好地扩展行。
注意 - 这也适用于跨行表格单元格。表格保持其正确的形状。

.wrapper {
  overflow-x:scroll;
  width:100%; 
}
table {
  table-layout: fixed; 
  width: 100%;
  border-collapse: collapse;
  background: white;
}
tr {
  border-top: 1px solid #ccc;
}
td, th {
  vertical-align: top;
  text-align: left;
  width:150px;
  padding: 5px;
}
.fix {
  position:sticky;
  background: white;
}
.fix:first-child {
  left:0;
  width:180px;
}
.fix:last-child {
  right:0;
  width:120px;
}
  <div class="wrapper">
    <table>
      <thead>
        <th class='fix'>Fixed</th>
        <th>Col 1</th>
        <th>Col 2</th>
        <th>Col 3</th>
        <th>Col 4</th>
        <th>Col 5</th>
        <th class='fix'>Fixed</th>
      </thead>
      <tbody>
        <tr>
          <td class='fix'>First Content</td>
          <td>A1</td>
          <td>A2 (with longer content)</td>
          <td>A3</td>
          <td>A4</td>
          <td>A5</td>
          <td class='fix'>Last Content</td>
        </tr>
        <tr>
          <td class='fix'>First Content (with longer content)</td>
          <td>B1</td>
          <td>B2</td>
          <td>B3</td>
          <td>B4</td>
          <td>B5</td>
          <td class='fix'>Last Content</td>
        </tr>
        <tr>
          <td class='fix'>First Content</td>
          <td>C1</td>
          <td>C2</td>
          <td>C3</td>
          <td>C4</td>
          <td>C5</td>
          <td class='fix'>Last Content (with longer content)</td>
        </tr>
      </tbody>
    </table>
  </div>

可供练习的示例:https://jsbin.com/qawidijigi/edit?html,css,output


3

看看这个 JQuery 插件:

http://fixedheadertable.com

它可以为现有的 HTML 表格添加垂直(固定表头行)或水平(固定第一列)滚动。您可以查看演示来了解滚动的两种情况。


6
注意:此代码依赖于已过时的JQuery功能,并且自约1年以来未进行更新。 - Hayk Saakian
@HaykSaakian 看起来那个项目现在又在更新了?显示是今年,需要 jQuery 1.7 版本。 - Metropolis

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