Skip to content

Keep API example line numbers in place when long lines scroll - #4843

Open
reakaleek wants to merge 10 commits into
mainfrom
fix-api-docs-code-scrollb-c24faa2b
Open

reakaleek wants to merge 10 commits into
mainfrom
fix-api-docs-code-scrollb-c24faa2b

Conversation

@reakaleek

@reakaleek reakaleek commented Nov 12, 2026 •

Copy link
Copy Markdown
Member

API example code now scrolls sideways under the same scrollbar as Markdown code blocks, and its line numbers and "Generated from the API spec" note stay in place while it scrolls.

Affects: API reference, Site UI

Prompt summary: Jan reports that the API example code blocks have no horizontal scrollbar, while Markdown code blocks have one. The ask is to make long lines as easy to reach as in a Markdown code block, without engineering more than that.

Why

The response and code-sample bodies set their own scrollbar thumb, --code-border (#373e47) on the #22272e code surface, which is close to invisible. Their ::-webkit-scrollbar rules never applied in Chrome, because the site sets scrollbar-width on every element. Once a long line scrolls, the line-number gutter scrolls out of view with the code, and so does the generated-sample note in a response. #4696 already stopped the request strip and the response from cutting off their scrollbars.

What

The site's scrollbar

The API code bodies drop their own scrollbar rules and take the site-wide thin bar that Markdown code blocks use, with the same thumb colour. With a mouse or "always show scrollbars", the bar is always visible. With a trackpad on macOS it appears while scrolling, as it does in Markdown code blocks.

Line numbers and notes that stay put

The line-number gutter is position: sticky with an opaque fill, and .code-lines is as wide as its longest line, so the gutter stays at the left all the way across. The space after the numbers moved into the gutter, so the gap stays the same while the code scrolls under it.

The "Generated from the API spec" note in a response stays at the bottom right of the visible code too. It was sticky already, but its parent .example-media-body was only as wide as the visible code, and a sticky box cannot leave its parent. The media body now spans the full code width, and its non-code children (the note, a caption, a media header) size to the response panel, which is exactly the visible width.

In the full-screen preview the code is now at least 100 characters wide (min-width) rather than exactly 100 (width). A fixed width ended .code-lines at 100 characters, so the line numbers slid away on a longer line. Samples of 100 characters or fewer open the same dialog as before, and a longer line widens the dialog up to the window before it scrolls.

A browser test for it

ApiExampleScrollingTests in the journeys project opens a Cloud Connect operation in headless Chrome, scrolls the request and the response sideways with a wheel event, and checks that the code scrolled, the language stayed, and the line numbers and the note stayed in place. The jsdom carousel tests cannot see real layout, and a .journey file cannot compare positions. The tests run in their own api-examples shard. Closes #4847.

Out of scope: Components/Pages/ApiReference/api-reference.css and api-code.css, the design-system port that loads only with NAVIGATION_PREVIEW, keep their old rules. ArrowLeft and ArrowRight inside a card still switch the example language instead of scrolling the code.

Verify

mise run site:test
mise run journeys:test   # ApiExampleScrollingTests
mise run serve

Open /api/doc/cloud-connect/operation/operation-patchcluster and scroll the request and the 200 response sideways. The bar looks like the one on /syntax/code, the line numbers stay at the left, and the note stays at the bottom right.

Check on the preview

🤖 Generated with Claude Code

A global `* { scrollbar-width: thin }` in `styles.css` turns off Chrome's `::-webkit-scrollbar` styling. On macOS the API code cards fell back to an overlay bar that shows only while scrolling, so a mouse user had no bar to drag. The cards now opt back in with a 14px slot whose thumb shows on card hover and fills the slot under the pointer. The line-number gutter is sticky, so the numbers stay put while the code scrolls.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Docs preview (local build)

Handbook preview: https://docs-v3-preview.elastic.dev/elastic/docs-builder/pull/4843/

The gutter now paints its own background, so it no longer relies on the wrapper's fill.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The response height was the window minus a 26rem guess at everything above it. On pages where the request, chips or captions are taller than the guess, the response ran past the bottom of the sticky rail, and the rail clipped its horizontal scrollbar. Every box from the rail down to the response body now shrinks, so the response fills exactly what is left. A floor of four lines, or the whole response when shorter, keeps it readable; below that floor the rail scrolls as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
reakaleek and others added 3 commits November 12, 2026 22:30
The note is sticky, but in a response it sits in .example-media-body, which was only as wide as the visible code, and a sticky box cannot leave its parent. Scrolling a wide response sideways carried the note off with the code. The media body now spans the full code width, and its non-code children size to the response panel, which is exactly the visible width, so the note stays at the bottom right like the request note does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… review by Libra)

scrollHeight leaves out the 14px horizontal scrollbar a wide line adds, so a short wide sample came up 14px short and scrolled vertically by the bar's height.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ollb-c24faa2b

# Conflicts:
#	src/Elastic.Documentation.Site/Assets/api-docs.css
#	src/Elastic.Documentation.Site/Assets/api-examples-carousel.ts
…s (per review by Libra)

A fixed width: 100ch on the preview's code ended .code-lines at 100ch, so on a longer line the sticky gutter slid out of view. A min-width keeps the 100-character dialog for shorter samples and lets the dialog grow with a longer line up to the window.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The carousel tests run in jsdom, so nothing caught an invisible scrollbar or line numbers that scroll away. Two tests open a Cloud Connect operation in headless Chrome, drag the request's and the response's scrollbar, and check that the code scrolled, the language stayed, and the line numbers and the generated-sample note stayed in place. Chrome is started without --hide-scrollbars, which Browser.LaunchAsync always passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The journeys workflow fails when a test class is in no shard. ApiExampleScrollingTests waits for the isolated site to render its API specs, so it gets its own job instead of slowing the site shard.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The custom 14px bar answered a misdiagnosis: headless Chrome draws overlay scrollbars, which hid the bar in every probe. With classic scrollbars, main already shows the API cards' bar now that the strip and the response count it. The cards now take the site-wide thin bar Markdown code blocks use, which also drops the old thumb that was nearly invisible on the dark surface. The browser test scrolls with a sideways wheel instead of dragging the bar, so it needs no Chrome of its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@reakaleek reakaleek changed the title Make long API example lines easy to scroll sideways with a mouse Keep API example line numbers in place when long lines scroll Nov 13, 2026
@@ -2648,35 +2647,6 @@ a.docs-reference-btn::after {
box-shadow: none;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: P2 (Medium)

This revision drops all scrollbar styling for the API code bodies, including the reset of scrollbar-width/scrollbar-color to auto and the 14px ::-webkit-scrollbar slot. The cards now just use the global * { scrollbar-width: thin; … } from styles.css. That is the setup the PR description names as the cause of the bug: on macOS the cards still get an overlay bar that only appears while scrolling, so a mouse user still has nothing to drag. The PR title and description ('A scrollbar you can grab', '14px slot that is always reserved', Firefox @supports fallback) still promise this, but the code no longer does it. Either restore the scrollbar rules or update the title and description so they don't claim this fix.

Generated by Libra. Specialist: libra-complexity. React with 👍 or 👎 to give feedback on this comment.

Comment on lines +79 to +87
// A sideways wheel over the code, as a trackpad swipe or shift+wheel sends it.
await page.SendAsync("Input.dispatchMouseEvent", writer =>
{
writer.WriteString("type", "mouseWheel");
writer.WriteNumber("x", before.GetProperty("centerX").GetDouble());
writer.WriteNumber("y", before.GetProperty("centerY").GetDouble());
writer.WriteNumber("deltaX", 200);
writer.WriteNumber("deltaY", 0);
}).ConfigureAwait(false);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: P3 (Low)

Replacing the scrollbar drag with a horizontal wheel event removes regression coverage for the interaction this PR is meant to fix. A wheel event can scroll an overflow container even when no scrollbar is visible or draggable, so these tests can pass with the scrollbar styling entirely absent. Retain a real scrollbar-drag assertion, using a browser configuration that renders scrollbars, alongside the sticky-position checks.

Generated by Libra. React with 👍 or 👎 to give feedback on this comment.

This branch was successfully deployed

2 active deployments
docs-preview — 0a702ccd Deployed Nov 13, 2026 by github-actions[bot]
assembler-preview — 0a702ccd Deployed Nov 13, 2026 by github-actions[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cover API example sideways scrolling with a browser journey

1 participant