0

I've a HTML table with many columns (even 50 columns!). I'm trying to have the possibility to scroll horizontally (all the table) and vertically (with fixed header).

All the solutions listed in the following link have a small bug: if in Chrome I do ctrl+f to find a specific column name (my table have many columns!), the header doesn't scroll automatically horizontally (native functionality of Chrome).

The link with the solutions tried: HTML table with 100% width, with vertical scroll inside tbody

Any solution to propose?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129

2 Answers2

0

You could put the table inside a div with max-width:100% and overflow-x: auto;. Using the accepted solution from the SO-post you linked I have created a simple example:

// Change the selector if needed
var $table = $('table.scroll'),
  $bodyCells = $table.find('tbody tr:first').children(),
  colWidth;

// Adjust the width of thead cells when window resizes
$(window).resize(function() {
  // Get the tbody columns width array
  colWidth = $bodyCells.map(function() {
    return $(this).width();
  }).get();

  // Set the width of thead columns
  $table.find('thead tr').children().each(function(i, v) {
    $(v).width(colWidth[i]);
  });
}).resize(); // Trigger resize handler
.table-master {
  max-width: 300px;
  overflow-x: auto;
}

table.scroll {
  /* width: 100%; */
  /* Optional */
  /* border-collapse: collapse; */
  border-spacing: 0;
  border: 2px solid black;
}

table.scroll tbody,
table.scroll thead {
  display: block;
}

thead tr th {
  height: 30px;
  line-height: 30px;
  /* text-align: left; */
}

table.scroll tbody {
  height: 100px;
  overflow-y: auto;
  overflow-x: hidden;
}

tbody {
  border-top: 2px solid black;
}

tbody td,
thead th {
  /* width: 20%; */
  /* Optional */
  border-right: 1px solid black;
  /* white-space: nowrap; */
}

tbody td:last-child,
thead th:last-child {
  border-right: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="table-master">
  <table class="scroll">
    <thead>
      <tr>
        <th>Head 1</th>
        <th>Head 2</th>
        <th>Head 3</th>
        <th>Head 4</th>
        <th>Head 5</th>
        <th>Head 5</th>
        <th>Head 5</th>
        <th>Head 5</th>
        <th>Head 5</th>
        <th>Head 5</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Content 1</td>
        <td>Content 2</td>
        <td>Content 3</td>
        <td>Content 4</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
      </tr>
      <tr>
        <td>Content 1</td>
        <td>Content 2</td>
        <td>Content 3</td>
        <td>Content 4</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
      </tr>
      <tr>
        <td>Content 1</td>
        <td>Content 2</td>
        <td>Content 3</td>
        <td>Content 4</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
      </tr>
      <tr>
        <td>Content 1</td>
        <td>Content 2</td>
        <td>Content 3</td>
        <td>Content 4</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
      </tr>
      <tr>
        <td>Content 1</td>
        <td>Content 2</td>
        <td>Content 3</td>
        <td>Content 4</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
      </tr>
      <tr>
        <td>Content 1</td>
        <td>Content 2</td>
        <td>Content 3</td>
        <td>Content 4</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
      </tr>
      <tr>
        <td>Content 1</td>
        <td>Content 2</td>
        <td>Content 3</td>
        <td>Content 4</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
        <td>Content 5</td>
      </tr>
    </tbody>
  </table>
</div>

In this example I used max-width:300px; to make the effect visible

MEE
  • 503
  • 1
  • 11
  • 21
0

I worked the last three days on this problem. You may find some nice JQuery solutions. Here is my approach in plain and pure JavaScript:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head>
<meta charset="utf-8">
<title>Table Test</title>
<script type="text/javascript">
window.onload = function() { NoScrollTables(); }

/* Set all tables, where a "noscroll-"+id exists to no scroll */
function NoScrollTables()
{
var list = document.getElementsByTagName('table');
for (var i = 0; i < list.length; i++)
    {
    if (document.getElementById('noscroll-' + list[i].id) != null) NoScrollTable(list[i].id);
    }
};

/* Initialize a single table to no-scroll */
function NoScrollTable(TabId)
{
var headerwidth=[]; // Storage for width of main table
var maintab = document.getElementById(TabId);
var noscroll = document.getElementById('noscroll-'+TabId);
var restwidth = noscroll.offsetWidth;
for (var i = 0; i < maintab.rows[1].cells.length; i++) headerwidth[i] = maintab.rows[1].cells[i].clientWidth;
var content = maintab.rows[0].innerHTML;
noscroll.rows[0].innerHTML = content;
maintab.rows[0].innerHTML='';
for (i = 0; i < maintab.rows[1].cells.length; i++)  // Set width for both tables identically
    {
    noscroll.rows[0].cells[i].width = headerwidth[i];
    maintab.rows[1].cells[i].width = headerwidth[i];
    restwidth = restwidth - headerwidth[i];
    }
i--;
noscroll.rows[0].cells[i].width = parseInt(noscroll.rows[0].cells[i].width) + parseInt(restwidth); // Expand last cell over possible scrollbar
return;
};

</script>
<style type="text/css">
body {
    text-align: left;
    }
table{
    width: 100%;
    border: 0;
    border-spacing: 0;
    padding: 0;
    clear: both;
    }
table th{
    background-color:#456789;
    display: inline-block;
    float: left;
    padding: 0;
}

table td{
    background-color:#999;
}
</style>
</head><body>

<h1>Pretty Table with pure JavaScript</h1>
<p>Just put an empty table above and name the id with praefix 'noscroll-{mytable}' where {mytable} is the id of the table below.<br/><br/></p>

<div style="width:600px;">
<table id='noscroll-TestTable' >
<thead>
<tr></tr>
</thead>
</table>
</div>
<div style="width:600px; max-height: 300px; overflow: auto;">
<table id='TestTable' style='max-height: 180px; overflow-y: auto;'>
<thead>
    <tr>
        <th>Header 1</th>
        <th>Header 2</th>
        <th>Header 3</th>
    </tr>
</thead>
<tbody>
    <tr>
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr>
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr>
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr>
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr>
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr>
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr>
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr>
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr>
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr>
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr>
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr>
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr>
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr>
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr>
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr>
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr>
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr>
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr>
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr>
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr>
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr>
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr>
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr>
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr>
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr>
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr>
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr>
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr>
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr>
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr>
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr>
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr>
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr>
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr>
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr>
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr>
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr>
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr>
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr>
        <td>And Repeat 1</td>
        <td>And Repeat 2</td>
        <td>And Repeat 3</td>
    </tr>
    <tr>
        <td>Cell Content 1</td>
        <td>Cell Content 2</td>
        <td>Cell Content 3</td>
    </tr>
    <tr>
        <td>More Cell Content 1</td>
        <td>More Cell Content 2</td>
        <td>More Cell Content 3</td>
    </tr>
    <tr>
        <td>Even More Cell Content 1</td>
        <td>Even More Cell Content 2</td>
        <td>Even More Cell Content 3</td>
    </tr>
    <tr>
        <td>End of Cell Content 1</td>
        <td>End of Cell Content 2</td>
        <td>End of Cell Content 3</td>
    </tr>
</tbody>
</table>
</div>

</body>
</html>

JSFiddle: https://jsfiddle.net/Mac65/mf494nuw/34/

Mac
  • 1
  • 4