Skip to content

Instantly share code, notes, and snippets.

@FremyCompany
Last active April 23, 2016 06:42
Show Gist options
  • Save FremyCompany/5f0d45cad2a5bbd8b9f5ffb6e0c578d4 to your computer and use it in GitHub Desktop.
Save FremyCompany/5f0d45cad2a5bbd8b9f5ffb6e0c578d4 to your computer and use it in GitHub Desktop.
Table height distribution -- ideas

Computing the table height

The height of a table is the largest of:

  • The specified height of the table (percentages are resolved against ancestors as usual)
  • The height required for the rows and the vertical border-spacings. For each row, the largest of:
  • The row’s specified height if it is defined in non-percentages units (0 otherwise)
    • Also the eventual rowgroup specified size, using the usual splitting among tracks
  • The height deemed necessary to render all its cells when running the same algorithm that is being used to compute a column min-width, where the min-height of a cell is the largest of:
    • The cell’s specified height if it is defined in non-percentages units (0 otherwise)
    • The height of the cell border and padding plus the scrollHeight of its content layouted as if:
      • the cell height was set to 0px and overflow was set to hidden,
      • percentage heights are resolved as “auto” on elements where overflow-y is visible and as 0px on those where overflow-y is hidden or scroll (if they are relative to the cell height)

Distributing the height to rows

If for some reason the specified height of the table won, height distribution will have to happen.

  • The first step is to attribute to each row its base size and its reference size.
  • Its base size is the size it would have got if the table didn’t have a specified height.
  • Its reference size is the largest of
    • its initial base height and
    • its new base height (where percentages used in rowgroups/rows/cells' specified heights are now resolved according to the table height, instead of being ignored as 0px).
  • If the table height is equal or smaller than sum of reference sizes, the final height of each row is the linear combination of the base and the reference size that yields the correct total height.
  • Else, if the table contains any “auto-height” row (that means, a row whose size is only determined by its content size and none of the specified heights), each non-auto-height row receives its reference size and auto-height rows receive their reference size plus some increment which is equal to the height missing to amount to the specified table height divided by the amount of such rows.
  • Else, rows receive their reference size plus some increment which is equal to the height missing to amount to the specified table height divided by the amount of rows.

Layout of the table contents

Once the height or each row and therefore of each cell is finally known, the content of each cell goes through layout for the second time if necessary (it is necessary if it contained heights defined as percentages, because those where ignored previously but can now be computed as fraction of the cell height, or if any element was absolutely positioned relatively to the bottom of the table cell).

Some test cases:

@dbaron
Copy link

dbaron commented Apr 23, 2016

A few thoughts:

  • Specified heights on cells should be applied to rows, not to cells. The CSS WG had an extensive discussion about this issue a few years ago and reached this conclusion, although Gecko hasn't updated yet.
  • The height needed for a row needs to consider vertical alignment of cells.
  • I think the "Layout of the table contents" section is one of the weird bits, and subject to some rather strange Web-compatibility constraints on what gets laid out again and what doesn't -- particularly in terms of which cells percentage heights work inside of and which they don't.

Note that I haven't attempted to review the "Distributing height to rows" section in any serious way. That's the hard part, although I'd note that I liked IE6's algorithm best, in particular, as to how it handled percentage heights on rows and cells. Last I looked, I thought the behavior of both Gecko and WebKit was pretty broken. But it's been a long time since I thought about it.

Also, the other caveat is that I know a lot less about table heights than widths, since I actually rewrote the table width calculation code in Gecko, but never did much for heights. I did once spend a few days planning to rewrite the height code, though.

@FremyCompany
Copy link
Author

Interesting, glad I took some time to get your feedback on this, and thanks for giving it a look.

Your point 1 was definitely my intention. I didn't consider at all vertical alignment of cells here (Point 2), as I did my experiments with values like center/top for which Point 1 was actually straightforward.

Solving this would require to divide this into three sections "before" / "after" / "over" the baseline. The height for a row would be the largest of "before+after" the baseline and "across" the baseline. Only content would matter in regards to "before" and "after" measurements, and specified values would only matter for "across", which would achieve the result we seem to both want. Relevant test case: https://jsfiddle.net/sjsagvLy/1/ vs https://jsfiddle.net/sjsagvLy/

I think Point 3 is not a real concern. Gecko has lot of cases where percentages do not work, but Chrome and Edge do not. There might be some cases where this causes compat issues, but I would argue not enough to warrant making this more complex than it should.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment