Reputation: 49
I have a website showing a simple table with weather data. We need to show many rows, so I want to make the body scrollable, while keeping the header fixed.
I have tried a number of solutions, but none of them seem to be compatible with my table header (some header cells have subcategories).
I would like to find a solution based on css and/or javascript. Introducing jQuery or similar would make the site much slower (many of the users have radiolink or satellite internet access).
I have copied part of my code to a JSFiddle
<table>
<thead>
<tr>
<th rowspan="2">Location</th>
<th rowspan="2">Updated</th>
<th colspan="2">Temperature [°C]</th>
<th colspan="2">Wind [m/s]</th>
<th rowspan="2">Air pressure [hPa]</th>
<th rowspan="2">Relative humidity [%]</th>
<th rowspan="2">Precipitation [mm]</th>
</tr>
<tr><th>present</th><th>wind chill</th><th>speed</th><th>max</th> </tr>
</thead>
<tbody>
<tr>
<td>Aasiaat</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Angisoq</td>
<td>20.07 15:00</td>
<td>5,9</td>
<td></td>
<td>3,6 ⇐</td>
<td>4,6</td>
<td>1013</td>
<td>85,0</td>
<td>n/a</td>
</tr>
<tr>
<td>Aasiaat</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test3</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test4</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test5</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
</tbody>
</table>
Upvotes: 0
Views: 936
Reputation: 2001
I drew up a quick codepen for you to see.
Here's the idea:
Remove the table header, and replace it with a fixed container that emulates the header. Give table a height, and make overflow scroll.
Markup:
<ul class="table-header">
<li>Location</li>
<li>Updated</li>
<li>
Temperature
<ul>
<li>present</li>
<li>wind chill</li>
</ul>
</li>
<li>
Wind
<ul>
<li>speed</li>
<li>max</li>
</ul>
</li>
<li>Air pressure</li>
<li>Relative humidity</li>
<li>Precipitation</li>
</ul>
css:
table {
width: 100%;
margin-top: 60px;
overflow: scroll;
max-height: 200px;
}
.table-header {
background-color: white;
position: fixed;
top: 0;
left: 0;
list-style: none;
display: flex;
padding-left: 0;
justify-content: space-around;
width: 100%;
li {
font-size: 1em;
font-weight: 600;
flex-grow: 1;
text-align: center;
}
ul {
display: flex;
list-style: none;
padding-left: 0;
li {
text-align: center;
flex-grow: 1;
}
}
}
It's not perfect, but you get the idea. You just have to play around with flex basis and make the top container look like the table header.
http://codepen.io/zsawaf/pen/mExAak
Upvotes: 0
Reputation: 105893
You will need javascript to hold/fake table layout properties (row/column adjusting to each others)
Maybe a clone()
jquery + table-layout:fixed
could be a start with evenly spread columns, demo below.
$("table thead ").clone().prependTo("table");
table,
th,
td,
th tr {
border: 1px solid black;
border-collapse: collapse;
border-color: #757575;
}
/* test */
* {
box-sizing: border-box;
}
body {
margin: 0;
}
table,
table thead:first-of-type {
width: 100%;
table-layout: fixed;
/* sprays column evenly when no width set */
}
table thead:first-of-type {
position: fixed;
display: table;
top: 0;
background: white;
left: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th rowspan="2">Location</th>
<th rowspan="2">Updated</th>
<th colspan="2">Temperature [°C]</th>
<th colspan="2">Wind [m/s]</th>
<th rowspan="2">Air pressure [hPa]</th>
<th rowspan="2">Relative humidity [%]</th>
<th rowspan="2">Precipitation [mm]</th>
</tr>
<tr>
<th>present</th>
<th>wind chill</th>
<th>speed</th>
<th>max</th>
</tr>
</thead>
<tbody>
<tr>
<td>Aasiaat</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Angisoq</td>
<td>20.07 15:00</td>
<td>5,9</td>
<td></td>
<td>3,6 ⇐</td>
<td>4,6</td>
<td>1013</td>
<td>85,0</td>
<td>n/a</td>
</tr>
<tr>
<td>Aasiaat</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test3</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test4</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test5</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Aasiaat</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Angisoq</td>
<td>20.07 15:00</td>
<td>5,9</td>
<td></td>
<td>3,6 ⇐</td>
<td>4,6</td>
<td>1013</td>
<td>85,0</td>
<td>n/a</td>
</tr>
<tr>
<td>Aasiaat</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test3</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test4</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test5</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Aasiaat</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Angisoq</td>
<td>20.07 15:00</td>
<td>5,9</td>
<td></td>
<td>3,6 ⇐</td>
<td>4,6</td>
<td>1013</td>
<td>85,0</td>
<td>n/a</td>
</tr>
<tr>
<td>Aasiaat</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test3</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test4</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test5</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
</tbody>
</table>
here body shows the scroll, but it can be a div with a set height, in this case see demo below where things comes a bit more average and tricky ....
$("table thead ").clone().prependTo("table");
table,
th,
td,
th tr {
border: 1px solid black;
border-collapse: collapse;
border-color: #757575;
}
/* test */
*{box-sizing:border-box;
}
div {
position:relative;
width : 700px;
padding-right:1em;
height:200px;
}
div div {/* buffer for positionning*/
position:static;
padding:0;
height:100%;
overflow:auto;
}
table,
table thead:first-of-type {
width: 100%;
table-layout: fixed;
/* sprays column evenly when no width set */
}
table thead:first-of-type {
position: absolute;
width: calc(100% - 1em - 1px);
display: table;
top: 0;
background: white;
left: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div><div>
<table>
<thead>
<tr>
<th rowspan="2">Location</th>
<th rowspan="2">Updated</th>
<th colspan="2">Temperature [°C]</th>
<th colspan="2">Wind [m/s]</th>
<th rowspan="2">Air pressure [hPa]</th>
<th rowspan="2">Relative humidity [%]</th>
<th rowspan="2">Precipitation [mm]</th>
</tr>
<tr>
<th>present</th>
<th>wind chill</th>
<th>speed</th>
<th>max</th>
</tr>
</thead>
<tbody>
<tr>
<td>Aasiaat</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Angisoq</td>
<td>20.07 15:00</td>
<td>5,9</td>
<td></td>
<td>3,6 ⇐</td>
<td>4,6</td>
<td>1013</td>
<td>85,0</td>
<td>n/a</td>
</tr>
<tr>
<td>Aasiaat</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test3</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test4</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test5</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
</tbody>
</table>
</div>
</div>
Upvotes: 0
Reputation: 1234
try this css :
.table-container {
height: 20em;
width:100%
}
table {
display: flex;
flex-flow: column;
height: 100%;
width: 100%;
}
table thead {
/* head takes the height it requires,
and it's not scaled when table is resized */
flex: 0 0 auto;
width: calc(100% - 0.9em);
}
table tbody {
/* body takes all the remaining available space */
flex: 1 1 auto;
display: block;
overflow-y: scroll;
}
table tbody tr {
width: 100%;
}
table thead,
table tbody tr {
display: table;
table-layout: fixed;
}
/* decorations */
.table-container {
border: 1px solid black;
padding: 0.3em;
}
table {
border: 1px solid lightgrey;
}
table td, table th {
padding: 0.3em;
border: 1px solid lightgrey;
}
table th {
border: 1px solid grey;
}
<div class="table-container">
<table>
<thead>
<tr>
<th rowspan="2">Location</th>
<th rowspan="2">Updated</th>
<th colspan="2">Temperature [°C]</th>
<th colspan="2">Wind [m/s]</th>
<th rowspan="2">Air pressure [hPa]</th>
<th rowspan="2">Relative humidity [%]</th>
<th rowspan="2">Precipitation [mm]</th>
</tr>
<tr><th>present</th><th>wind chill</th><th>speed</th><th>max</th> </tr>
</thead>
<tbody>
<tr>
<td>Aasiaat</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Angisoq</td>
<td>20.07 15:00</td>
<td>5,9</td>
<td></td>
<td>3,6 ⇐</td>
<td>4,6</td>
<td>1013</td>
<td>85,0</td>
<td>n/a</td>
</tr>
<tr>
<td>Aasiaat</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test3</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test4</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
<tr>
<td>Test5</td>
<td>20.07 15:00</td>
<td>9,3</td>
<td></td>
<td>2,5 ⇙</td>
<td>3,1</td>
<td>1010</td>
<td>87,1</td>
<td>0,0</td>
</tr>
</tbody>
</table>
</div>
Upvotes: 3