<h1>Scroll Middle Section Sideways</h1>
<div class="table-scroll-wrap">
<div id="table-scroll" class="table-scroll">
<table id="main-table" class="main-table">
<thead>
<tr>
<th class="col col1" scope="col">Header 1</th>
<th class="col col2" scope="col">Header 2</th>
<th class="col col3" scope="col">Header 3 </th>
<th scope="col">Header 4 </th>
<th scope="col">Header 5</th>
<th scope="col">Header 6</th>
<th scope="col">Header 7</th>
<th scope="col">Header 8</th>
<th scope="col">Header 9</th>
<th scope="col">Header 10</th>
<th scope="col">Header 11</th>
<th scope="col">Header 12</th>
<th scope="col">Header 13</th>
<th scope="col">Header 14</th>
<th scope="col">Header 15</th>
<th class="col collast" scope="col">Header 16</th>
</tr>
</thead>
<tbody>
<tr>
<td class="col col1">1FirsttopColumnColumn Column</td>
<td class="col col2">2 Cell content </td>
<td class="col col3">3 <a href="#">Cellcontentlonger</a></td>
<td>4Cellcontentwithmore content and more content </td>
<td>5 Cell content</td>
<td>6 Cell content</td>
<td>7 Cell content</td>
<td>8 Cell content</td>
<td>9Cellcontentwith more content and more </td>
<td>10 Cell content</td>
<td>11 Cell content</td>
<td>12 Cell content with more content </td>
<td>13 Cell content</td>
<td>14 Cell content</td>
<td>15 Cell content</td>
<td class="col collast">16 Cell content</td>
</tr>
<tr>
<td class="col col1">1 FirstColumn</td>
<td class="col col2">2 Cell content </td>
<td class="col col3">3 <a href="#">Cell content longer</a></td>
<td>4 Cell content with more content and more content </td>
<td>5 Cell content</td>
<td>6 Cell content</td>
<td>7 Cell content</td>
<td>8 Cell content</td>
<td>9 Cell content with more content and more </td>
<td>10 Cell content</td>
<td>11 Cell content</td>
<td>12 Cell content with more content </td>
<td>13 Cell content</td>
<td>14 Cell content</td>
<td>15 Cell content</td>
<td class="col collast">16 Cell content</td>
</tr>
<tr>
<td class="col col1">1 FirstColumn</td>
<td class="col col2">2 Cell content </td>
<td class="col col3">3 <a href="#">Cell content longer</a></td>
<td>4 Cell content with more content and more content </td>
<td>5 Cell content</td>
<td>6 Cell content</td>
<td>7 Cell content</td>
<td>8 Cell content</td>
<td>9 Cell content with more content and more </td>
<td>10 Cell content</td>
<td>11 Cell content</td>
<td>12 Cell content with more content </td>
<td>13 Cell content</td>
<td>14 Cell content</td>
<td>15 Cell content</td>
<td class="col collast">16 Cell content</td>
</tr>
<tr>
<td class="col col1">1 FirstColumn</td>
<td class="col col2">2 Cell content </td>
<td class="col col3">3 <a href="#">Cell content longer</a></td>
<td>4 Cell content with more content and more content </td>
<td>5 Cell content</td>
<td>6 Cell content</td>
<td>7 Cell content</td>
<td>8 Cell content</td>
<td>9 Cell content with more content and more </td>
<td>10 Cell content</td>
<td>11 Cell content</td>
<td>12 Cell content with more content </td>
<td>13 Cell content</td>
<td>14 Cell content</td>
<td>15 Cell content</td>
<td class="col collast">16 Cell content</td>
</tr>
<tr>
<td class="col col1">1 FirstColumn</td>
<td class="col col2">2 Cell content </td>
<td class="col col3">3 <a href="#">Cell content longer</a></td>
<td>4 Cell content with more content and more content </td>
<td>5 Cell content</td>
<td>6 Cell content</td>
<td>7 Cell content</td>
<td>8 Cell content</td>
<td>9 Cell content with more content and more </td>
<td>10 Cell content</td>
<td>11 Cell content</td>
<td>12 Cell content with more content </td>
<td>13 Cell content</td>
<td>14 Cell content</td>
<td>15 Cell content</td>
<td class="col collast">16 Cell content</td>
</tr>
<tr>
<td class="col col1">1 FirstColumn</td>
<td class="col col2">2 Cell content </td>
<td class="col col3">3 <a href="#">Cell content longer</a></td>
<td>4 Cell content with more content and more content </td>
<td>5 Cell content</td>
<td>6 Cell content</td>
<td>7 Cell content</td>
<td>8 Cell content</td>
<td>9 Cell content with more content and more </td>
<td>10 Cell content</td>
<td>11 Cell content</td>
<td>12 Cell content with more content </td>
<td>13 Cell content</td>
<td>14 Cell content</td>
<td>15 Cell content</td>
<td class="col collast">16 Cell content</td>
</tr>
<tr>
<td class="col col1">1 FirstColumn</td>
<td class="col col2">2 Cell content </td>
<td class="col col3">3 <a href="#">Cell content longer</a></td>
<td>4 Cell content with more content and more content </td>
<td>5 Cell content</td>
<td>6 Cell content</td>
<td>7 Cell content</td>
<td>8 Cell content</td>
<td>9 Cell content with more content and more </td>
<td>10 Cell content</td>
<td>11 Cell content</td>
<td>12 Cell content with more content </td>
<td>13 Cell content</td>
<td>14 Cell content</td>
<td>15 Cell content</td>
<td class="col collast">16 Cell content</td>
</tr>
<tr>
<td class="col col1">1 FirstColumn</td>
<td class="col col2">2 Cell content </td>
<td class="col col3">3 <a href="#">Cell content longer</a></td>
<td>4 Cell content with more content and more content </td>
<td>5 Cell content</td>
<td>6 Cell content</td>
<td>7 Cell content</td>
<td>8 Cell content</td>
<td>9 Cell content with more content and more </td>
<td>10 Cell content</td>
<td>11 Cell content</td>
<td>12 Cell content with more content </td>
<td>13 Cell content</td>
<td>14 Cell content</td>
<td>15 Cell content</td>
<td class="col collast">16 Cell content</td>
</tr>
<tr>
<td class="col col1">1 FirstColumn</td>
<td class="col col2">2 Cell content </td>
<td class="col col3">3 <a href="#">Cell content longer</a></td>
<td>4 Cell content with more content and more content </td>
<td>5 Cell content</td>
<td>6 Cell content</td>
<td>7 Cell content</td>
<td>8 Cell content</td>
<td>9 Cell content with more content and more </td>
<td>10 Cell content</td>
<td>11 Cell content</td>
<td>12 Cell content with more content </td>
<td>13 Cell content</td>
<td>14 Cell content</td>
<td>15 Cell content</td>
<td class="col collast">16 Cell content</td>
</tr>
<tr>
<td class="col col1">1 FirstColumn</td>
<td class="col col2">2 Cell content </td>
<td class="col col3">3 <a href="#">Cell content longer</a></td>
<td>4 Cell content with more content and more content </td>
<td>5 Cell content</td>
<td>6 Cell content</td>
<td>7 Cell content</td>
<td>8 Cell content</td>
<td>9 Cell content with more content and more </td>
<td>10 Cell content</td>
<td>11 Cell content</td>
<td>12 Cell content with more content </td>
<td>13 Cell content</td>
<td>14 Cell content</td>
<td>15 Cell content</td>
<td class="col collast">16 Cell content</td>
</tr>
<tr>
<td class="col col1">1 FirstColumn</td>
<td class="col col2">2 Cell content </td>
<td class="col col3">3 <a href="#">Cell content longer</a></td>
<td>4 Cell content with more content and more content </td>
<td>5 Cell content</td>
<td>6 Cell content</td>
<td>7 Cell content</td>
<td>8 Cell content</td>
<td>9 Cell content with more content and more </td>
<td>10 Cell content</td>
<td>11 Cell content</td>
<td>12 Cell content with more content </td>
<td>13 Cell content</td>
<td>14 Cell content</td>
<td>15 Cell content</td>
<td class="col collast">16 Cell content</td>
</tr>
<tr>
<td class="col col1">1 FirstColumn</td>
<td class="col col2">2 Cell content </td>
<td class="col col3">3 <a href="#">Cell content longer</a></td>
<td>4 Cell content with more content and more content </td>
<td>5 Cell content</td>
<td>6 Cell content</td>
<td>7 Cell content</td>
<td>8 Cell content</td>
<td>9 Cell content with more content and more </td>
<td>10 Cell content</td>
<td>11 Cell content</td>
<td>12 Cell content with more content </td>
<td>13 Cell content</td>
<td>14 Cell content</td>
<td>15 Cell content</td>
<td class="col collast">16 Cell content</td>
</tr>
<tr>
<td class="col col1">1 FirstColumn</td>
<td class="col col2">2 Cell content </td>
<td class="col col3">3 <a href="#">Cell content longer</a></td>
<td>4 Cell content with more content and more content </td>
<td>5 Cell content</td>
<td>6 Cell content</td>
<td>7 Cell content</td>
<td>8 Cell content</td>
<td>9 Cell content with more content and more </td>
<td>10 Cell content</td>
<td>11 Cell content</td>
<td>12 Cell content with more content </td>
<td>13 Cell content</td>
<td>14 Cell content</td>
<td>15 Cell content</td>
<td class="col collast">16 Cell content</td>
</tr>
<tr>
<td class="col col1">1 FirstColumn</td>
<td class="col col2">2 Cell content </td>
<td class="col col3">3 <a href="#">Cell content longer</a></td>
<td>4 Cell content with more content and more content </td>
<td>5 Cell content</td>
<td>6 Cell content</td>
<td>7 Cell content</td>
<td>8 Cell content</td>
<td>9 Cell content with more content and more </td>
<td>10 Cell content</td>
<td>11 Cell content</td>
<td>12 Cell content with more content </td>
<td>13 Cell content</td>
<td>14 Cell content</td>
<td>15 Cell content</td>
<td class="col collast">16 Cell content</td>
</tr>
<tr>
<td class="col col1">1 Last FirstColumn</td>
<td class="col col2">2 Cell content </td>
<td class="col col3">3 <a href="#">Cell content longer</a></td>
<td>4 Cell content with more content and more content </td>
<td>5 Cell content</td>
<td>6 Cell content</td>
<td>7 Cell content</td>
<td>8 Cell content</td>
<td>9 Cell content with more content and more </td>
<td>10 Cell content</td>
<td>11 Cell content</td>
<td>12 Cell content with more content </td>
<td>13 Cell content</td>
<td>14 Cell content</td>
<td>15 Cell content</td>
<td class="col collast">16 Cell content</td>
</tr>
</tbody>
<tfoot>
<tr>
<td class="col col1">Footer 1</td>
<td class="col col2">Footer 2</td>
<td class="col col3">Footer 3</td>
<td>Footer 4</td>
<td>Footer 5</td>
<td>Footer 6</td>
<td>Footer 7</td>
<td>Footer 8</td>
<td>Footer 9</td>
<td>Footer 10</td>
<td>Footer 11</td>
<td>Footer 12</td>
<td>Footer 13</td>
<td>Footer 14</td>
<td>Footer 15</td>
<td class="col collast">Footer 16</td>
</tr>
</tfoot>
</table>
</div>
</div>
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
display: flex;
flex-direction: column;
min-height: 100vh;
margin:0;
}
h1 {
margin: auto 0 0;
text-align: center;
font-size: 1.5rem;
}
.table-scroll-wrap {
position: relative;
margin: 0 auto auto;
width: 85%;
max-width: 2000px;
height: 70vh; /* for vertical scrolling if required*/
}
.table-scroll {
position: relative;
width: 100%;
z-index: 1;
margin: 0;
overflow: auto;
height: 100%; /* for vertical scrolling if required*/
}
.table-scroll table {
width: 100%;
margin: 0;
table-layout: auto;
border-collapse: separate;
border-spacing: 0;
word-wrap: break-word;
}
.table-wrap {
position: relative;
}
.table-scroll th,
.table-scroll td {
padding: 5px 10px;
border: 1px solid #000;
background: #fff;
vertical-align: top;
width: auto;
min-width:100px;
}
.table-scroll thead th {
background: #333;
color: #fff;
position: -webkit-sticky;
position: sticky;
top: 0;
white-space:nowrap;
}
/* safari and ios need the tfoot itself to be position:sticky also */
.table-scroll tfoot,
.table-scroll tfoot th,
.table-scroll tfoot td {
position: -webkit-sticky; /* this is needed for ios*/
position: sticky;
bottom: 0;
background: #666;
color: #fff;
z-index: 4;
}
a:focus {
background: red;
} /* testing links*/
.col {
position: -webkit-sticky;
position: sticky;
left: 0;
z-index: 2;
}
tbody .col {
background: #ccc;
}
.collast {
left: auto;
right: 0;
}
thead .col,
.table-scroll tfoot .col {
z-index: 6;
}
@media screen and (max-width: 1050px) {
.table-scroll-wrap {
width: calc(100% - 20px);
margin:auto;
}
}
/* for small screen I would remove sticky side columns and just let table scroll sideways.*/
/* something roughly like this */
@media screen and (max-width: 900px) {
.table-scroll table {
table-layout: auto;
}
.table-scroll tbody .col {
position: static;
}
.table-scroll thead .col,
.table-scroll tfoot .col {
left: auto!important;
right: auto!important;
}
.table-scroll tbody td.col {
background: #fff;
}
.table-scroll th,
.table-scroll td {
min-width: 150px;
}
.table-scroll-wrap:after,
.table-scroll-wrap:before{
content: "";
position: absolute;
right: 0;
top: 0;
bottom: 0;
background: linear-gradient(to left, #666, transparent);
z-index: 999;
width: 45px;
pointer-events: none;
}
.table-scroll-wrap:before{
right:auto;
left:0;
background: linear-gradient(to right, #666, transparent)
}
}
function updateStickyColumnPositions() {
const table = document.querySelector('.main-table');
const rows = table.querySelectorAll('tr');
let colWidths = [];
// Grab the first row (thead or tbody, doesn't matter if structure is consistent)
const firstRow = rows[0].children;
// Measure the widths of the first 3 sticky columns
for (let i = 0; i < 3; i++) {
colWidths[i] = firstRow[i].offsetWidth;
}
// Compute cumulative left offsets
const left1 = 0;
const left2 = colWidths[0];
const left3 = colWidths[0] + colWidths[1];
// Set inline styles dynamically
const col1Els = document.querySelectorAll('.col1');
const col2Els = document.querySelectorAll('.col2');
const col3Els = document.querySelectorAll('.col3');
col1Els.forEach(el => el.style.left = left1 + 'px');
col2Els.forEach(el => el.style.left = left2 + 'px');
col3Els.forEach(el => el.style.left = left3 + 'px');
}
// Run on DOM load and on resize to handle dynamic table width
window.addEventListener('DOMContentLoaded', updateStickyColumnPositions);
window.addEventListener('resize', updateStickyColumnPositions);
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.