I have:
Bug description
Quarto's HTML outputs render navigation — navbar, search, sidebar, page tabs, TOC — before the main content, with no "skip to main content" link. Keyboard and switch users must therefore tab through every navigation stop on every page before reaching the content, which fails WCAG 2.2 SC 2.4.1 "Bypass Blocks" (Level A) — a criterion Section 508, EN 301 549, and the US ADA Title II rule all incorporate.
Authors have no remedy short of hand-injecting HTML (the announcement workaround from #11602 consumes that feature and leaves a visible bar), so I'm filing this as a bug rather than a feature request; the standing request is discussion #10096.
Most of the machinery already exists:
- The target has shipped since 2022: 59616f22e added
<main id="quarto-document-content"> explicitly "for things like skip links" (before-body-article.ejs#L20, nav-before-body.ejs#L128-L130); the link never followed.
- Bootstrap's
.visually-hidden-focusable helper (what Bootstrap's own docs use for their skip link) is already compiled into every Quarto theme bundle.
- Exception:
format: dashboard output has no <main> and no id on its content container, so there is currently nothing to target — itself a missing-landmark issue.
Related:
- Discussion #10096 (Jun 2024): standing feature request; comments cite MkDocs Material and pkgdown as reference implementations.
- Issue #11602 (Dec 2024): same report plus the workaround; converted to discussion #11603, duplicate of Skip to Main Content button #10096.
Steps to reproduce
Render each of the three documents below, open the output in a browser, click in the address bar, then press Tab repeatedly and observe which element receives focus at each step.
1. Document with a TOC (format: html):
---
title: "Reproducible Quarto Document"
format: html
toc: true
---
## Section one
Some text with a [link](https://quarto.org).
{{< lipsum 1 >}}
## Section two
{{< lipsum 1 >}}
## Section three
{{< lipsum 1 >}}
2. Multi-page dashboard (format: dashboard):
---
title: "Reproducible Quarto Dashboard"
format: dashboard
---
# Heat
## Row
Content about heat-related illness, with a [link](https://quarto.org).
# Air quality
## Row
Content about air quality.
# Water
## Row
Content about water quality.
3. Website with navbar and sidebar (quarto render on this project):
_quarto.yml:
project:
type: website
website:
title: "Reproducible Website"
navbar:
left:
- href: index.qmd
text: Home
- href: about.qmd
text: About
- href: data.qmd
text: Data
sidebar:
contents:
- index.qmd
- about.qmd
- data.qmd
index.qmd (plus trivial about.qmd, data.qmd):
---
title: "Home"
---
Some text with a [link](https://quarto.org).
Actual behavior
There is no skip link anywhere; the first tab stops are always navigation. Measured tab order (Quarto 1.10.12, Chrome 150; the numbers are Tab presses from page load):
Document with TOC — content reached at stop 4:
1 <a#toc-section-one> "Section one"
2 <a#toc-section-two> "Section two"
3 <a#toc-section-three> "Section three"
4 first link inside the document content
Dashboard — content reached at stop 3:
1 <a> navbar brand "Reproducible Quarto Dashboard"
2 <a#tab-heat.nav-link.active> "Heat" (inactive page tabs are tabindex="-1")
3 first link inside the dashboard content
Website with navbar + 3-item sidebar — content reached at stop 9:
1 <a.navbar-brand> "Reproducible Website"
2 <button> search
3 <a.nav-link.active> "Home"
4 <a.nav-link> "About"
5 <a.nav-link> "Data"
6 <a.sidebar-link.active> "Home"
7 <a.sidebar-link> "About"
8 <a.sidebar-link> "Data"
9 first link inside the page content
These are minimal examples; the count grows linearly with navigation size. A documentation site with a 40-item sidebar imposes ~45 tab stops per page, on every page, and the TOC case grows with document length.
Expected behavior
The standard skip-link pattern (as shipped by pkgdown, MkDocs Material, and Bootstrap's own documentation):
- Pressing Tab once on a freshly loaded page reveals a visible "Skip to main content" link as the first tab stop, before the navbar brand, search, TOC, or page tabs. This is the position WCAG's sufficient technique G1 requires — its test procedure is "check that a link is the first focusable control on the Web page" — and G1 explicitly permits the link to be visually hidden until focused, so nothing changes for mouse users.
- Activating it with Enter scrolls to the main content and moves the sequential focus point there, so the next Tab lands on the first interactive element inside the content (the body link in the repros above) rather than back in the navigation.
- Tabbing past the link without activating it hides it again.
- Screen readers announce it as the first link on the page.
- The link appears on every page of a website. For dashboards, one link per document suffices (multi-page dashboards are Bootstrap tab panes within a single document), but the content container needs a
<main> element or at least an id to serve as the target — dashboard output currently has neither.
Expected tab order for the website repro would then be: stop 1 = skip link → Enter → next Tab = first link in content. Two keystrokes instead of nine — on a real docs site, two instead of dozens.
No JavaScript should be needed: following a same-page fragment link moves the sequential focus navigation starting point in all modern browsers; tabindex="-1" on the target covers older browser/AT combinations.
Your environment
- IDE: Positron 2026.07.0 build 352
- OS: macOS 26.5.1 (build 25F80)
- Browser (keyboard testing): Google Chrome 150.0.7871.49
An AI assistant helped investigate this issue, grounded in a local clone of quarto-cli (per CONTRIBUTING.md, "Using AI tools to investigate"). Tab orders were verified with real keypresses in headless Chrome.
Quarto check output
Quarto 1.10.12
[✓] Checking environment information...
Quarto cache location: /Users/charlottewickham/Library/Caches/quarto
[✓] Checking versions of quarto binary dependencies...
Pandoc version 3.8.3: OK
Dart Sass version 1.87.0: OK
Deno version 2.7.14: OK
Typst version 0.14.2: OK
[✓] Checking versions of quarto dependencies......OK
[✓] Checking Quarto installation......OK
Version: 1.10.12
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.13.2
Path: /Users/charlottewickham/.local/share/uv/python/cpython-3.13.2-macos-aarch64-none/bin/python
Jupyter: (None)
Jupyter is not available in this Python installation.
Install with python3 -m pip install jupyter
[✓] Checking Julia installation...
I have:
Bug description
Quarto's HTML outputs render navigation — navbar, search, sidebar, page tabs, TOC — before the main content, with no "skip to main content" link. Keyboard and switch users must therefore tab through every navigation stop on every page before reaching the content, which fails WCAG 2.2 SC 2.4.1 "Bypass Blocks" (Level A) — a criterion Section 508, EN 301 549, and the US ADA Title II rule all incorporate.
Authors have no remedy short of hand-injecting HTML (the
announcementworkaround from #11602 consumes that feature and leaves a visible bar), so I'm filing this as a bug rather than a feature request; the standing request is discussion #10096.Most of the machinery already exists:
<main id="quarto-document-content">explicitly "for things like skip links" (before-body-article.ejs#L20, nav-before-body.ejs#L128-L130); the link never followed..visually-hidden-focusablehelper (what Bootstrap's own docs use for their skip link) is already compiled into every Quarto theme bundle.format: dashboardoutput has no<main>and no id on its content container, so there is currently nothing to target — itself a missing-landmark issue.Related:
Steps to reproduce
Render each of the three documents below, open the output in a browser, click in the address bar, then press Tab repeatedly and observe which element receives focus at each step.
1. Document with a TOC (
format: html):2. Multi-page dashboard (
format: dashboard):3. Website with navbar and sidebar (
quarto renderon this project):_quarto.yml:index.qmd(plus trivialabout.qmd,data.qmd):Actual behavior
There is no skip link anywhere; the first tab stops are always navigation. Measured tab order (Quarto 1.10.12, Chrome 150; the numbers are Tab presses from page load):
Document with TOC — content reached at stop 4:
Dashboard — content reached at stop 3:
Website with navbar + 3-item sidebar — content reached at stop 9:
These are minimal examples; the count grows linearly with navigation size. A documentation site with a 40-item sidebar imposes ~45 tab stops per page, on every page, and the TOC case grows with document length.
Expected behavior
The standard skip-link pattern (as shipped by pkgdown, MkDocs Material, and Bootstrap's own documentation):
<main>element or at least an id to serve as the target — dashboard output currently has neither.Expected tab order for the website repro would then be: stop 1 = skip link → Enter → next Tab = first link in content. Two keystrokes instead of nine — on a real docs site, two instead of dozens.
No JavaScript should be needed: following a same-page fragment link moves the sequential focus navigation starting point in all modern browsers;
tabindex="-1"on the target covers older browser/AT combinations.Your environment
An AI assistant helped investigate this issue, grounded in a local clone of quarto-cli (per CONTRIBUTING.md, "Using AI tools to investigate"). Tab orders were verified with real keypresses in headless Chrome.
Quarto check output