Skip to content

a11y: links that contain inline code fail WCAG AA color contrast in the default theme #14827

Description

@cwickham

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

  1. Save the document below as index.qmd.
  2. Run quarto preview index.qmd.
  3. 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 main at abc6a78ed68f9e8bc9d54e27851093bd687a1cb7

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions