How to set tbody height with overflow scroll

If you want tbody to show a scrollbar, set its display: block;.

Set display: table; for the tr so that it keeps the behavior of a table.

To evenly spread the cells, use table-layout: fixed;.

DEMO tbody scroll


CSS:

table, tr td {
    border: 1px solid red
}
tbody {
    display: block;
    height: 50px;
    overflow: auto;
}
thead, tbody tr {
    display: table;
    width: 100%;
    table-layout: fixed;/* even columns width , fix width of table too*/
}
thead {
    width: calc( 100% - 1em )/* scrollbar is average 1em/16px width, remove it from thead width */
}
table {
    width: 400px;
}

If tbody doesn’t show a scroll, because content is less than height or max-height, set the scroll any time with: overflow-y: scroll;. DEMO 2


<editS/updateS> 2019 – 04/2021


  • Important note: this approach to making a table scrollable has drawbacks in some cases. (See comments below.) some of the duplicate answers in this thread deserves the same warning by the way

WARNING: this solution disconnects the thead and tbody cell grids; which means that in most practical cases, you will not have the cell alignment you expect from tables. Notice this solution uses a hack to keep them sort-of aligned: thead { width: calc( 100% – 1em ) }

  • Anyhow, to set a scrollbar, a display reset is needed to get rid of the table-layout (which will never show scrollbar).

  • Turning the <table> into a grid via display:grid/contents will also leave a gap in between header and scrollable part, to mind about. (idem if built from divs)

  • overflow:overlay; has not yet shown up in Firefox ( keep watching it)

  • position:sticky will require a parent container which can be the scrolling one. make sure your thead can be sticky if you have a few rows and rowspan/colspan headers in it (it does not with chrome).

So far, there is no perfect solution yet via CSS only. there is a few average ways to choose along so it fits your own table (table-layout:fixed; is .. fixing table and column’s width, but javascript could probably be used to reset those values => exit pure CSS)

Leave a Comment