Skip to content

chat: wrap markdown tables with horizontal scrollbar#298604

Merged
roblourens merged 3 commits intomainfrom
roblou/markdown-table-scrolling
Mar 1, 2026
Merged

chat: wrap markdown tables with horizontal scrollbar#298604
roblourens merged 3 commits intomainfrom
roblou/markdown-table-scrolling

Conversation

@roblourens
Copy link
Copy Markdown
Member

Fixes #265062

Summary

Markdown tables in the chat panel can have many columns with wide content. Previously the table would overflow its container with no way to scroll, and short cell values like 001 would be aggressively squished to a single character wide.

Changes

Horizontal scrolling

  • Each rendered <table> is now wrapped in a DomScrollableElement so it scrolls horizontally using the VS Code custom scrollbar.
  • The table is placed inside an intermediate <div> first — passing a <table> directly to DomScrollableElement doesn't work because a table always expands to its content width, so clientWidth === scrollWidth and the scrollbar never appears.
  • A scanDomNode callback is registered as a layout participant so the scrollbar re-measures on resize.

Column min-widths

  • Per-column min-width is set (in ch units) based on the maximum textContent.length of any cell in that column, capped at 3ch. This prevents columns like 001 from being squeezed to one character wide while keeping the layout flexible for wide content.
  • Single-character columns are left alone (no min-width applied).
  • This is layout-free — only textContent lengths are read, causing no forced reflows.

Header wrapping

  • Table <th> cells now use white-space: normal + overflow-wrap: break-word instead of white-space: nowrap, so headers wrap at word boundaries rather than overflowing.

Refactoring

  • The wrapping logic is extracted into a new chatMarkdownTableScrolling.ts module.
  • Unit tests added in chatMarkdownTableScrolling.test.ts covering DOM structure, scroll wrapper class, layout participants, min-width capping, and multiple-table handling.

(Written by Copilot)

- Wrap each rendered markdown table in a DomScrollableElement so it
  scrolls horizontally with the VS Code custom scrollbar instead of
  the native one.
- Apply per-column min-width (in ch units, capped at 3ch) based on
  max text-content length, so short values like "001" aren't squeezed
  to a single character wide.
- Allow table headers to wrap at word boundaries (white-space: normal)
  rather than staying on a single line.
- Extract the wrapping logic into chatMarkdownTableScrolling.ts with
  unit tests in chatMarkdownTableScrolling.test.ts.

Fixes #265062

(Written by Copilot)
Copilot AI review requested due to automatic review settings March 1, 2026 21:25
@vs-code-engineering vs-code-engineering bot added this to the March 2026 milestone Mar 1, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds horizontal scrolling support for rendered markdown tables in the chat widget (using VS Code’s custom scrollbar) and improves table readability by preventing overly-squeezed short columns and allowing header text to wrap.

Changes:

  • Wrap rendered <table> elements in a DomScrollableElement scroll container and re-measure on resize via layout participants.
  • Apply per-column min-width (in ch, capped) derived from max cell text length to reduce aggressive column squishing.
  • Update chat CSS for the new wrapper and allow <th> wrapping; add unit tests for DOM wrapping + sizing behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/vs/workbench/contrib/chat/test/browser/widget/chatMarkdownTableScrolling.test.ts Adds unit tests covering wrapper DOM structure, resize participants, and min-width behavior across tables.
src/vs/workbench/contrib/chat/browser/widget/media/chat.css Styles the new scroll wrapper and adjusts table header wrapping behavior.
src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownTableScrolling.ts Introduces table wrapping + min-width computation logic for rendered markdown tables.
src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownContentPart.ts Integrates the new table-wrapping helper into markdown rendering.

@roblourens roblourens enabled auto-merge (squash) March 1, 2026 21:37
Instead of setting style.minWidth on every cell in the table (all rows ×
columns), only apply it to the first row. Column constraints propagate
naturally via CSS table layout, so this avoids unnecessary style mutations
for large tables.

(Written by Copilot)
@roblourens roblourens merged commit d63b8bd into main Mar 1, 2026
20 checks passed
@roblourens roblourens deleted the roblou/markdown-table-scrolling branch March 1, 2026 22:53
DonJayamanne pushed a commit that referenced this pull request Mar 2, 2026
- Wrap each rendered markdown table in a DomScrollableElement so it
  scrolls horizontally with the VS Code custom scrollbar instead of
  the native one.
- Apply per-column min-width (in ch units, capped at 3ch) based on
  max text-content length, so short values like "001" aren't squeezed
  to a single character wide.
- Allow table headers to wrap at word boundaries (white-space: normal)
  rather than staying on a single line.
- Extract the wrapping logic into chatMarkdownTableScrolling.ts with
  unit tests in chatMarkdownTableScrolling.test.ts.

Fixes #265062

(Written by Copilot)
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.

Markdown table rendering inconsistent between question and answer — column width too narrow in answers

3 participants