a11y: logos without alt text are handled inconsistently across formats

Open
#14,660 0 comments 1 reaction 1 assignee View on GitHub

@cderv is already working on this.

Since Jul 8, 2026.

Assessment

This issue has not been assessed yet.

Description

accessibility bug revealjs typst
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

Logo alt text is settable across formats — websites via logo-alt, typst and revealjs via logo: {path, alt}.
This issue is about the default when no alt is provided: the format pipelines disagree, and two of them produce inaccessible output rather than a safe fallback.

When a logo (navbar/sidebar logo, revealjs slide logo, or typst logo) is rendered without alt text, they emit:

Path Emitted markup for a logo with no alt Source
HTML website navbar <img … alt="" …> navbrand.ejs#L6-L9
HTML website sidebar <img … alt="" …> sidebar.ejs#L40-L43
revealjs slide logo <img …>alt attribute omitted format-reveal.ts#L409-L416
Typst title-page logo image(...)alt parameter omitted page.typ#L14

HTML defaults a missing logo alt to an empty alt=""; revealjs and Typst leave the attribute off entirely.

This matters because empty vs. absent alt are not equivalent for accessibility:

  • <img alt=""> is a valid decorative-image signal — assistive tech skips it, and axe-core's image-alt rule passes.
  • <img> with no alt attribute fails axe-core image-alt (tagged wcag2a/wcag111 → WCAG 2.2 SC 1.1.1 Non-text Content, Level A), and screen readers commonly announce the image filename instead.

So on the same input (a logo with no alt), a Quarto website is conformant while a reveal deck produces a Level A failure — and the Typst PDF's logo has no text alternative.

Investigation was AI-assisted, grounded in a local clone of this repo (source pinned to 50f3d27) and reproduced with Quarto 1.10.12, per CONTRIBUTING.md's note on using AI tools.

The design question

Fixing the inconsistency forces a decision about the intended default, which is really the point of this issue.
Our options are:

  1. Assume logos are decorative → emit alt="" everywhere. Make revealjs/Typst match HTML. Simplest; no broken output; passes axe. Downside: it silently passes — an author who forgot alt on a genuinely meaningful logo is never told, because alt="" conforms.
  2. Emit alt="" everywhere and warn at render time when a logo resolves with no alt, plus an explicit opt-out to mark a logo decorative and suppress the warning. Alerts every author at build time while keeping output safe. Downside: more work; needs a "decorative" flag and could be noisy for logos that legitimately sit next to visible title text.
  3. Something else?

I think omit alt as a default isn't an option. This leads to an outright 1.1.1 failure that will only get picked up if an author runs a check.

So at minimum revealjs and typst should stop omitting the attribute. The open question is whether the default should stay a silent alt="" (option 1) or gain a warning (option 2).

For context, logos are often decorative but not always. For example, a navbar logo that includes the site/organization name (that isn't otherwise in the navbar).

Steps to reproduce
---
title: "Logo alt test"
format: revealjs
logo: logo.svg
---

## Slide one

Content.

Render, then inspect the emitted logo:

quarto render deck.qmd
grep -oE '<img[^>]*slide-logo[^>]*>' deck.html
Actual behavior

Same input, no alt specified — divergent output:

revealjs:  <img src="logo.svg" class="slide-logo">                       # no alt
website:   <img src="./logo.svg" alt="" class="navbar-logo light-content">  # alt=""

The revealjs <img> has no alt attribute → axe-core image-alt violation (WCAG 1.1.1, Level A); screen readers may read logo.svg. The Typst pipeline likewise omits the alt: parameter on the title-page logo.

Expected behavior

Consistent handling across formats.

Your environment
  • IDE: Positron (CLI render; IDE-independent)
  • OS: macOS 26.5.1 (25F80)
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
      VeraPDF: 1.28.2
      Chrome Headless Shell: (not installed)

[✓] Checking LaTeX....................OK
      Using: TinyTex
      Path: /Users/charlottewickham/Library/TinyTeX/bin/universal-darwin
      Version: 2026

[✓] Checking Chrome Headless....................OK
      Using: Chrome found on system
      Path: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
      Source: MacOS known location

[✓] 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...
Dominant language
JavaScript
Stars
6k
Forks
458
Avg merge
1d 9h
Merged PRs (30d)
41

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from quarto-dev/quarto-cli

All issues in quarto-dev/quarto-cli

Similar issues

More JavaScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.