0

I'm buindling a custom table with a detached header. That means the table rows content can be scrolled while the table header remain visible.

I'm almost there, except for 2 minor things I need to accomplish.

Problem 1: I need to keep my vertical bar visible at all time, but when I have more columns than the width, the horizontal scrollbar appears and send my vertical bar to the right side of the columns, making it disappear:

enter image description here

Problem 2: I need to be able to extend the last column to fill the whole width, even if there is space left:

enter image description here

I would rather use pure JavaScript, not jQuery.

JSFiddle

<p>
Problem 1: How to keep the vertical scrollbar on view
</p>

<div class="container1">
  <table>
    <thead>
      <tr>
        <th>Column 1</th>
        <th>Column 2</th>
        <th>Column 3</th>
        <th>Column 4</th>
        <th>Column 5</th>
        <th>Column 6</th>
        <th>Column 7</th>
        <th>Column 8</th>
      </tr>

    </thead>
    <tbody>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
        <td>Data 6</td>
        <td>Data 7</td>
        <td>Data 8</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
        <td>Data 6</td>
        <td>Data 7</td>
        <td>Data 8</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
        <td>Data 6</td>
        <td>Data 7</td>
        <td>Data 8</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
        <td>Data 6</td>
        <td>Data 7</td>
        <td>Data 8</td>
      </tr>

    </tbody>
  </table>
</div>


<p>
Problem 2: How to make the last cell go full width
</p>

<div class="container2">
  <table>
    <thead>
      <tr>
        <th>Column 1</th>
        <th>Column 2</th>
        <th>Column 3</th>
        <th>Column 4</th>
        <th>Column 5</th>
      </tr>

    </thead>
    <tbody>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
      </tr>

    </tbody>
  </table>
</div>


.container1 table,
.container1 th,
.container1 td {
  background-color: white;
  padding: 5px;
  font-size: 15px;
  border: 1px solid black;
  border-collapse: collapse;
  min-width: 50px;
  max-width: 50px;
}


.container1 {
  max-width: 100%;
  width: 100%;
  overflow-x: scroll;
}

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

.container1 table tbody {
  overflow-y: scroll;
  height: 50px;
}



.container2 table,
.container2 th,
.container2 td {
  background-color: white;
  padding: 5px;
  font-size: 15px;
  border: 1px solid black;
  border-collapse: collapse;
  min-width: 50px;
  max-width: 50px;
}

.container2 th:last-child,
.container2 td:last-child {
  background-color: yellow;
  min-width: 50px;
  max-width: 100%;
}


.container2 {
  max-width: 100%;
  width: 100%;
  overflow-x: scroll;
}

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

.container2 table tbody {
  overflow-y: scroll;
  height: 50px;
}
halfer
  • 19,824
  • 17
  • 99
  • 186
Mendes
  • 17,489
  • 35
  • 150
  • 263

2 Answers2

0

Table with fixed header and scrolling in the body

I did a small function using pure javascript and made a slight modification in your html to include a scrollable div.

function setWidth(container) {
  var 
  tds = document.querySelectorAll("." + container + " .scroll table tr:first-child td"),
  ths = document.querySelectorAll("." + container + ">table tr:first-child th");
  for (var i = 0; i < tds.length - 1; i++) {
    ths[i].style.width = tds[i].clientWidth - 2 + 'px';
  }
}
setWidth("container1");
setWidth("container2");
table {
  font-size: 15px;
  border-collapse: collapse;
  margin: 0 0 -1px 0;
  table-layout: fixed;
  width: 100%;
}
td, th {
  border: 1px solid black;
}
td:last-child,
th:last-child {
  width: auto;
}
.scroll {
  height: 50px;
  overflow-y: scroll;
}
.container2 th:last-child,
.container2 td:last-child {
  background-color: yellow;
}
<p>
Problem 1: How to keep the vertical scrollbar on view
</p>

<div class="container1">
  <table>
    <thead>
      <tr>
        <th>Column 1</th>
        <th>Column 2</th>
        <th>Column 3</th>
        <th>Column 4</th>
        <th>Column 5</th>
        <th>Column 6</th>
        <th>Column 7</th>
        <th>Column 8</th>
      </tr>
    </thead>
  </table>
  <div class="scroll">
  <table>
    <tbody>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
        <td>Data 6</td>
        <td>Data 7</td>
        <td>Data 8</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
        <td>Data 6</td>
        <td>Data 7</td>
        <td>Data 8</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
        <td>Data 6</td>
        <td>Data 7</td>
        <td>Data 8</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
        <td>Data 6</td>
        <td>Data 7</td>
        <td>Data 8</td>
      </tr>

    </tbody>
  </table>
  </div>
</div>


<p>
Problem 2: How to make the last cell go full width
</p>

<div class="container2">
  <table>
    <thead>
      <tr>
        <th>Column 1</th>
        <th>Column 2</th>
        <th>Column 3</th>
        <th>Column 4</th>
        <th>Column 5</th>
      </tr>
    </thead>
  </table>
  <div class="scroll">
  <table>
    <tbody>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
      </tr>

    </tbody>
  </table>
</div>
</div>
0

document.getElementById("tbody").addEventListener("scroll", myFunction);
function myFunction() {

var elmnt = document.getElementById("tbody");
var elmnt2 = document.getElementById("thead");

elmnt2.scrollLeft = elmnt.scrollLeft;

}
.container1 table,
.container1 th,
.container1 td {
  background-color: white;
  padding: 5px;
  font-size: 15px;
  border: 1px solid black;
  border-collapse: collapse;
  min-width: 50px;
  max-width: 50px;
}

.container1 {
  width: 400px;
}

.container1 table tbody,
.container1 table thead {
  display: block;
  
}
.container1 table thead{
  width: 400px;
  overflow-x:hidden;
}
.container1 table{
  width: 400px;
}
.container1 table tbody {
  height: 80px;
  width: 400px;
  overflow: scroll;
}

table {
  margin: 0;
  padding: 0;
}

.container2 table {
  width: 100%;
  background-color: white;
  padding: 5px;
  font-size: 16px;
  border: 1px solid black;
  border-collapse: collapse;
}

.container2 th,
.container2 td {
  background-color: white;
  padding: 5px;
  font-size: 16px;
  border: 1px solid black;
  border-collapse: collapse;
  min-width: 50px;
  max-width: 50px;
}

.container2 th:last-child,
.container2 td:last-child {
  background-color: yellow;
  width: 100%;
}

.container2 {
  max-width: 100%;
  width: 100%;
  overflow-x: scroll;
}

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

.container2 table tbody {
  overflow-y: scroll;
  height: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
  Problem 1: How to keep the vertical scrollbar on view
</p>

<div class="container1">
  <table id="table1">
    <thead id="thead">
      <tr>
        <th>Column 1</th>
        <th>Column 2</th>
        <th>Column 3</th>
        <th>Column 4</th>
        <th>Column 5</th>
        <th>Column 6</th>
        <th>Column 7</th>
        <th>Column 8</th>
      </tr>

    </thead>
    <tbody id="tbody">
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
        <td>Data 6</td>
        <td>Data 7</td>
        <td>Data 8</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
        <td>Data 6</td>
        <td>Data 7</td>
        <td>Data 8</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
        <td>Data 6</td>
        <td>Data 7</td>
        <td>Data 8</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
        <td>Data 6</td>
        <td>Data 7</td>
        <td>Data 8</td>
      </tr>

    </tbody>
  </table>
</div>


<p>
  Problem 2: How to make the last cell go full width
</p>

<div class="container2">
  <table>
    <thead>
      <tr>
        <th>Column 1</th>
        <th>Column 2</th>
        <th>Column 3</th>
        <th>Column 4</th>
        <th>Column 5</th>
      </tr>

    </thead>
    <tbody>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
      </tr>
      <tr>
        <td>Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
        <td>Data 4</td>
        <td>Data 5</td>
      </tr>

    </tbody>
  </table>
</div>
Shadow Fiend
  • 1,829
  • 1
  • 9
  • 14
  • Friend: nice answer, but my Problem1 seens not to be solved, as now my table has a fixed 400px width. I need the table to get full width of its container div (100%) and once scrolled horizontally to keep the vertical scroll bar visible. – Mendes Sep 30 '17 at 11:45
  • can you post a fiddle for with so I can look at it? – Shadow Fiend Sep 30 '17 at 11:51
  • Here is the [JSFiddle](https://jsfiddle.net/t12r0p8r/2/). I just need to mantain the vertical scrollbar always visible no matter where is the horizontal bar wihtout changing the table scructure. Repair that it has a fixed header - no matter what you do with the vertical bar, the header is maintened visible, and alto it gets full with of its container. In the fiddle the vertical bar is only visible if I scroll right the horizontal bar. – Mendes Sep 30 '17 at 12:10
  • is the width of your container fixed? – Shadow Fiend Sep 30 '17 at 13:02