I am using a data table for which i am using the traditional table markup but what i want is my table start from somewhere in the page and i want my table header to be fixed where it starts and table body should scroll by taking the remaining page height
i am showing a small example here
https://codepen.io/avreddy/pen/eyYBdB?editors=1100
.datatable{ width: 50%; border-collapse: collapse; } td{ text-align: center; border: 1px solid; padding:5px; }
<body> <div class="somecontent"> <h4>Some Content</h4><h4>Some Content</h4><h4>Some Content</h4> </div> <table class="datatable"> <thead> <tr> <th>col1</th> <th>col2</th> <th>col3</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr> </tbody> </table> </body>
I know we can get it from flex-box responsive table but my limitation is i have to use traditional table markup so if tell me if there is any other way than flexbox responsive table
Thank you
4 Answers
Answers 1
Scrollable table + fixed header tricks cannot work with automatic column widths. This is because they change the display property of tbody
element which creates a new (anonymous) table having different column widths.
The best solution I could think of is to create a copy of the table (so that both have identical content and therefore identical column widths) and manipulate them independently.
In the following example, I use jQuery to create a copy of table and visibility: collapse
to hide the table header and body:
$(function() { $("#button-1").one("click", function() { $(".datatable").clone().insertAfter(".datatable"); $(".datatable").eq(0).addClass("tablehead"); $(".datatable").eq(1).addClass("tablebody"); }); });
/* full height */ html { height: 100%; } body { height: 100%; margin: 0; padding: 0; font: medium monospace; } /* make last item scrollable and occupy available height */ #wrapper { height: 100%; display: flex; flex-direction: column; overflow-y: hidden; } #wrapper > :last-child { display: block; flex: 1; overflow-y: auto; } /* make thead and tbody collapse when JavaScript adds the classes */ .datatable.tablehead tbody { visibility: collapse; } .datatable.tablebody thead { visibility: collapse; } /* beautify */ .datatable { border-collapse: collapse; } .datatable th { border: 1px solid; background-color: #CCC; } .datatable td { border: 1px solid; padding: 5px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <!-- Notes: 1) Using a wrapper div instead of body because third party scripts often append elements to body element breaking our flex model 2) Width of second column is determined by thead > 1st row > 2nd column while width of third column is determined by tbody > 1st row > 3rd column 3) If JavaScript fails the result is still usable --> <div id="wrapper"> <div> <h4>Some Content</h4> <h4>Some Content</h4> <p><button type="button" id="button-1">Convert to fixed header</button></p> </div> <table class="datatable"> <thead> <tr> <th>col 1</th> <th>col 2 (wide header)</th> <th>col 3</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>2</td> <td>3 (wide content)</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> </tbody> </table> </div>
Note that visibility: collapse
is not implemented properly in all browsers. Alternate solution is to wrap the two tables inside divs: fixed height div for header table, scrollable div for body table. But then you need to set the height of the header.
Answers 2
.datatable{ width: 50%; border-collapse: collapse; } /*this code is added to fix header at the top of the screen*/ thead th{ position: sticky; /*stick the element*/ top: 0px; background: grey; } td{ text-align: center; border: 1px solid; padding:5px; }
<body> <div class="somecontent"> <h4>Some Content</h4><h4>Some Content</h4><h4>Some Content</h4> </div> <table class="datatable"> <thead> <tr> <th>col1</th> <th>col2</th> <th>col3</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr><tr> <td>1</td> <td>2</td> <td>3</td> </tr> </tbody> </table> </body>
you want something like this header will be sticky on top of the page.
Answers 3
Try position: sticky
for your thead
.
You need to apply it to the th
to work in all browsers.
thead th { position: sticky; // Sticky makes it, well, sticky top: 0px; // At which offset it should become sticky background-color: #fff; // Otherwise the th is transparent }
To make it sticky from it's current position, you can use a little javascript:
let topOffset = document.getElementById("datatable").offsetTop; let elementList = document.querySelectorAll('.datatable thead th'); for (i = 0; i < elementList.length; i++) { elementList[i].style.top = topOffset + 'px'; }
It may look a little weird now in the pen (overlap/transparency), but when you say there is content above the thead
(a header, an alertbox, ..), just a apply a zIndex
higher than the table, and it should look fine.
I'm currently working on a website with a fullscreen table, a sticky header, and a variable height content block above it, and this is what I use (although the offset is calculated a little different with AngularJS).
Answers 4
I think it works.
<style> table { max-width:980px; table-layout:fixed; } th, td { padding:5px 10px; border:1px solid #000; } thead, tfoot { background:#f9f9f9; display:table; width:100%; width:calc(100% - 18px); } tbody { height:300px; overflow:auto; overflow-x:hidden; display:block; width:100%; } tbody tr { display:table; width:100%; table-layout:fixed; } </style>
0 comments:
Post a Comment