具有水平滚动的 HTML 表(第一列固定)

我一直在想一种方法来创建一个有固定的第一列的表格(以及其他有水平溢出的表格) ,我看到一个帖子有一个类似的问题。但固定栏位似乎没有得到解决。帮忙?

230080 次浏览

I have a similar table styled like so:

<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>

Take a look at this JQuery plugin:

http://fixedheadertable.com

It adds vertical (fixed header row) or horizontal (fixed first column) scrolling to an existing HTML table. There is a demo you can check for both cases of scrolling.

Use jQuery DataTables plug-in, it supports fixed header and columns. This example adds fixed column support to the html table "example":

http://datatables.net/extensions/fixedcolumns/

For two fixed columns:

http://www.datatables.net/release-datatables/extensions/FixedColumns/examples/two_columns.html

How about:

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>

You can test it out in this jsbin: http://jsbin.com/uxecel/4/edit

Based on skube's approach, I found the minimal set of CSS I needed was:

.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>

You can use below table style to have horizontal scrolling table with fixed first column.

<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>

Here's an example with fixed first and last columns. Sticky works better than absolute positioning for expanding the rows when the cells have more content.

Note - this also works with rowspan table cells. The table holds its correct shape.

.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>

Example to play with: https://jsbin.com/qawidijigi/edit?html,css,output