Repository navigation
Fix notebook preview header hidden by website header - #15017
Merged
Merged
Conversation
Collaborator
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
On a website with a navbar, the notebook preview page has two fixed-top bars: the site's #quarto-header and the preview's #quarto-embed-header. The site navbar paints over the preview bar, hiding the back link, the notebook title and the download link (#14972). The test checks that each of those controls is the topmost element at its center. It fails on current main ("back link is covered by another element"). The fixture uses stored notebook outputs so no kernel is needed in CI.
On a website, the notebook preview page carries two fixed-top bars: the site's #quarto-header and the preview's #quarto-embed-header. Both sit at top: 0 and the site header paints over the preview bar, hiding the back link, notebook title and download link (#14972). The notebook view postprocessor now moves #quarto-embed-header into #quarto-header as its last child and drops the bar's own fixed-top and headroom classes. The site navigation script already sizes the body offset from the header height (ResizeObserver) and runs Headroom on the whole header, so the embed template's inline script skips its own padding and Headroom setup in that case. Same placement approach as the draft alert and dashboard navigation, which also insert into #quarto-header. Pages without a site header (standalone documents, manuscripts) keep the bar fixed at the top as before.
The site header (#quarto-header) exists whenever a website has a navbar, a sidebar (its collapsed toggle bar on narrow screens) or an announcement, so the notebook preview header must stay uncovered in each case. A standalone document has no site header and keeps the preview bar fixed at the top; that path is checked too. Each case also checks that the first notebook cell starts below the header, so content is offset by the stacked header height.
The notebook preview bar holding the back link, notebook title and download link was a plain <div>, outside every landmark on pages without a site header, so screen reader users could not reach it through landmark navigation, and axe reported it under `region` (#14968). The bar is now a <nav> labelled by its own notebook title heading via aria-labelledby, so the landmark carries the notebook name without a new localized string. It is a <nav> rather than a <header> because on websites the bar sits inside #quarto-header, which is already the page banner.
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.
On a website with a navbar, the notebook preview page (the
*-preview.htmlbehind an embedded notebook's source link) has two fixed-top bars: the site's#quarto-headerand the preview's#quarto-embed-header. Both sit attop: 0with the same z-index, and the site header comes later in the DOM, so it paints over the preview bar and hides the back link, the notebook title and the download link. The overlap has been there since notebook previews were introduced. The same happens with a sidebar (its collapsed toggle bar) or an announcement bar.The overlap can't be fixed in CSS alone because the two bars don't know about each other's height:
quarto-nav.jsoffsets the body by the site header height, while the embed template's inline script pads the content by the preview bar height only.Fix
The notebook view postprocessor now moves
#quarto-embed-headerinto#quarto-headeras its last child and drops the bar's ownfixed-topandheadroomclasses. The site navigation script already sizes the body offset from the header height (ResizeObserver) and runs Headroom on the whole header, so the embed template's inline script skips its own padding and Headroom setup in that case. This is the same placement approach as the draft alert and the dashboard navigation, which also insert into#quarto-header.Pages without a site header (standalone documents, manuscripts) keep the bar fixed at the top as before.
Two alternatives were rejected: offsetting the two fixed headers separately, which fights Headroom's pin/unpin on each bar, and hiding the site navbar on previews, which loses site navigation.
Navigation landmark
The preview bar was a plain
<div>, outside every landmark on pages without a site header, so screen reader users could not reach it through landmark navigation and axe reported it underregion. It is now a<nav>labelled by the notebook title heading througharia-labelledby, so the landmark carries the notebook name without a new localized string. It is a<nav>rather than a<header>because on websites the bar sits inside#quarto-header, which is already the page banner.Both changes touch the same element and template, so they go together here.
The CSS workaround suggested on #14972 is no longer needed once this lands.
Fixes #14972, fixes #14968
Checklist
I have (if applicable):
AI-assisted PR
Note: autonomous AI agents submitting PRs without human oversight are not permitted — see the Code of Conduct.