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)
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.
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).
A few thoughts:
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.