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).
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.