quarto-dev / quarto-dev/quarto-cli
a11y: links that contain inline code fail WCAG AA color contrast in the default theme
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 6k
- Forks
- 458
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 41
Description
I have
- searched the existing issues, and did not find a duplicate.
- tried the latest release of Quarto.
- made a minimal reproducible example.
Bug description
In the default HTML theme, a link that contains inline code fails color
contrast. Authors write this as [`function_name`](url).
The code renders as #0d6efd on #f1f3f5, a ratio of 4.04:1. The requirement
is 4.5:1.
Plain inline code passes at 7.06:1. A plain link passes at 4.50:1. Only the
combination of the two fails.
This fails WCAG 2.2 Success Criterion 1.4.3 Contrast (Minimum)
(Level AA). axe-core reports it as color-contrast, impact serious.
The pattern is common in Quarto documentation, because authors link function
names and option names to their reference pages.
Cause
Two rules combine. Bootstrap gives inline code inside a link the link color
(_reboot.scss#L322-L333):
code {
color: var(--#{$prefix}code-color);
// Streamline the style when inside anchors to avoid broken underline and more
a > & {
color: inherit;
}
}
Quarto then puts a gray background behind inline code in paragraphs, list items,
and table cells
(_bootstrap-rules.scss#L971-L997).
In the default theme this computes to #f1f3f5.
The result is the link color on a gray background, a pair that nothing checks.
Quarto does set a safe color for plain inline code, $code-color: #7d12ba
(_bootstrap-variables.scss#L41-L45),
which measures 7.06:1 on that same background. The link color receives no
equivalent treatment.
The default link color #0d6efd measures exactly 4.50:1 on white. It clears the
threshold on the page by the smallest possible margin, so the gray tint is
enough to move it under.
Relation to existing issues
#5780 reported this case in cosmo. Its body lists
[`inline code link`](https://quarto.org) at #2780e3, with a measured
ratio of 3.71. It was closed as completed for v1.4 by moving the cosmo blue to
#2761e3, which brings that theme to 4.83:1.
The default theme was not part of that change, and still fails today.
#2548 corrected the color of plain inline code in the default theme. That fix
holds. This report is about a different pair of colors.
Steps to reproduce
- Save the document below as
index.qmd. - Run
quarto preview index.qmd. - Read the accessibility report at the end of the page.
Use quarto preview, not quarto render. The checker loads as a module script,
which a browser blocks over file://, so the report is empty on a rendered file
opened directly.
---
title: "Linked inline code contrast"
format:
html:
axe:
output: document
---
A link with inline code: [`linked_code`](https://example.com)
Plain inline code for comparison: `plain_code`
Actual behavior
The report shows one violation, with one target:
Serious · WCAG 2.0 AA (1.4.3): Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds
Elements must meet minimum color contrast ratio thresholds
a > code
The target is a > code. The plain inline code on the same page is not
reported.
Measured directly, the code inside the link computes to #0d6efd on #f1f3f5,
a ratio of 4.04:1. The plain inline code computes to #7d12ba on #f1f3f5, a
ratio of 7.06:1.
The same failure appears wherever inline code carries the gray background:
paragraphs, list items, table cells, callouts, blockquotes, and figure captions.
In figure captions the background is #f8f9fa and the ratio is 4.26:1, which
also fails.
Expected behavior
In the default theme, inline code inside a link meets 4.5:1 against its own
background.
Your environment
- IDE: none, Quarto CLI at the command line
- OS: macOS 26.5.2 (build 25F84)
- Browser: Google Chrome for Testing 151.0.7922.34
- Scanner: axe-core 4.13.0
- Also present in Quarto 99.9.9, built from
mainatabc6a78ed68f9e8bc9d54e27851093bd687a1cb7
Quarto check output
Quarto 1.10.18
[✓] 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.10.18
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 described in CONTRIBUTING.md.
Contributor 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.
Research direction
Start with src/resources/formats/html/bootstrap/_bootstrap-rules.scss and _bootstrap-variables.scss, using the linked _reboot.scss section for context. Run quarto preview on the supplied index.qmd and inspect the axe report. Done means linked inline code in the default theme meets the 4.5:1 contrast ratio while plain inline code remains compliant.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- sass
- Domain
- accessibility, frontend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100