brand font family names are not quoted in generated CSS

オープン 初心者向け
#14,882 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
84/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
css, sass, typescript
領域
frontend, web-dev

調査の方向性

src/core/sass/brand.ts の brandTypographyLayer から始め、src/core/css.ts の asCssFont および src/format/html/format-html-scss.ts にある既存の mainfont パスと、ファミリーの扱いを比較します。自己完結型の HTML 例をレンダリングし、生成された Bootstrap CSS を確認します。brand font-family 宣言が一貫して引用符で囲まれ、Typst に影響を与えずに HTML と revealjs の出力で Source Sans 3 が適用されれば完了です。

索引モデルが issue の本文から書いたものです。

説明

brand bug html revealjs

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

A brand font family whose name contains a bare number does not apply in HTML output. The text falls back to the browser default serif font.

Quarto writes the family name into the generated CSS without quotes. For Source Sans 3 the output is font-family:Source Sans 3. A bare 3 is not a valid CSS identifier, so the browser discards the whole declaration.

The @import for the font is correct and the font downloads. This makes the problem look like a font-loading error, but the font is never used.

Quotes in the YAML do not help. Quarto strips them before it generates the CSS.

The same family name works when it is set with document metadata instead:

mainfont: Source Sans 3   # produces font-family:"Source Sans 3" — works

Related but different: #11947 reports Source Sans 3 as a _brand.yml font, and that thread diagnosed a Typst font-name mismatch. The HTML side was noted as unexplained there. This issue is the HTML cause.

Steps to reproduce

Render this self-contained document to HTML:

---
title: Font test
format: html
brand:
  typography:
    fonts:
      - family: Source Sans 3
        source: google
    base: Source Sans 3
---

Hello world.

Open the result in a browser, or read the generated index_files/libs/bootstrap/bootstrap-*.min.css.

A _brand/_brand.yml file with the same typography block produces byte-identical CSS.

Actual behavior

The generated CSS holds the family name without quotes:

@import"https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,400;0,700;1,400;1,700&display=swap";
...
:root,[data-bs-theme=light]{...--bs-body-font-family: Source Sans 3;...}
...
font-family:Source Sans 3

The computed font-family on body in Chromium is Times.

Scope, measured on Quarto 1.11.4:

Element Affected Note
base yes $font-family-base, $mainFont, $mermaid-font-family
headings yes $headings-font-family, $presentation-heading-font
monospace, monospace-inline, monospace-block yes falls back to generic monospace
link no link has no family property in the schema
Format Affected
html yes
revealjs yes (--r-main-font, --r-heading-font, --r-code-font)
typst no — the Typst emitter writes font: ("Source Sans 3",), always quoted
Font source Affected
google yes
bunny yes
file yes

The file source shows the inconsistency inside one stylesheet. The @font-face rule quotes the family, the variable that uses it does not:

@font-face{font-family:"My Font 3";src:url("fonts/myfont.woff2");font-weight:400;font-style:normal}
...
font-family:My Font 3

The trigger is any family name with a space-separated part that starts with a digit. Source Sans 3, Bricolage Grotesque 96pt, M PLUS 1 Code and M PLUS Rounded 1c all fail. Roboto Mono works, because both parts are valid identifiers.

Cause

brandTypographyLayer interpolates the value straight into the Sass variable, with no quoting for family names:

https://github.com/quarto-dev/quarto-cli/blob/abc6a78ed68f9e8bc9d54e27851093bd687a1cb7/src/core/sass/brand.ts#L543-L549

A helper for this already exists. asCssFont quotes any font name that contains a space:

https://github.com/quarto-dev/quarto-cli/blob/abc6a78ed68f9e8bc9d54e27851093bd687a1cb7/src/core/css.ts#L85-L104

It is used for the mainfont and monofont metadata path, which is why mainfont: Source Sans 3 works:

https://github.com/quarto-dev/quarto-cli/blob/abc6a78ed68f9e8bc9d54e27851093bd687a1cb7/src/format/html/format-html-scss.ts#L481-L482

The brand path does not use it. Applying asCssFont when source is family would match the existing metadata path, the @font-face rule that fileFontImportString already emits with quotes, and Bootstrap's own defaults in the same stylesheet (--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, …).

Expected behavior

The generated CSS quotes the family name, and the font applies:

font-family:"Source Sans 3"

With the quotes added by hand to the generated stylesheet, the computed font-family on body becomes "Source Sans 3" and the font renders.

Your environment

  • IDE: Positron 1.130.0
  • OS: macOS 26.6.2 (build 25G83)

AI assistance was used to investigate this, grounded in a local clone of the repository, as described in Using AI tools to investigate.

Quarto check output

Quarto 1.11.4
[✓] 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.11.4
      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.5.2
      Path: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources
      LibPaths:
        - /Users/charlottewickham/Library/R/arm64/4.5/library
        - /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/library
      knitr: 1.51
      rmarkdown: 2.30
[✓] 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...
主要言語
JavaScript
スター
6k
フォーク
458
平均マージ
1日 8時間
マージ済み PR(30日)
42

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

quarto-dev/quarto-cli のほかの issue

quarto-dev/quarto-cli の issue をすべて見る

似ている issue

JavaScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。