Sticky header scrolls out of view when collapsing file sections in a diff/code review viewer. CSS scroll anchoring spec explicitly excludes `position: sticky` elements from being anchor candidates, so the browser cannot automatically keep the sticky file header visible when content below it collapses. Tried CSS-only approaches: grid-template-rows transitions, content-visibility, overflow-anchor — none work because of the sticky exclusion in the spec.
Use native HTML <details>/<summary> elements for file sections (same approach as GitHub PR diffs). The <summary> becomes the sticky file header, the body content sits inside the <details>.
Key pieces:
- CSS
scroll-margin-topon the<details>container to account for any fixed/sticky app header above:
.file-section { scroll-margin-top: 49px; }
- Remove default
<summary>disclosure triangle:
summary.file-header { list-style: none; }
summary.file-header::-webkit-details-marker { display: none; }
- Intercept click on
<summary>BEFORE the native toggle to fix scroll position before content disappears (prevents flicker). Then manually close:
header.addEventListener('click', function(e) {
if (section.open) {
e.preventDefault();
if (section.getBoundingClientRect().top < 0) {
section.scrollIntoView({ behavior: 'instant' });
}
section.open = false;
}
// Expanding: let native <details> handle it
});
The scroll correction happens while content is still visible (no flicker), then section.open = false collapses it. For expanding, the native <details> behavior works fine without intervention.
This is the same pattern used by GitHub (js-details-target) and Gitea (PR #23702). Pure CSS cannot solve this because the scroll anchoring spec excludes sticky elements.