Skip to content

feat(layout): lay out display:table, table-row and table-cell - #33

Open
leshchenko1979 wants to merge 1 commit into
Macawls:mainfrom
leshchenko1979:fix/table-layout
Open

leshchenko1979 wants to merge 1 commit into
Macawls:mainfrom
leshchenko1979:fix/table-layout

Conversation

@leshchenko1979

Copy link
Copy Markdown
Contributor

Fixes #28.

Problem

display: table was parsed and stored but had no consumer anywhere in layout/: the display enum had no table/table-row/table-cell values, ParseDisplay defaulted everything to block, tagDefaults had no UA defaults for table/tr/td/th, and there was zero table code. Every cell was laid out as a block child, so a three-column table stacked its cells vertically.

Measured against Chromium on a 21-case harness (% of pixels differing by more than 32 per channel):

case before after
08-table 5.15 % 0.09 %
18-table-tr-row2 8.10 % 0.13 %
17-table-div 1.20 % 1.20 % (uses flex, unaffected)

What this adds

Four display values (table, table-row, table-row-group, table-cell) with their UA defaults for table/thead/tbody/tfoot/tr/td/th (th also font-weight: 700), plus a table layout pass in layout/table.go:

  • columns — an explicit cell width is that column's preferred width; a column without one takes its cells' max-content width; the total is scaled down proportionally when it overflows the table, and the slack is shared equally when it does not. That is what a browser's auto table layout converges to for the markup people actually write.
  • rows — stacked vertically, each as tall as its tallest cell.
  • row groups — thead/tbody/tfoot are transparent for layout.
  • height — a table's height is the sum of its rows, never the definite height the flex pass hands down. In CSS a table never stretches, and adopting that height pushed every sibling below it out of place.
  • cell offsets — relative to the row. Storing the absolute y on both the row and the cell made the renderer add the row offset twice, so every row after the first landed one row-height too low.
  • main axis — rows are mapped to a horizontal main axis so the intrinsic-size estimator maxes its cells instead of summing them; otherwise an auto-height wrapper around a table came out twice as tall as the table.

Tests

layout/table_test.go, 7 tests: cells side by side, auto columns sharing the slack, rows stacking and sizing to the tallest cell, the table ignoring a definite container height, an explicit height still winning, row groups being transparent, and display: none cells not consuming a column. Two of them (cell-offset relativity and the auto-height wrapper) were verified to fail on the pre-fix code.

go test ./... and go vet ./... pass. Existing golden SVGs are unchanged.

Not implemented

table-layout: fixed, border-collapse, rowspan, colspan. The cases above need none of them, and guessing at border-collapse would change the geometry of every bordered table.

Ogre parsed `display: table` but had no table layout at all: every row and
cell was laid out as a block, so a three-column table stacked its cells
vertically and a table inside an auto-height wrapper reported twice its real
height.

Add the four display values, their UA defaults for table/thead/tbody/tfoot/
tr/td/th, and a table layout pass in layout/table.go:

  - columns: an explicit cell width is the column's preferred width, a column
    without one takes its cells' max-content width, and the result is scaled
    down proportionally when it overflows the table or given an equal share of
    the slack when it does not - which is what a browser's auto table layout
    converges to for the markup people actually write;
  - rows: stacked vertically, each as tall as its tallest cell;
  - row groups (thead/tbody/tfoot) are transparent for layout;
  - a table's height is the sum of its rows, never the definite height the
    flex pass hands down, exactly as in CSS;
  - cell offsets are relative to their row, so the renderer does not add the
    row offset twice;
  - rows are mapped to a horizontal main axis, so the intrinsic-size estimator
    maxes its cells instead of summing them.

Against Chromium, on the 21-case comparison harness:

  08-table            5.15% -> 0.09%
  18-table-tr-row2    8.10% -> 0.13%
  17-table-div        1.20% -> 1.20% (unaffected, it uses flex, not table)

Not implemented: table-layout: fixed, border-collapse, rowspan, colspan.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

table layout not implemented: tr/td stack vertically, tr background covers wrong area

1 participant