I am trying to make a table with fixed header and a scrollable content using the bootstrap 3 table. Unfortunately the solutions I have found does not work with bootstrap or mess up the style.
Here there is a simple bootstrap table, but for some reason to me unknown the height of the tbody is not 10px.
height: 10px !important; overflow: scroll;
Example:
Make | Model | Color | Year |
---|---|---|---|
111 Ford | Escort | Blue | 2000 |
Ford | Escort | Blue | 2000 |
Ford | Escort | Blue | 2000 |
Ford | Escort | Blue | 2000 |
Fixed table head - CSS-only
Simply position: sticky; top: 0;
your th
elements. (Chrome, FF, Edge)
.tableFixHead { overflow: auto; height: 100px; } .tableFixHead thead th { position: sticky; top: 0; z-index: 1; } /* Just common table stuff. Really. */ table { border-collapse: collapse; width: 100%; } th, td { padding: 8px 16px; } th { background:#eee; }
TH 1 | TH 2 |
---|---|
A1 | A2 |
B1 | B2 |
C1 | C2 |
D1 | D2 |
E1 | E2 |
For both sticky vertical TH and horizontal TH columns (inside TBODY
):
.tableFixHead { overflow: auto; height: 100px; width: 240px; }
.tableFixHead thead th { position: sticky; top: 0; z-index: 1; }
.tableFixHead tbody th { position: sticky; left: 0; }
.tableFixHead { overflow: auto; height: 100px; width: 240px; } .tableFixHead thead th { position: sticky; top: 0; z-index: 1; } .tableFixHead tbody th { position: sticky; left: 0; } /* Just common table stuff. Really. */ table { border-collapse: collapse; width: 100%; } th, td { padding: 8px 16px; white-space: nowrap; } th { background:#eee; }
TH 1 | TH 2 | |
---|---|---|
Foo | Some long text lorem ipsum | Dolor sit amet |
Bar | B1 | B2 |
Baz | C1 | C2 |
Fuz | D1 | D2 |
Zup | E1 | E2 |
TH borders problem fix
Since border
cannot be painted properly on a translated TH
element, to recreate and render "borders" use the box-shadow
property:
/* Borders (if you need them) */
.tableFixHead,
.tableFixHead td {
box-shadow: inset 1px -1px #000;
}
.tableFixHead th {
box-shadow: inset 1px 1px #000, 0 1px #000;
}
.tableFixHead { overflow: auto; height: 100px; } .tableFixHead thead th { position: sticky; top: 0; z-index: 1; } /* Just common table stuff. Really. */ table { border-collapse: collapse; width: 100%; } th, td { padding: 8px 16px; } th { background:#eee; } /* Borders (if you need them) */ .tableFixHead, .tableFixHead td { box-shadow: inset 1px -1px #000; } .tableFixHead th { box-shadow: inset 1px 1px #000, 0 1px #000; }
TH 1 | TH 2 |
---|---|
A1 | A2 |
B1 | B2 |
C1 | C2 |
D1 | D2 |
E1 | E2 |
TH sticky not working fix
Ensure that parent-elements of "th
" element, at least till table
element (inclusive), do Not set overflow
related styles (e.g. overflow
, overflow-x
, overflow-y
).
For more see stackoverflow.com/Why is 'position: sticky' not working?
Fixed table head - using JS. (IE)
You can use a bit of JS and translateY the th
elements
jQuery example
var $th = $('.tableFixHead').find('thead th') $('.tableFixHead').on('scroll', function() { $th.css('transform', 'translateY('+ this.scrollTop +'px)'); }); .tableFixHead { overflow-y: auto; height: 100px; } /* Just common table stuff. */ table { border-collapse: collapse; width: 100%; } th, td { padding: 8px 16px; } th { background:#eee; }
TH 1 | TH 2 |
---|---|
A1 | A2 |
B1 | B2 |
C1 | C2 |
D1 | D2 |
E1 | E2 |
Or plain ES6 if you prefer (no jQuery required):
// Fix table head
function tableFixHead (e) {
const el = e.target,
sT = el.scrollTop;
el.querySelectorAll("thead th").forEach(th =>
th.style.transform = `translateY(${sT}px)`
);
}
document.querySelectorAll(".tableFixHead").forEach(el =>
el.addEventListener("scroll", tableFixHead)
);
translateY
(and the jQuery code - if you don't compile your ES6 js code). It'll work, but will look a bit "jumpish". But that's OK. If one wants to use outdated browsers than such person/company will never complain about choppy things - as far as he's able to see the content and have a decent interaction with your website. Interesting read ahead: nealbuerger.com/2018/01/the-end-of-life-of-internet-explorer-11{ position: sticky; top: 0; }
somehow does not work in your code - check theoverflow-x
andoverflow-y
css properties of containing elements, especiallytable
,thead
,tr
. Overflows, surprisingly both of them, must not be set. You may need to explicitlyunset
them. More info - stackoverflow.com/a/54806576/882936For a pure CSS approach you'd need a container with
overflow-y: auto;
and decide how to hide scrolled/overflown rows:Overlay by a non-transparent sticky header (position: sticky; top: 0; z-index: 1;), like in the @RokoCBuljan's answer. Toggle visibility of the rows (by setting tr:after properties as per below).
Note that the container can be an external
<div>
, or the<table>
itself, or a part of it (e.g.<tbody>
). For the later two you gotta setdisplay: block;
so effectively they're treated asdiv
s.See below a modified @giulio's solution:
:root { --height-height: 150px; /* cell width has to reserve some space for scrolling. Hence the sum < 100% */ --cell-width: 85px; } .header-fixed { width: 200px; } /* Treat all as divs */ .header-fixed > thead, .header-fixed > tbody, .header-fixed > thead > tr, .header-fixed > tbody > tr, .header-fixed > thead > tr > th, .header-fixed > tbody > tr > td { display: block; } /* Prevent header to wrap */ .header-fixed > thead > tr > th { white-space: nowrap; background-color: lightgrey; } .header-fixed > tbody > tr:after, .header-fixed > thead > tr:after { content: ' '; display: block; visibility: hidden; clear: both; } .header-fixed > tbody { overflow-y: auto; height: var(--height-height); } .header-fixed > tbody > tr > td, .header-fixed > thead > tr > th { width: var(--cell-width); border: thin solid grey; float: left; }
Note: If you've got >2 columns, you need to fiddle with the
var(--cell-width)
variable accordingly..header-fixed > thead > tr > th{white-space: nowrap;}
as well. If headers start wrapping it messes things up[<>]
snippet editor?Here is the working solution:
table { width: 100%; } thead, tbody, tr, td, th { display: block; } tr:after { content: ' '; display: block; visibility: hidden; clear: both; } thead th { height: 30px; /*text-align: left;*/ } tbody { height: 120px; overflow-y: auto; } thead { /* fallback */ } tbody td, thead th { width: 19.2%; float: left; }
Link to jsfiddle
Update
For newer and still maintained library try jquery.floatThead (as mentioned by Bob Jordan in the comment) instead.
Old Answer
This is a very old answer, the library mentioned below no longer maintained.
I am using StickyTableHeaders on GitHub and it works like charm!
I had to add this css to make the header not transparent though.
.tableFloatingHeaderOriginal { //css }
.Don't need the wrap it in a div...
CSS:
Bootply : https://www.codeply.com/p/nkaQFc713a
It is easier with css
table-layout:fixed
by adding a CSS class with JavaScriptth
does not align withtd
By far the best solution I've seen that is CSS only, with good cross browser support, and no alignment issues is this solution from codingrabbithole
<colgroup><col style="width: 10px;"><col style="width: 100px;"></colgroup>
to manage width of columns of your table - all your settings are ignored..table-scroll th:nth-child(1), .table-scroll td:nth-child(1) { width: 3%; }
for n number of columnstable { overflow-y: auto; height: 50vh; /* !!! HEIGHT MUST BE IN [ vh ] !!! */ } thead th { position: sticky; top: 0; }
You don't need js. Important is to set table height in [vh]
Late to the party (Story of my life), but since this is the first result on google, and none of the above got me working, here's my code
th:nth-child(2), td:nth-child(2)
is equivalent totr > :nth-child(2)
In my eyes, one of the best plugins for jQuery is DataTables.
It also has an extension for fixed header, and it is very easily implemented.
Taken from their site:
HTML:
JavaScript:
But the simplest you can have for just making a scrollable
<tbody>
is:The latest addition position:'sticky' would be the simplest solution here
.outer{ overflow-y: auto; height:100px; } .outer table{ width: 100%; table-layout: fixed; border : 1px solid black; border-spacing: 1px; } .outer table th { text-align: left; top:0; position: sticky; background-color: white; }
block
to table display, anonymous table wrapper will be created), fixed table layout is not needed andsticky
can't be set on thead and tr in today's browsers (would you add this info to your answer to save others troubles implementing it?)Multiple scrollable table support in a single window.
Pure CSS & No fixed or sticky.
I am searching fixed table header with auto "td" and "th" width for years. Finally i coded something, it's work well for me but i am not sure is it work well for everyone.
Problem 1: We can't set table or tbody height while have tons of "tr" it's because of default table properties.
Solution: Set table a display property.
Problem 2: When we set a display property, the width of "td" elements can't be equal width of "th" elements. And it is hard to fill elements properly in full width table like 100%.
Solution: CSS "flex" is very good solution for width and fill set-ups, so we will build our tbody and thead elements with CSS "flex".
.ea_table { border: 1px solid #ddd; display: block; background: #fff; overflow-y: hidden; box-sizing: border-box; float: left; height:auto; width: 100%; } .ea_table tbody, thead { flex-direction: column; display: flex; } .ea_table tbody { height: 300px; overflow: auto; } .ea_table thead { border-bottom: 1px solid #ddd; } .ea_table tr { display: flex; } .ea_table tbody tr:nth-child(2n+1) { background: #f8f8f8; } .ea_table td, .ea_table th { text-align: left; font-size: 0.75rem; padding: 1.5rem; flex: 1; }
jsfiddle
You should try with "display:block;" to tbody, because now it's inline-block and in order to set height, the element should be "block"
I had a lot of trouble getting the stickytableheaders library to work. Doing a bit more searching, I found floatThead is an actively maintained alternative with recent updates and better documentation.
I used the floatThead jQuery plugin (https://mkoryak.github.io/floatThead/#intro)
docs say it works with Bootstrap 3 tables and I can say it also works with Bootstrap 4 tables with or without the table-responsive helper.
Using the plugin is as simple as this:
HTML (vanilla bootstrap table markup)
Plugin Initialization:
Full disclaimer: I am not associated with the plugin in any way. I happened to find it after hours of trying lots of other solutions posted here and elsewhere.
First add some markup for a bootstrap table. Here I created a striped table but also have added a custom table class
.table-scroll
which adds vertical scroll bar to the table and makes the table header fixed while scrolling down.css
For tables that are full height (the page scrolls, not the table)
Note: I move the whole
<thead>...</thead>
beause In my case I had two rows (Title and filters)With JS (jQuery)
CSS (Just for styling)
Now that “all” browsers support ES6, I’ve incorporated the various suggestions above into a JavaScript class that takes a table as an argument and makes the body scrollable. It lets the browser’s layout engine determine header and body cell widths, and then makes the column widths match each other.
The height of a table can be set explicitly, or made to fill the remaining part of the browser window, and provides callbacks for events such as viewport resizing and/or
details
elements opening or closing.Multi-row header support is available, and is especially effective if the table uses the id/headers attributes for accessibility as specified in the WCAC Guidelines, which is not as onerous a requirement as it might seem.
The code does not depend on any libraries, but plays nicely with them if they are being used. (Tested on pages that use JQuery).
The code and sample usage are available on Github.
This is my implementation for a content scrollable table implemented with just the
div
element and pure CSS Flexbox styling..table { display: flex; flex-direction: column; background-color: lightblue; width: 600px; height: 200px; font-family: "Courier New"; } .header { display: flex; flex-direction: row; background-color: whitesmoke; padding-right: 10px; font-weight: bold; } .row { border-bottom: 1px solid gainsboro; } .row>div { width: 25%; text-align: left; } .content { height: 100%; display: flex; flex-direction: column; overflow-y: scroll; } .entry { display: flex; flex-direction: row; padding-top: 5px; } /* Chrome, Edge, Safari and Opera support the non-standard ::-webkit-scrollbar pseudo element. We need the scroll bar width set so as to apply same padding in the table header row for alignment. */ /* width */ ::-webkit-scrollbar { width: 10px; } /* Track */ ::-webkit-scrollbar-track { background: whitesmoke; border-radius: 2px; } /* Handle */ ::-webkit-scrollbar-thumb { background: lightgrey; border-radius: 2px; } /* Handle on hover */ ::-webkit-scrollbar-thumb:hover { background: grey; }
Content Scrollable Table - CSS only
@maruifeng
CodePen
For whatever it's worth now: I did post a solution to a sister-thread Table scroll with HTML and CSS which
takes two tables (one for only header, one for all - layouted by the browser)
after layouting, adjust the upper (header-only) table to the widths of the lower one
hide (visibility, not display) the header of the lower table and make the lower table scrollable w/in a div
The solution is agnostic to any styles / frameworks used - so maybe it's useful here as well...
A long description is in Table scroll with HTML and CSS / the code is also in this pen: https://codepen.io/sebredhh/pen/QmJvKy
Cleaner Solution (CSS Only)
Used this link, stackoverflow.com/a/17380697/1725764, by Hashem Qolami at the original posts' comments and used display:inline-blocks instead of floats. Fixes borders if the table has the class 'table-bordered' also.
Then just add the widths of the td and th
put the table inside the div like this to make scrollable table vertically. change
overflow-y
tooverflow-x
to make table scrollable horizontally. justoverflow
to make table scrollable both horizontal and vertical.All of the six or so CSS solutions assumed a short table. These should have tested with something hundreds of rows long.
based on @Roko C. Buljan answer, if you try to add rowspan, Only the first
th
will befixed
when you scroll..tableFixHead { overflow: auto; height: 100px; } .tableFixHead thead th { position: sticky; top: 0; z-index: 1; } /* Just common table stuff. Really. */ table { border-collapse: collapse; width: 100%; } th, td { padding: 8px 16px; } th { background:#eee; }
You can add this line if you want try to fixed the rowspan
for an example you can check this snippet
.tableFixHead { overflow: auto; height: 200px; } .tableFixHead thead th { position: sticky; top: 0; z-index: 1; } .tableFixHead thead tr:nth-child(2) th { top: 34px; /* change the number according to your need */ } .tableFixHead thead tr:nth-child(3) th { top: 68px; /* change the number according to your need */ } /* Just common table stuff. Really. */ table { border-collapse: collapse; width: 100%; } th, td { padding: 8px 16px; } th { background:#eee; }
above snippet will work if you specify number manually with
nth-child(number)
Just found a cool solution using grid! This is what I used and it worked out perfectly:
Demo: https://codesandbox.io/s/table-with-inner-body-scroll-hggq7x
You can place two div where 1st div (Header) will have transparent scroll bar and 2nd div will be have data with visible/auto scroll bar. Sample has angular code snippet for looping through the data.
Below code worked for me -
Additional style to hide header scroll bar -
table { display: block; } thead, tbody { display: block; } tbody { position: absolute; height: 150px; overflow-y: scroll; } td, th { min-width: 100px !important; height: 25px !important; overflow:hidden !important; text-overflow: ellipsis !important; max-width: 100px !important; }
An easy way without fixed width:
Source
Now, on onLoad, to adjust th widths, just add this jquery script:
Follow WeChat
Success story sharing
Want to stay one step ahead of the latest teleworks?
Subscribe Now相似问题
HuntsBot,a one-stop outsourcing task, remote job, product ideas sharing and subscription platform, which supports DingTalk, Lark, WeCom, Email and Telegram robot subscription. The platform will push outsourcing task requirements, remote work opportunities, product ideas to every subscribed user with timely, stable and reliable.
Platform
Support
Contact US
Any questions or suggestions during use, you can contact us in the following ways:
Email: huntsbot@xinbeitime.com
微信公众号
Tips