fix(editor): the viewport fills its slot, no reserved scrollbar gutters - #48
Closed
pythonlearner1025 wants to merge 1 commit into
Closed
pythonlearner1025 wants to merge 1 commit into
pythonlearner1025 wants to merge 1 commit into
Conversation
index.html asked every element for `scrollbar-gutter: stable`. In Chrome an `overflow: hidden` box is a scroll container, so each one kept 11 px for a scrollbar it can never show. The canvas lost 33 px to three nested panels and the Inspector lost 44 px to four nested boxes. The gutter now sits on the four boxes that really scroll: the Objects tree's tab panel, the Resources sections, the Files grid and the Inspector's panel stack view. The Resources tab brings its own scroll box, so the tab panel under it reserves nothing. The Inspector card drops `overflow-y: scroll`, which drew a permanent empty track beside the real scrollbar. At 1600x1000 the canvas goes from 913 in a 946 slot to 959 in a 959 slot, and the Inspector content from 260 to 309 against a 320 tab strip. Boxes that keep a gutter go from 65 to 3. The three scroll boxes keep the same gutter with short and long content: 11, 12, 11 both ways. Verified headless on Chrome at 1512x982 and 1600x1000, both themes, every panel collapsed and expanded, and a window resize. npm run typecheck, npm run lint, npm test -w packages/kite3d (10 tests), npm run test:scripts (2 tests).
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.
What part this touches
The editor screen is one row of panels.
WindowPanesLayoutbuilds it withreact-resizable-panels: a left slot, a center slot, a right slot, and a bottom slot inside thecenter. Each slot holds a Blueprint
Tabs, and each tab draws its content in a.bp5-tab-panel.The center slot's tab panel holds the 3D viewport canvas. The right slot's Inspector tab holds a
card, a Blueprint panel stack, and the stack's view, which is the box the Inspector rows scroll in.
react-resizable-panelsgives everyPaneland everyPanelGroupoverflow: hidden.packages/editor/index.htmlcarries a small style block for scrollbars. It styles the*selector,so it reaches every element on the page.
packages/uiconfig-blueprintis a workspace package. Itssrc/renderer.scssstyles the Inspectorcard and the panel stack.
packages/editor/src/renderer.scssimports it at line 1, and npm linksthe workspace, so the editor compiles that file from source into its own bundle.
The problem
The style block set
scrollbar-gutter: stableon*.In Chrome an
overflow: hiddenbox is a scroll container.stabletells a scroll container to keepthe scrollbar's width whether it shows a scrollbar or not. So every
overflow: hiddenbox in theeditor kept 11 px it could never use.
The canvas and every box above it, read in a headless Chrome at 1512 by 982 on the build before
this branch:
.editorCanvasContainer.window-panel-card.bp5-tab-panel.bp5-tabs.window-panels-tabs.center-top-panel#center-panel.editorSplitContainerhtmlThree panel levels each took 11 px. The owner saw the innermost one as a dark band to the right of
the canvas, 33 px wide. The root element took another 11 px from the window, so the whole layout was
1501 px wide in a 1512 px window, and the last 11 px painted white in the dark theme.
The Inspector lost more, because five boxes nest there. The same run, same viewport:
#right-panel.bp5-tab-panel.bpInspectorCard.inspector-stack.bp5-panel-stack2.bp5-panel-stack2-viewThe tab list above read 286.6 px and the content read 243 px, so the content was 44 px narrower than
the strip. Only the last box ever scrolls. The card also set
overflow-y: scroll, which paints atrack with nothing to scroll: that was the second, empty strip beside the real scrollbar.
The content was too narrow to fit its own rows, so the Inspector also scrolled sideways: the view
reported
scrollWidth284 againstclientWidth243.PR #33 fixed the center tab panel alone, with
scrollbar-gutter: auto. That is why the canvas wasnot narrower still.
The fix
packages/editor/index.htmldropsscrollbar-gutter: stablefrom the*rule. The rule keepsscrollbar-width,scrollbar-colorand the::-webkit-scrollbarsizing..hierarchy-stack, the left slot's tab panel, reserves one. The Objects tree scrolls in it..hierarchy-stack:has(.resources-panel)reserves none. The Resources tab brings its own scrollbox, so that tab panel never scrolls.
.resources-panelreserves one. The three resource sections scroll in it..files-panel-gridreserves one. The Files grid scrolls in it..bp5-panel-stack2-viewreserves one, inpackages/uiconfig-blueprint/src/renderer.scss. TheInspector rows scroll in it.
.bpInspectorCardchangesoverflow-y: scrolltoauto. It never scrolls, so it now paints notrack.
.center-top-panel > .window-panels-tabs > .bp5-tab-paneldropsscrollbar-gutter: autofromPR fix(editor): the center slot shows its tab strip #33. Nothing gives that box a gutter any more, so the line had no work left.
overflow: hidden. That line still works: withautoa PageDown scrolls thepanel 4 px and takes the canvas with it. I measured the canvas moving from y 81 to y 77.
The risk trade
The cost is that a gutter is now a decision per box, not a blanket. A future scroll box that wants
a stable gutter has to ask for one, or its content shifts 11 px when a scrollbar appears. What
lowers the cost: the four rules each say in one line why that box scrolls, and the acceptance run
counts every box that keeps a gutter, so a new one that does not scroll shows up as a number.
The Inspector still scrolls sideways at a 300 px panel: it needs 294 px against 289 px of room, so
5 px overflow. Before it needed 284 px against 245 px, so 39 px. The row that sets the floor is
Render Scale, a label with a slider and a number box. At a 306 px panel the overflow is gone. I did
not change any row's width, because that is inspector layout and not this bug.
Rejected alternative: put the gutter on
.editorSplitContainer .bp5-tabs > .bp5-tab-panel, whichis one rule instead of four. I measured the tab panels and rejected it. Only the left slot's tab
panel scrolls. The right slot's and the bottom slot's hold a scroll box of their own, so that rule
would keep the Inspector's 11 px loss and the Files panel's 11 px loss, which is the bug again.
uiconfig-blueprintis not published byscripts/release.mjs. Its two lines reach users throughthe editor bundle, which compiles the workspace source. A build that resolved
uiconfig-blueprint@0.1.0-dev.14from the registry instead of the workspace would not carry them.npm ciin this repo links the workspace, because the versions match.Tests
Headless Google Chrome 153, the owner's own binary, fresh profile, viewport 1512 by 982 and 1600 by
1000, device pixel ratio 2. The dev server ran with
CI=1and--no-openon port 4476, serving/Users/minjunes/games/terminator-next. I never rankite3d install. Nothing took focus. Zero pageerrors in every run.
I confirmed the served editor was my build. The sha256 of each served bundle matched
packages/editor/dist/assets:/private/tmp/claude-501/-Users-minjunes-blitz/278f5f97-7e16-4722-b1bc-c061014966db/scratchpad/evidence/canvas-gutter/served-is-my-build-final.txt.The acceptance table, same script both ways, at 1600 by 1000:
Two numbers need their definition stated. A box keeps a gutter when
offsetWidthminusclientWidthminus its borders is 8 px or more. Inside the right panel I count 5 before, because Icount the
#right-panelbox itself; a count that starts below it reads 4. Counting elements whosecomputed
scrollbar-gutteris notautois not a useful number before the change: the*rulegives every element
stable, so the count is the document's element count, 777 in my run. After thechange it is 3.
The one box that keeps a gutter without scrolling is the Objects tree's tab panel with the tree
collapsed. That is the point of a stable gutter: the rows keep their width as branches open.
The before column comes from the same page with the deleted rules put back with
addStyleTag. Ichecked that stand in against the real baseline build at 1512 by 982: canvas 860, slot 893, band 33,
Inspector content 243, tab strip 286.6, right panel 297.6, 65 boxes keeping a gutter. Every number
matched the build I measured before I touched anything.
Screenshots I looked at, all under
/private/tmp/claude-501/-Users-minjunes-blitz/278f5f97-7e16-4722-b1bc-c061014966db/scratchpad/evidence/canvas-gutter/shots/:before-full.pngandafter-full.png: the whole editor. The band beside the canvas is gone.before-canvas-right-edge-3x.pngandafter-canvas-right-edge-3x.png: the canvas's right edge atthree times size. Before, two thirds of the crop is flat panel colour. After, it is all 3D.
before-inspector.pngandafter-inspector.png: the Inspector panel. Before, the rows stop 44 pxshort and
terminator-nodeis cut. After, the rows reach the edge andterminator-node-mapfits.baseline-emulated-inspector-strips-4x.pngandafter-inspector-strips-4x.png: the right of theInspector at four times size. Before, two empty strips beside the content. After, one gutter.
before-inspector-right-edge-3x.pngandafter-inspector-right-edge-3x.png: before, a white 11 pxstrip runs down the window's right edge, which is the root element's reserved gutter.
after-resources-scrolled.png: the Resources tab scrolled 4000 px. The sticky section headersstill stick, at the panel's own width of 291 px.
after-tree-scrolled.png,after-1512-tree-long.png,after-files.png,after-light.png,after-resized.png,after-expand-all.png.The edges I ran, all after the fix:
The canvas matched its slot every time: 906 and 906, 1208 and 1208, 1510 and 1510. The render size
followed, 1812 by 1616 at device pixel ratio 2.
held
clientWidth291 in all three states.with a light picked, 957 px of rows, which does. The view kept 12 px both times and held
clientWidth309. Scrolled to 400 and back, the content did not move.dragged tall, 325 px of items in a 325 px box, which does not. The grid kept 11 px both times.
overflow-y: auto. It did not scroll in thisproject, 434 px of rows in a 434 px box, so it gets no gutter and I left it alone.
Suites, on the final tree:
npm run typecheckexit 0,npm run lintexit 0,npm test -w packages/kite3d5 files and 10 tests passed,npm run test:scripts2 tests passed.What fails without the fix: putting the six deleted declarations back on the running page, with
addStyleTag, moves the canvas from 959 to 913 in the same 946 slot, the band from 0 to 33 px, theInspector content from 309 to 260, and the boxes keeping a gutter from 3 to 65. That is the run in
acceptance-baseline-1600.jsonagainstacceptance-after-1600.json.No test was added. This is layout in a stylesheet, it did not flake across runs, and the proof is
the measured walkthrough above.
Deploy
The editor bundle ships it, through the next
kite3dnpm release.npm run buildcompilespackages/editor/index.html,packages/editor/src/renderer.scssand the workspace copy ofpackages/uiconfig-blueprint/src/renderer.scssintopackages/editor/dist/assets, andkite3d devserves that folder.
Rollback: the previous version on npm,
kite3d@0.21.0-alpha.6.npm install -g kite3d@0.21.0-alpha.6restores the editor with the blanket gutter.