123

I have a table with many rows on my page. I would like to set table's height, say for 500px, such that if the height of the table is bigger than that, a vertical scroll bar will appear. I tried to use CSS height attribute on the table, but it doesn't work.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Misha Moroshko
  • 166,356
  • 226
  • 505
  • 746

5 Answers5

207

Try using the overflow CSS property. There are also separate properties to define the behaviour of just horizontal overflow (overflow-x) and vertical overflow (overflow-y).

Since you only want the vertical scroll, try this:

table {
  height: 500px;
  overflow-y: scroll;
}

EDIT:

Apparently <table> elements don't respect the overflow property. This appears to be because <table> elements are not rendered as display: block by default (they actually have their own display type). You can force the overflow property to work by setting the <table> element to be a block type:

table {
  display: block;
  height: 500px;
  overflow-y: scroll;
}

Note that this will cause the element to have 100% width, so if you don't want it to take up the entire horizontal width of the containing element, you need to specify an explicit width for the element as well.

Lee Goddard
  • 10,680
  • 4
  • 46
  • 63
AgentConundrum
  • 20,288
  • 6
  • 64
  • 99
  • 4
    This doesn't limit the height though. – Fred Dec 16 '10 at 03:58
  • @Fred: I thought it was implied, but you're right. I've added an explicit `height` property to my example. – AgentConundrum Dec 16 '10 at 04:02
  • 8
    No, it does, you just need `display:block` on the table to make it behave like a `div` http://jsfiddle.net/TSGSA/1/ – Fred Dec 16 '10 at 04:11
  • @Misha: This seems to be because tables arent block elements. See my edit. – AgentConundrum Dec 16 '10 at 04:14
  • 3
    This answer really helped me, but instead of applying it to the table tag, it should be done to the tbody, in order to allow the header to remain static when scrolling. Then there's some styling to sort out with regard to the area in the thead that is above the scroll bar. – David Oct 09 '12 at 01:02
  • @Derek - I know this is incredibly late, but I just saw this (got some rep on it and remembered it existed). It looks like you can fix this by setting the CSS on the `tbody` and including `position:absolute` (you may need to set the table element itself to `position:relative` to anchor the tbody so it doesn't get rendered in a weird spot). It looks like you'll need to explicitly set the width to 100% to match the original answer. I just played with this for like 5 minutes in an IETester (IE9 only), so it may not be complete and it may not work correctly on *actual* IE9 or at all on IE8. – AgentConundrum Jan 08 '14 at 05:06
  • @Derek Here's the updated fiddle. Let me know if it works and I'll update the answer. I'll try to test it properly tomorrow. http://jsfiddle.net/TSGSA/113/ – AgentConundrum Jan 08 '14 at 05:13
  • 7
    If you're going to use this on the tbody, make sure you add the display:block to the thead (and probably tfoot) or they could go a little crazy. The problem, it seems, is that once you do this, you've broken the link between the thead and tbody: columns of the former aren't aware of the width of the latter. So you patch that and down the slippery slope you go. "I died for beauty..." – Cuse70 Jun 20 '14 at 00:23
  • For some reason Chrome needs a ` `, or it ignores the `overflow`. – bryc Mar 15 '15 at 08:13
71

You need to wrap the table inside another element and set the height of that element. Example with inline css:

<div style="height: 500px; overflow: auto;">
 <table>
 </table>
</div>
Dark Falcon
  • 43,592
  • 5
  • 83
  • 98
  • 9
    This won't allow for keeping the thead in place while the tbody scrolls. – David Oct 09 '12 at 01:00
  • 24
    This requirement is not in the original question. – Dark Falcon Oct 09 '12 at 12:08
  • 3
    Also, the other (accepted) answer doesn't keep the thead in place either. – Brock Adams Dec 24 '12 at 21:08
  • You can still make there appear to be a header in place with this method. You hide the table's header, then create a second table above the first table that has the header in it. Then, style both tables to have `display:table;` their rows to have `display:table-row;` and their cells to have `display:table-cell;` and the two tables will match up and appear to be one. (NOTE: this doesn't work with very large tables; basically, it matches them up when it can. I've used this technique multiple times.) – levininja Feb 27 '14 at 17:59
  • Is there a way to do this with percentage height? I don't want to use a fixed pixel height when the rest of the page is responsive, but this method only seems to work with fixed height. I've specified the maximum height of each TD and TR in pixels in an attempt to remove any circular dependency in size calculation but still no joy. – Desty Mar 20 '14 at 13:26
  • 1
    Sure. The parent's size must be specified to use relative sizes. For example: http://jsfiddle.net/hz8wy/ – Dark Falcon Mar 20 '14 at 13:35
  • @DarkFalcon: Thanks! Does this mean everything going back to the root element (the tag) must have a manually specified "height=100%", for example? I tried this and it indeed limits the table size -- in fact it squashed it into a tiny scrollable box, perhaps because I had left things like "height=4%" in various DIVs for testing and forgot about them because they had no effect. Hopefully we can force a percentage size for the table (or its parent div) without having to restrict and specify the sizes of all ancestors as that would be cumbersome :D – Desty Mar 20 '14 at 13:47
  • Yes, to my knowledge any element which uses a relative size must have a parent which has an explicit size specified. If that parent is relative-sized, its parent must also have a size, all the way up to the `html` element. For practical purposes, the `html` element's parent can be considered to be the window, which has a non-relative size. – Dark Falcon Mar 20 '14 at 13:52
10

None of those solutions worked. However, I grabbed the flex solution of Bootstrap and it worked

table, td {
  border: 1px solid black;
}
th {
  border-left: 1px solid black;
}

table {
  border-collapse: collapse;
  width: 100%;
}

table {
    display: flex;
    flex-flow: column;
    width: 100%;
    height: 400px;
    
}

thead {
    padding-right: 13px;
    flex: 0 0 auto;
}

tbody {
    flex: 1 1 auto;
    display: block;
    overflow-y: auto;
    overflow-x: hidden;
}

tr {
    width: 100%;
    display: table;
    table-layout: fixed;
}
<table>
<thead>
  <tr>
    <th>Firstname</th>
    <th>Lastname</th>
    <th>Savings</th>
  </tr>
  </thead>
  <tbody>
  <tr>
    <td>Peter</td>
    <td>Griffin</td>
    <td>$100</td>
  </tr>
  <tr>
    <td>Lois</td>
    <td>Griffin</td>
    <td>$150</td>
  </tr>
  <tr>
    <td>Joe</td>
    <td>Swanson</td>
    <td>$300</td>
  </tr>
  <tr>
    <td>Cleveland</td>
    <td>Brown</td>
    <td>$250</td>
  </tr>
    <tr>
    <td>Peter</td>
    <td>Griffin</td>
    <td>$100</td>
  </tr>
  <tr>
    <td>Lois</td>
    <td>Griffin</td>
    <td>$150</td>
  </tr>
  <tr>
    <td>Joe</td>
    <td>Swanson</td>
    <td>$300</td>
  </tr>
  <tr>
    <td>Cleveland</td>
    <td>Brown</td>
    <td>$250</td>
  </tr>
    <tr>
    <td>Peter</td>
    <td>Griffin</td>
    <td>$100</td>
  </tr>
  <tr>
    <td>Lois</td>
    <td>Griffin</td>
    <td>$150</td>
  </tr>
  <tr>
    <td>Joe</td>
    <td>Swanson</td>
    <td>$300</td>
  </tr>
  <tr>
    <td>Cleveland</td>
    <td>Brown</td>
    <td>$250</td>
  </tr>
    <tr>
    <td>Peter</td>
    <td>Griffin</td>
    <td>$100</td>
  </tr>
  <tr>
    <td>Lois</td>
    <td>Griffin</td>
    <td>$150</td>
  </tr>
  <tr>
    <td>Joe</td>
    <td>Swanson</td>
    <td>$300</td>
  </tr>
  <tr>
    <td>Cleveland</td>
    <td>Brown</td>
    <td>$250</td>
  </tr>
    <tr>
    <td>Peter</td>
    <td>Griffin</td>
    <td>$100</td>
  </tr>
  <tr>
    <td>Lois</td>
    <td>Griffin</td>
    <td>$150</td>
  </tr>
  <tr>
    <td>Joe</td>
    <td>Swanson</td>
    <td>$300</td>
  </tr>
  <tr>
    <td>Cleveland</td>
    <td>Brown</td>
    <td>$250</td>
  </tr>
    <tr>
    <td>Peter</td>
    <td>Griffin</td>
    <td>$100</td>
  </tr>
  <tr>
    <td>Lois</td>
    <td>Griffin</td>
    <td>$150</td>
  </tr>
  <tr>
    <td>Joe</td>
    <td>Swanson</td>
    <td>$300</td>
  </tr>
  <tr>
    <td>Cleveland</td>
    <td>Brown</td>
    <td>$250</td>
  </tr>
    <tr>
    <td>Peter</td>
    <td>Griffin</td>
    <td>$100</td>
  </tr>
  <tr>
    <td>Lois</td>
    <td>Griffin</td>
    <td>$150</td>
  </tr>
  <tr>
    <td>Joe</td>
    <td>Swanson</td>
    <td>$300</td>
  </tr>
  <tr>
    <td>Cleveland</td>
    <td>Brown</td>
    <td>$250</td>
  </tr>
  </tbody>
</table>
eneski
  • 1,575
  • 17
  • 40
3

This CSS also shows a fixed height HTML table. It sets the height of the HTML tbody to 400 pixels and the HTML tbody scrolls when the it is larger, retaining the HTML thead as a non-scrolling element.

In addition, each th cell in the heading and each td cell the body should be styled for the desired fixed width.

#the-table {
  display: block;
  background: white; /* optional */
}

#the-table thead {
  text-align: left; /* optional */
}

#the-table tbody {
  display: block;
  max-height: 400px;
  overflow-y: scroll;
}
Stephen Reed
  • 137
  • 7
1

to set the height of table, you need to first set css property "display: block" then you can add "width/height" properties. I find this Mozilla Article a very good resource to learn how to style tables : Link

Community
  • 1
  • 1
krupesh Anadkat
  • 1,932
  • 1
  • 20
  • 31