Fix frozen rows layout by restoring line break separator#4902
Merged
Conversation
Reproduces the regression where freezing a row no longer pins it above the scrollable body. PR #4809 removed the <br> that separated the inline-block frozen-rows-holder from the column headers; without it the holder collapses next to the headers and the frozen row is no longer visible at the top. Adds one unit test (initialize() inserts a <br> before topElement) and two integration tests using TabulatorFull that assert the rendered holder's previousSibling is a <br>, covering both row.freeze() and the frozenRows table option.
PR #4809 removed the <br> that the FrozenRows initializer used to insert between the column headers and the frozen-rows-holder, and tried to replace it with padding-top: 1em on the holder. That doesn't work because both .tabulator-headers and .tabulator-frozen-rows-holder are display: inline-block, so without a line break the holder sits next to the headers instead of below them, and frozen rows are no longer visible at the top of the table. Restore the <br> and drop the unused padding-top.
Codify the practice of dropping the issue URL alongside both the code that fixes the bug and the regression test that covers it, so future readers can trace any line back to the original report. Also apply the convention retroactively to the FrozenRows #4871 fix.
Add repo layout, common commands, testing patterns (pure-unit vs TabulatorFull integration, the createDocumentFragment / Module prototype pollution gotcha, jsdom layout caveat), and build notes alongside the existing bug-fix issue link convention.
…4871) jsdom can't observe layout, so the unit tests only verify the structural fix (presence of the <br> separator). This Playwright spec loads a 50-row table with frozenRows: 1 in a real browser and asserts: - the frozen row is laid out at the same x as the body (with the bug it's pushed ~1200px to the right of the inline-block headers and clipped by the header's overflow:hidden, which is what the user reported as "the row is not frozen") - scrolling the body actually moves the body rows - the frozen row's screen position is unchanged after scrolling Verified the test passes with the fix and fails without it (the left- edge assertion catches the off-screen layout: expected <5, got 1224).
azmy60
approved these changes
Jun 30, 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.
Fix #4871
Summary
Restores the
<br>element that was removed in PR #4809 between the column headers and the frozen rows holder. This separator is necessary for correct layout when both elements aredisplay: inline-block.Changes
fragment.appendChild(document.createElement("br"))ininitialize()with updated comment explaining why it's needed for inline-block layoutpadding-top: 1emworkaround that was added in PR SASS upgrade - and extra header row removed #4809, as it was an incomplete fix for the layout issue<br>separator is present in the DOMrow.freeze()andfrozenRowsoption initialization pathsImplementation Details
The frozen rows holder and column headers are both
display: inline-blockelements. Without a structural separator between them, the holder collapses inline with the headers instead of rendering on a new line below them. This caused frozen rows to be clipped and not appear pinned above the scrollable body.The
<br>element forces the inline-block holder onto its own row, restoring the correct visual layout. The padding-top workaround was insufficient because it didn't address the underlying inline-block layout issue.Tests cover the fix at three levels:
https://claude.ai/code/session_01U9KrvQH7MRRQ6Z2xShhuKb