I have been trying to think of a way to make a table with a fixed first column (and the rest of the table with a horizontal overflow) I saw a post which had a similar question. but the fixed column bit did not seem to be resolved. Help?
-
I'd like to expand this question a little: a friend of mine wants to make a table which wouldn't scale to more than 100% of the page, but would have more than two columns that together should be scrollable in case they need more horizontal space than there is. In effect, this should be similar to Frozen columns in MS Excel. Is that possible?Rimas Kudelis– Rimas Kudelis2010-09-04 11:09:00 +00:00Commented Sep 4, 2010 at 11:09
-
See my answer on similar question: stackoverflow.com/a/17557830/1763149Marcin Raczyński– Marcin Raczyński2013-07-09 20:49:17 +00:00Commented Jul 9, 2013 at 20:49
7 Answers
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
10 Comments
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>
2 Comments
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>
6 Comments
You can use below table style to have horizontal scrolling table with fixed first column.
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;
}
<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>
Comments
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
1 Comment
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
Comments
Take a look at this JQuery plugin:
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.