a11y: notebook preview header is outside any landmark
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 1/5
- Estimated time
- Under an hour
- Newbie friendliness
- 90/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- html
- Domain
- accessibility
Research direction
Start with src/resources/formats/html/embed/template.html at the embed header markup. Render the three-file website reproduction with quarto render, open _site/nb-preview.html, and run axe-core on it. Done means the notebook controls are exposed through a named navigation landmark and the region finding is gone.
Written by the indexing model from the issue text.
Description
I have:
- searched the issue tracker for similar issues
- installed the latest version of Quarto CLI
- formatted my issue following the Bug Reports guide
Bug description
On a notebook preview page (*-preview.html), the #quarto-embed-header bar is a plain <div> outside every landmark. The bar holds the "Back to Article" link, the notebook title, and the "Download Notebook" link. Screen-reader users cannot get to these controls with landmark navigation.
axe-core 4.10.3 reports this as region ("All page content should be contained by landmarks"). axe rates region as Best Practice, not as a WCAG failure. The closest success criterion is 1.3.1 Info and Relationships.
- Cause: the embed template writes the bar as a
<div>at the start of<body>: https://github.com/quarto-dev/quarto-cli/blob/abc6a78ed68f9e8bc9d54e27851093bd687a1cb7/src/resources/formats/html/embed/template.html#L119-L133 - Impact: the page has no landmark for its navigation controls. We found it on quarto.org at https://quarto.org/docs/authoring/penguins-preview.html.
- Fix: change the
<div>to<nav id="quarto-embed-header" aria-label="Notebook" ...>. Do not use<header>. In a website,#quarto-headeris already the banner, and a second banner causeslandmark-no-duplicate-banner.
Steps to reproduce
Make a website project with three files: _quarto.yml, index.qmd, and nb.ipynb.
_quarto.yml:
project:
type: website
index.qmd:
---
title: Embed test
---
{{< embed nb.ipynb#one-plus-one >}}
nb.ipynb (already executed, so no kernel is necessary):
{"cells":[{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["2\n"]}],"source":["#| label: one-plus-one\n","print(1 + 1)"]}],
"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python"}},"nbformat":4,"nbformat_minor":5}
- Run
quarto render. - Open
_site/nb-preview.html. - Run axe-core (4.10.3) on the page.
Actual behavior
axe reports region on #quarto-embed-header at 1440x900 and at 320x568:
<div id="quarto-embed-header" class="headroom fixed-top bg-primary">
Expected behavior
The header bar is inside a landmark, for example a nav element with an accessible name. axe reports no region finding for it.
Your environment
- IDE: Positron 2026.10.0 (build 56)
- OS: macOS 26.6.2 (build 25G83)
Quarto check output
Quarto 1.11.4
[✓] Checking environment information...
Quarto cache location: /Users/charlottewickham/Library/Caches/quarto
[✓] Checking versions of quarto binary dependencies...
Pandoc version 3.10.0: OK
Dart Sass version 1.101.0: OK
Deno version 2.7.14: OK
Typst version 0.15.1: OK
[✓] Checking versions of quarto dependencies......OK
[✓] Checking Quarto installation......OK
Version: 1.11.4
Path: /Applications/quarto/bin
[✓] Checking tools....................OK
TinyTeX: v2026.04
Chrome Headless Shell: 150.0.7871.115
VeraPDF: 1.28.2
[✓] Checking LaTeX....................OK
Using: TinyTex
Path: /Users/charlottewickham/Library/TinyTeX/bin/universal-darwin
Version: 2026
[✓] Checking Chrome Headless....................OK
Using: Chrome Headless Shell installed by Quarto
Path: /Users/charlottewickham/Library/Application Support/quarto/chrome-headless-shell/chrome-headless-shell-mac-arm64/chrome-headless-shell
Version: 150.0.7871.115
[✓] Checking basic markdown render....OK
[✓] Checking R installation...........OK
Version: 4.6.0
Path: /Library/Frameworks/R.framework/Versions/4.6/Resources
LibPaths:
- /Users/charlottewickham/Library/R/arm64/4.6/library
- /Library/Frameworks/R.framework/Versions/4.6/Resources/library
knitr: 1.51
rmarkdown: 2.31
[✓] Checking Knitr engine render......OK
[✓] Checking Python 3 installation....OK
Version: 3.12.2
Path: /Users/charlottewickham/.pyenv/versions/3.12.2/bin/python3
Jupyter: 5.9.1
Kernels: python3
[✓] Checking Jupyter engine render....OK
[✓] Checking Julia installation...
AI helped with this investigation. The work was grounded in a local clone of quarto-cli, as "Using AI tools to investigate" in CONTRIBUTING.md describes.
- Dominant language
- JavaScript
- Stars
- 6k
- Forks
- 461
- Avg merge
- 13h 15m
- Merged PRs (30d)
- 54
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from quarto-dev/quarto-cli
-
accessibility bug embed websites
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
quarto-dev/quarto-cli#14972 ·
Maintainers usually reply within 1 day
-
accessibility documentation revealjs
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
quarto-dev/quarto-cli#14971 ·
Maintainers usually reply within 1 day
-
accessibility revealjs
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
quarto-dev/quarto-cli#14970 ·
Maintainers usually reply within 1 day
-
accessibility revealjs themes
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
quarto-dev/quarto-cli#14963 ·
Maintainers usually reply within 1 day
-
accessibility revealjs themes
Difficulty 1/5 Under an hour Newbie friendliness 88/100
quarto-dev/quarto-cli#14962 ·
Maintainers usually reply within 1 day
All issues in quarto-dev/quarto-cli
Similar issues
-
external-issue to-triage
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
LearningCircuit/local-deep-research#7067 ·
Maintainers usually reply within 1 day
-
automated issue report
Difficulty 1/5 Under an hour Newbie friendliness 65/100
lirantal/discoprint#32 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
Maintainers usually reply within 1 day