I have:
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:
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:
- 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.
- 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.
- 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...
I have:
Bug description
Logo alt text is settable across formats — websites via
logo-alt,typstandrevealjsvialogo: {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/sidebarlogo,revealjsslide logo, ortypstlogo) is rendered without alt text, they emit:<img … alt="" …>navbrand.ejs#L6-L9<img … alt="" …>sidebar.ejs#L40-L43<img …>— alt attribute omittedformat-reveal.ts#L409-L416image(...)— alt parameter omittedpage.typ#L14HTML 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'simage-altrule passes.<img>with noaltattribute fails axe-coreimage-alt(taggedwcag2a/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.
The design question
Fixing the inconsistency forces a decision about the intended default, which is really the point of this issue.
Our options are:
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, becausealt=""conforms.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.I think omit
altas 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
revealjsandtypstshould stop omitting the attribute. The open question is whether the default should stay a silentalt=""(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
Render, then inspect the emitted logo:
quarto render deck.qmd grep -oE '<img[^>]*slide-logo[^>]*>' deck.htmlActual behavior
Same input, no alt specified — divergent output:
The revealjs
<img>has noaltattribute → axe-coreimage-altviolation (WCAG 1.1.1, Level A); screen readers may readlogo.svg. The Typst pipeline likewise omits thealt:parameter on the title-page logo.Expected behavior
Consistent handling across formats.
Your environment
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...