Skip to content

(sidebar): size the sidebar to its container, not the window - #306

Merged
jbr-sekoia merged 1 commit into
mainfrom
fix/sidebar-overflows-its-container
Sep 18, 2026
Merged

jbr-sekoia merged 1 commit into
mainfrom
fix/sidebar-overflows-its-container

Conversation

@jbr-sekoia

Copy link
Copy Markdown
Collaborator

The defect

#sidebar and #sidebar-resize-handle were height: 100vh. Their parent #app-container is a flex child of body that shares the window with the 22px #status-bar, so both were 22px taller than the box holding them.

Measured in a running instance: #app-container reported clientHeight: 1078, scrollHeight: 1100 and scrollTop: 22, with the sidebar's first row at getBoundingClientRect().top === -22 — the top row of toolbar icons scrolled above the viewport and was clipped. #app-container is overflow: hidden, so no scrollbar exists and the user cannot scroll back; the clipping persists until the window reloads. Setting scrollTop = 0 from the console restores it. Any focus or scrollIntoView on an element below the fold triggers it; it happened twice unprompted in a 30-minute session.

The fix

Both rules use height: 100%, which resolves against #app-container instead of the window. #app-container's own sizing is untouched — the status bar's 22px strip is deliberate.

Only .jsonl-screenshot-fullscreen img's max-height: 95vh still uses a viewport unit, on a position: fixed; inset: 0 overlay that is pinned to the viewport by design and is not laid out inside #app-container.

How it is pinned

test/app-container-viewport-height-css.test.js asserts the property rather than the literal value: it reads every (min-/max-)height declaration in style.css whose value reaches 100vh, resolves each rule's selector against public/index.html with jsdom, and fails if any match lands inside #app-container. A second test pins the premise the invariant rests on — #status-bar is a sibling of #app-container with a fixed pixel height, and #app-container is overflow: hidden, so overflow cannot be scrolled back.

Mutation-checked: restoring height: 100vh on #sidebar alone fails the test, and on both rules the failure names both selectors.

Checks

  • npx eslint . — 0 errors, 333 warnings (identical to the count on c939748 in this worktree).
  • npm test — stage 1: 1903 tests / 1900 pass / 1 fail / 2 skipped; stage 2: 120 / 119 / 0 fail / 1 skipped. The single failure is the pre-existing environmental one, test/ipc-path-validator.test.js "allows files under ~/.claude/".

#sidebar and #sidebar-resize-handle were 100vh, but their parent
#app-container is the window minus the 22px #status-bar, so both were
22px taller than the box holding them. Any focus or scrollIntoView below
the fold made the browser scroll #app-container by exactly that overflow
(clientHeight 1078, scrollHeight 1100, scrollTop 22), clipping the top
row of sidebar icons; #app-container is overflow: hidden, so there is no
scrollbar to scroll back and the clipping survives until a reload.

A container-relative height leaves nothing inside #app-container sized
to the viewport. The new CSS source test pins that for the whole file:
it reads every (min-/max-)height declaration reaching 100vh and fails if
its selector matches an element under #app-container in index.html.

@devsuitup devsuitup left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Reviewed a4a0c5d. The CSS fix is right: html,body {height:100%}, body flex column, #app-container {flex:1; min-height:0; overflow:hidden} gives the container a definite height, so 100% on #sidebar / #sidebar-resize-handle resolves instead of collapsing; the only remaining vh is the fixed fullscreen overlay, out of the container by design. CI green, no trailers.

One thing in the test, which is the PR's stated deliverable: selectorOf (test/app-container-viewport-height-css.test.js:31-34) takes only the last physical line before {. With the multi-line grouped selectors that dominate style.css (25+ groups), a future

#sidebar,
#unrelated {
  height: 100vh;
}

is checked as #unrelated only and passes green — reproduced. Build the selector list from the whole head (head.trim().split(',')) rather than its last line; then a mutation grouping #sidebar with another selector must go red. Note, not an ask: the test resolves against the static index.html, so runtime-created elements are outside its reach — fine today, worth one line in the test header.

Approving on the fix; please land the selectorOf change before merge so the guarantee matches the description.

@jbr-sekoia
jbr-sekoia merged commit cb4a0a3 into main Sep 18, 2026
10 checks passed
@jbr-sekoia
jbr-sekoia deleted the fix/sidebar-overflows-its-container branch September 18, 2026 16:55
@jbr-sekoia jbr-sekoia mentioned this pull request Sep 18, 2026
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.

2 participants