15

I have a data table that needs to scroll vertically. It seems that if your display value is table, you cannot set a height or max-height, and so overflow-y:scroll does nothing. (Codepen with table)

.fake-table {
  display: table;
  max-height: 300px;
  overflow-y: scroll;
}

Also, if you remove the display:table from the parent but keep the display:table-row and table-cell, the width of the rows will not be 100%;

I tried instead doing this with flexbox (Codepen with flexbox). But of course, then I don't have nice columns that are left-justified.

.fake-table > * {
  display: flex;
  justify-content: space-around;
}

Browser support is all modern browsers (IE10 +) including mobile safari and android browser.

Dr Ace
  • 153
  • 1
  • 1
  • 4
  • 1
    Can you wrap your `.fake-table` in a `div` with the `max-height` and `overflow-y` set? See this [codepen](http://codepen.io/anon/pen/JowWbV) – zgood Mar 19 '15 at 21:55
  • Do you want your table headers to stay static? Because that has an answer here: http://stackoverflow.com/questions/17584702/how-to-add-a-scrollbar-to-an-html5-table – Heretic Monkey Mar 19 '15 at 22:11

3 Answers3

21
  • It seems that if your display value is table, you cannot set a height or max-height

    Effectively, the spec says (max-height):

    In CSS 2.1, the effect of 'min-height' and 'max-height' on tables, inline tables, table cells, table rows, and row groups is undefined.

    And you can use the height property, but it will be treated as a minimum height, and thus won't produce overflow (Table height algorithms):

    The height of a table is given by the 'height' property for the 'table' or 'inline-table' element. A value of 'auto' means that the height is the sum of the row heights plus any cell spacing or borders. Any other value is treated as a minimum height.

  • Also, if you remove the display:table from the parent but keep the display:table-row and table-cell, the width of the rows will not be 100%

    In this case, since there is no tabular container, an anonymous one is generated (Anonymous table objects):

    Document languages other than HTML may not contain all the elements in the CSS 2.1 table model. In these cases, the "missing" elements must be assumed in order for the table model to work. Any table element will automatically generate necessary anonymous table objects around itself

    But that anonymous table won't necessarily be as wide as .fake-table.

  • I tried instead doing this with flexbox

    Flexbox is a bad choice because it has no grid notion.

    Maybe CSS Grid would be better, but it's currently experimental and only IE10 supports it (an older version of the spec, tough).

Basically, you have two options:

  • Fixed column width approach

    If you predefine the width of the columns, the result will be a grid, even if you don't use tabular/grid displays.

  • Non-tabular to wrapper

    You can wrap your table inside a dummy (non-tabular) element, and set overflow and max-height to that element.

Oriol
  • 274,082
  • 63
  • 437
  • 513
  • 2
    I think wrapping the `table` in a `div` and giving that a `max-height` is the best solution since grid layout is only supported in IE. – Dr Ace Mar 20 '15 at 23:15
3

Wrap your .fake-table in a div?

CodePen

Also, it is 100% acceptable to use actual <table>'s for displaying tabular data... actually it's preferred. Its using tables for layout when things get hairy.

zgood
  • 12,181
  • 2
  • 25
  • 26
  • This page has two layouts that are controlled by CSS. One is the "tile" layout and one is the "table" layout, so the same html needs to work for both layouts. – Dr Ace Mar 20 '15 at 22:01
0

This addition worked for me:

table {
  width: 100%;
}
.example-container {
  height: 400px;
  max-width: 100%;
  overflow: auto;
}

Just set a container for your table, make it scrollable and fix its size, and limit its width, to prevent horizontal scroll.

I would like to give credit to Hardik Savani, who wrote the solution & explanation here.

DGR
  • 422
  • 1
  • 4
  • 14