feat(table): support rowspan attribute on td/th#395
Merged
nicoburns merged 2 commits intoDioxusLabs:mainfrom Apr 20, 2026
Merged
feat(table): support rowspan attribute on td/th#395nicoburns merged 2 commits intoDioxusLabs:mainfrom
nicoburns merged 2 commits intoDioxusLabs:mainfrom
Conversation
Demonstrates the current broken behavior where <td rowspan=2> is rendered as span=1, causing cells in row 3 to overlap or shift unexpectedly.
The `<td rowspan=N>` / `<th rowspan=N>` attribute was ignored because `grid_row.end` was hardcoded to `span(1)`. This caused cells in later rows to overlap with or shift around rowspan cells from earlier rows. Fix: - Parse `rowspan` on cell nodes, clamped to [1, 65534] per HTML Standard. - Apply it to `grid_row` span. - Switch `grid_column.start` to `auto` so that cells use Taffy's grid auto-placement for column positioning. - Set `grid_auto_flow: RowDense` on the table root. The `dense` auto-flow is required because the default (sparse) flow holds a per-item secondary-axis cursor across rows in `place_definite_secondary_axis_item`. With sparse flow, a cell in row N+1 would start its column search after wherever the previous cell ended, rather than restarting from the first track of its own row. That makes it impossible to backfill columns left empty by rowspan cells from earlier rows. The `dense` branch resets the search to the first track for every item and so naturally skips columns occupied by rowspan cells (it still honors each cell's explicit grid_row so inter-row order is preserved). rowspan=0 is currently clamped to 1 rather than interpreted as "span to end of row group" as the HTML Living Standard specifies. Browser behavior for rowspan=0 is inconsistent and this PR focuses on the common case; deferring the spec-exact behavior as a follow-up.
Member
|
@mitsuru Could you rebase on top of latest That also ought to get the WPT tests running (and it would be good to see how this affects those). |
Member
|
Hmm... running the WPT locally it's causing 2 tests to fail and none to pass which is not great... Pass => Fail css/CSS2/tables/border-collapse-dynamic-cell-005.xht |
Member
|
Hmm... it definitely seems to help some tables on https://en.wikipedia.org/wiki/Walt_Disney_World |
nicoburns
approved these changes
Apr 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #394.
What
Add support for the
rowspanattribute on<td>/<th>, which waspreviously ignored (
grid_row.endwas hardcoded tospan(1)).How
Four changes in
packages/blitz-dom/src/layout/table.rs:rowspanattribute on table cells, clamped to[1, 65534]per the HTML Living Standard.grid_row.end(wasspan(1), nowspan(rowspan)).grid_column.starton each cell from an explicitline(col+1)toauto(), so Taffy handles column placement.grid_auto_flow: RowDenseon the table root style.Step 4 is load-bearing. With the default sparse row-flow,
place_definite_secondary_axis_itemkeeps a per-item secondary-axiscursor that carries across rows, so a cell in row N+1 starts its
column search from wherever the previous cell ended rather than from
the first track of its own row. That makes it impossible to backfill
columns freed up by rowspan cells from earlier rows.
The
densebranch resets the column search to the first track on everyitem. Each cell still honors its explicit
grid_row, so inter-rowordering is preserved; only the within-row column search is restarted
— exactly the behavior required for HTML table layout with rowspan.
Diff is 18 lines.
Testing
cargo test -p blitz-dom— all existing tests pass.examples/rowspan.html(added in the first commit of this PR) —renders identically to Chrome after the patch. Before the patch the
table is structurally broken (cell "6" collapses into column B,
column C in row 3 is empty).
rowspan-support-v0.2.x)to fulgur via
[patch.crates-io]. Its 497 unit testscontinue to pass and its rowspan fixture renders correctly as a PDF.
Follow-ups (not in this PR)
rowspan="0"is clamped to1rather than interpreted as"span to end of row group" per HTML Living Standard §4.9.11.
Browser behavior on the edge cases is inconsistent; happy to
layer spec-exact semantics in a follow-up.
rowspan-support-v0.2.xif a 0.2.x point release is on the cards.