Make First Column Fixed and Next Column Scrollable in HTML Table

How do I create an HTML table with a fixed/frozen left column and a scrollable body?

If you want a table where only the columns scroll horizontally, you can position: absolute the first column (and specify its width explicitly), and then wrap the entire table in an overflow-x: scroll block. Don't bother trying this in IE7, however...

Relevant HTML & CSS:

table {
border-collapse: separate;
border-spacing: 0;
border-top: 1px solid grey;
}

td,
th {
margin: 0;
border: 1px solid grey;
white-space: nowrap;
border-top-width: 0px;
}

div {
width: 500px;
overflow-x: scroll;
margin-left: 5em;
overflow-y: visible;
padding: 0;
}

.headcol {
position: absolute;
width: 5em;
left: 0;
top: auto;
border-top-width: 1px;
/*only relevant for first row*/
margin-top: -1px;
/*compensate for top border*/
}

.headcol:before {
content: 'Row ';
}

.long {
background: yellow;
letter-spacing: 1em;
}
<div>
<table>
<tr>
<th class="headcol">1</th>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
</tr>
<tr>
<th class="headcol">2</th>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
</tr>
<tr>
<th class="headcol">3</th>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
</tr>
<tr>
<th class="headcol">4</th>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
</tr>
<tr>
<th class="headcol">5</th>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
</tr>
<tr>
<th class="headcol">6</th>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
</tr>
</table>
</div>

Make first column fixed and next column scrollable in html Table

You could use CSS overflow:auto;, as in http://jsfiddle.net/Yw679/2/

If I understand correctly, you want the entire left column to be static, and the entire right column (including the header) to be horizontally scrollable. Is that correct?

If so, it's not possible with one table. But with a bit of extra code, it's possible with two tables like this: http://jsfiddle.net/Yw679/6/

Making html table scrollable with first row and column fixed

You can do something like this(View in full screen for good visualization):

$(document).ready(function() {  $('tbody').scroll(function(e) { //detect a scroll event on the tbody       $('thead').css("left", -$("tbody").scrollLeft()); //fix the thead relative to the body scrolling    $('thead th:nth-child(1)').css("left", $("tbody").scrollLeft()); //fix the first cell of the header    $('tbody td:nth-child(1)').css("left", $("tbody").scrollLeft()); //fix the first column of tdbody  });});
table {  position: relative;  width: 900px;  background-color: #aaa;  overflow: hidden;  border-collapse: collapse;}

/*thead*/
thead { position: relative; display: block; width: 900px; overflow: visible;}
thead th { background-color: #99a; min-width: 120px; height: 32px; border: 1px solid #222;}
thead th:nth-child(1) { /*first cell in the header*/ position: relative; display: block; /*seperates the first cell in the header from the header*/ background-color: #88b;}

/*tbody*/
tbody { position: relative; display: block; width: 900px; height: 239px; overflow: scroll;}
tbody td { background-color: #bbc; min-width: 120px; border: 1px solid #222;}
tbody tr td:nth-child(1) { position: relative; display: block; height: 40px; background-color: #99a;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<head> <title>sample</title> <meta charset="utf-8" http-equiv="refresh" content="300"> <link href="https://fonts.googleapis.com/css?family=Lato&display=block" rel="stylesheet"> <link rel="stylesheet" type="text/css" href="css/style.css"></head>
<body> <div class="container"> <table class="checkBox"> <thead> <tr>
<th>Name</th> <th>user1</th> <th>user2</th> <th>user3</th> <th>user4</th> <th>user5</th> <th>user6</th> <th>user7</th> <th>user8</th> <th>user9</th> <th>user10</th> <th>user11</th> <th>user12</th> <th>user13</th> </tr> </thead> <tbody> <tr id='row1'> <td>row1</td> <td id='user1'></td> <td id='user2'></td> <td id='user3'></td> <td id='user4'></td> <td id='user5'></td> <td id='user6'></td> <td id='user7'></td> <td id='user8'></td> <td id='user9'></td> <td id='user10'></td> <td id='user11'></td> <td id='user12'></td> <td id='user13'></td> </tr> <tr id='row2'> <td>row2</td> <td id='user1'></td> <td id='user2'></td> <td id='user3'></td> <td id='user4'></td> <td id='user5'></td> <td id='user6'></td> <td id='user7'></td> <td id='user8'></td> <td id='user9'></td> <td id='user10'></td> <td id='user11'></td> <td id='user12'></td> <td id='user13'></td> </tr> <tr id='row3'> <td>row3</td> <td id='user1'></td> <td id='user2'></td> <td id='user3'></td> <td id='user4'></td> <td id='user5'></td> <td id='user6'></td> <td id='user7'></td> <td id='user8'></td> <td id='user9'></td> <td id='user10'></td> <td id='user11'></td> <td id='user12'></td> <td id='user13'></td> </tr> <tr id='row4'> <td>row4</td> <td id='user1'></td> <td id='user2'></td> <td id='user3'></td> <td id='user4'></td> <td id='user5'></td> <td id='user6'></td> <td id='user7'></td> <td id='user8'></td> <td id='user9'></td> <td id='user10'></td> <td id='user11'></td> <td id='user12'></td> <td id='user13'></td> </tr> <tr id='row5'> <td>row5</td> <td id='user1'></td> <td id='user2'></td> <td id='user3'></td> <td id='user4'></td> <td id='user5'></td> <td id='user6'></td> <td id='user7'></td> <td id='user8'></td> <td id='user9'></td> <td id='user10'></td> <td id='user11'></td> <td id='user12'></td> <td id='user13'></td> </tr> <tr id='row6'> <td>row6</td> <td id='user1'></td> <td id='user2'></td> <td id='user3'></td> <td id='user4'></td> <td id='user5'></td> <td id='user6'></td> <td id='user7'></td> <td id='user8'></td> <td id='user9'></td> <td id='user10'></td> <td id='user11'></td> <td id='user12'></td> <td id='user13'></td> </tr> <tr id='row7'> <td>row7</td> <td id='user1'></td> <td id='user2'></td> <td id='user3'></td> <td id='user4'></td> <td id='user5'></td> <td id='user6'></td> <td id='user7'></td> <td id='user8'></td> <td id='user9'></td> <td id='user10'></td> <td id='user11'></td> <td id='user12'></td> <td id='user13'></td> </tr> <tr id='row8'> <td>row8</td> <td id='user1'></td> <td id='user2'></td> <td id='user3'></td> <td id='user4'></td> <td id='user5'></td> <td id='user6'></td> <td id='user7'></td> <td id='user8'></td> <td id='user9'></td> <td id='user10'></td> <td id='user11'></td> <td id='user12'></td> <td id='user13'></td> </tr> <tr id='row9'> <td>row9</td> <td id='user1'></td> <td id='user2'></td> <td id='user3'></td> <td id='user4'></td> <td id='user5'></td> <td id='user6'></td> <td id='user7'></td> <td id='user8'></td> <td id='user9'></td> <td id='user10'></td> <td id='user11'></td> <td id='user12'></td> <td id='user13'></td> </tr> <tr id='row10'> <td>row10</td> <td id='user1'></td> <td id='user2'></td> <td id='user3'></td> <td id='user4'></td> <td id='user5'></td> <td id='user6'></td> <td id='user7'></td> <td id='user8'></td> <td id='user9'></td> <td id='user10'></td> <td id='user11'></td> <td id='user12'></td> <td id='user13'></td> </tr>
</tbody> </table> </div></body>

Scrollable html table with fixed first row and first column, along with angular material controls within the cells of table

I think it is not possible with CSS only. You might need support of JavaScript/JQuery. Check out this light weight plugin. It will help you for sure.

https://github.com/nitsugario/jQuery-Freeze-Table-Column-and-Rows

HTML table with horizontal scrolling (first column fixed)

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>

HTML table with horizontal scrolling (four columns fixed)

CSS:

table {
table-layout: fixed;
width: 100%;
*margin-left: -100px;/*ie7*/
}
td, th {
vertical-align: top;
border-top: 1px solid #ccc;
padding:10px;
width:100px;
}
.col1{
position:absolute;
*position: relative; /*ie7*/
left:0;
width:100px;
}
.col2{
position:absolute;
*position: relative; /*ie7*/
left:100px;
width:100px;
}
.col3{
position:absolute;
*position: relative; /*ie7*/
left:200px;
width:100px;
}
.col4{
position:absolute;
*position: relative; /*ie7*/
left:300px;
width:100px;
}
.outer {position:relative}
.inner {
overflow-x:scroll;
overflow-y:visible;
width:500px;
margin-left:400px;
}

Html:

<div class="outer">
<div class="inner">
<table>
<tr>
<th class="col1">Header A</th>
<th class="col2">Header A</th>
<th class="col3">Header A</th>
<th class="col4">Header A</th>

<td>col 2 - A (WITH LONGER CONTENT)</td>
<td>col 3 - A</td>
<td>col 4 - A</td>
<td>col 5 - A</td>
<td>col 6 - B</td>
<td>col 7 - B</td>
</tr>
<tr>
<th class="col1">Header B</th>
<th class="col2">Header B</th>
<th class="col3">Header B</th>
<th class="col4">Header B</th>

<td>col 2 - B</td>
<td>col 3 - B</td>
<td>col 4 - B</td>
<td>col 5 - B</td>
<td>col 6 - B</td>
<td>col 7 - B</td>
</tr>
<tr>
<th class="col1">Header C</th>
<th class="col2">Header C</th>
<th class="col3">Header C</th>
<th class="col4">Header C</th>

<td>col 2 - C</td>
<td>col 3 - C</td>
<td>col 4 - C</td>
<td>col 5 - C</td>
<td>col 6 - B</td>
<td>col 7 - B</td>
</tr>
</table>
</div>
</div>

https://jsfiddle.net/h75zn59o/

Position:absolute; is what causes that first header column to be fixed. With the original CSS, it's just applied to "th", but using classes (in this example, col1, col2, etc.) we can assign different fixed positions to different columns. Because the columns are 100px wide, each following column is positioned another 100px left So, the first one is 0px, then 100px for col2, etc) to avoid overlap with the previous column.

Scrollable table with fixed column fixed with equal size

What about using javascript to calculate and set the width of the fixed column(.fix-col) and the margin-left of the container div(.table-scroll)?

var columns = document.querySelectorAll('.fix-col');var maxWidth = 0;
/* Loop through columns to get the widest one */for (var i = 0; i < columns.length; i++) { /* Get only the width, without any paddings */ var w = parseFloat(window.getComputedStyle(columns[i]).getPropertyValue('width')); if (w > maxWidth) { maxWidth = w; }}
/* Second loop to set the width */for (var i = 0; i < columns.length; i++) { columns[i].style.width = maxWidth + 'px';}
/* And finally update the margin of the wrapping div */var paddingPlusBorder = 21;document.querySelector('.table-scroll').style.marginLeft = maxWidth + paddingPlusBorder + 'px';
.table-main {  border: none;  border-right: solid 1px rgb(75, 90, 102);  border-collapse: separate;  border-spacing: 0;  font: normal 13px Arial, sans-serif;}
.table-main thead th { background-color: rgb(203, 220, 233); border: none; color: #336B6B; padding: 10px; text-align: left; text-shadow: 1px 1px 1px #fff; white-space: nowrap;}
.table-main tbody td { border-bottom: solid 1px rgb(75, 90, 102); color: #333; padding: 10px; text-shadow: 1px 1px 1px #fff; white-space: nowrap;}
.table { position: relative;}
.table-scroll { overflow-x: scroll; overflow-y: visible; padding-bottom: 5px; width: 500px;}
.table-main .fix-col { border-left: solid 1px rgb(75, 90, 102); border-right: solid 1px rgb(75, 90, 102); left: 0; position: absolute; top: auto;}
<div class="table">  <div class="table-scroll">    <table class="table-main" id="my-table">      <thead>        <tr>          <th class="fix-col">Name</th>          <th>Designation</th>          <th>Experience</th>          <th>Technology</th>          <th>Company</th>          <th>Location</th>          <th>Contact No.</th>          <th>Address</th>        </tr>      </thead>      <tbody>        <tr>          <td class="fix-col">Some very long name</td>          <td>Front End Developer</td>          <td>5 yrs</td>          <td>HTML,CSS</td>          <td>Google</td>          <td>California</td>          <td>9876543210</td>          <td>Google Office</td>        </tr>        <tr>          <td class="fix-col">LooooooooooongNameeee</td>          <td>Front End Developer</td>          <td>5 yrs</td>          <td>HTML,CSS</td>          <td>Google</td>          <td>California</td>          <td>9876543210</td>          <td>Google Office</td>        </tr>        <tr>          <td class="fix-col">Bob</td>          <td>Front End Developer</td>          <td>5 yrs</td>          <td>HTML,CSS</td>          <td>Google</td>          <td>California</td>          <td>9876543210</td>          <td>Google Office</td>        </tr>      </tbody>    </table>  </div></div>

HTML Table first column fixed while scrolling horizontal

It will take some tweaking, but I've successfully done a "sticky column" by using position: sticky on the table cells you'd like to stay in place:

#customers td:nth-child(1),
#customers th:nth-child(1) {
position: sticky;
left: 0;
}

This lets things horizontally scroll underneath the first column.



Related Topics



Leave a reply



Submit