Typograqphy

Warning

This section still reflects the brand.yml spec during design. It will be updated shortly to reflect the current brand.yml specification.

About

Fonts

The goal of the with property (may be aliased as font or fonts) is to specify font files that should be included in the brand theme. The primary goal is to provide brand.yml consumers to find and download the fonts used by the brand. brand.yml authors only need to include fonts that are not installed on the system. In general, we support three font sources:

  • Google Fonts
  • Direct URLs
  • Fonts bundled with the brand.yml

brand.yml tooling will be able to provision fonts from Google and remote fonts to a local directory. Where these fonts are stored might be different depending on the output format.

For bundled fonts, we should consider re-using Quarto extension or custom format infrastructure to make it possible to bundle and share brand.yml assets. See Open Questions for more details.

Typography

Determining which fonts are used for key elements is a separate step. This ensures that the typography settings are independent of the font source, and it makes it easier for us to handle the font-downloading tasks by focusing only on the typography.fonts property.

The typography property is used to specify the fonts and some basic typographic settings for key content types:

base
The type used as the default text, primarily in the document body.
headings
The type used for headings. Note that these settings cover all heading levels (h1, h2, etc.).
monospace
The type used for code blocks and other monospaced text.

In the future we can consider adding more types, such as h1, h2, etc., or blockquote, links, etc.

Example

brand.yml
typography:
  with:
    open-sans:
      google: "Open Sans"
    fira-code:
      google: "Fira Code"
    roboto-slab:
      google:
        family: "Roboto Slab"
        weight: 600
        style: normal
        display: block

  base:
    family: open-sans
    line-height: 1.25
    size: 1rem
  headings:
    family: robot-slab
    color: primary
    weight: 600
  monospace:
    family: fira-code
    size: 0.9em

Spec

- id: brand-typography
  description: Typography definitions for the brand.
  object:
    closed: true
    properties:
      with:
        description: Font files and definitions for the brand.
        ref: brand-font
      base:
        description: >
          The base font settings for the brand. These are used as the default for all text.
        ref: brand-typography-options
      headings:
        description: >
          The font settings for headings.
        ref: brand-typography-options-no-size
      monospace:
        description: >
          The font settings for monospace text. Color in this context refers to inline code.
        ref: brand-typography-options
      emphasis:
        description: The text properties used for emphasized (or emboldened) text.
        object:
          closed: true
          properties:
            weight:
              ref: brand-font-weight
            color:
              ref: brand-maybe-named-color
            background-color:
              ref: brand-maybe-named-color
      link:
        description: The text properties used for hyperlinks.
        object:
          closed: true
          properties:
            weight:
              ref: brand-font-weight
            decoration: string
            color:
              schema:
                ref: brand-maybe-named-color
              default: primary
            background-color:
              ref: brand-maybe-named-color

- id: brand-typography-options
  description: Typographic options.
  object:
    closed: true
    properties:
      family: string
      size: string
      line-height: string
      weight:
        ref: brand-font-weight
      style:
        ref: brand-font-style
      color:
        ref: brand-maybe-named-color
      background-color:
        ref: brand-maybe-named-color

- id: brand-typography-options-no-size
  description: Typographic options without a font size.
  object:
    closed: true
    properties:
      family: string
      line-height: string
      weight:
        ref: brand-font-weight
      style:
        ref: brand-font-style
      color:
        ref: brand-maybe-named-color
      background-color:
        ref: brand-maybe-named-color

- id: brand-font
  description: Font files and definitions for the brand.
  arrayOf:
    anyOf:
      - ref: brand-font-google
      - ref: brand-font-file
      - ref: brand-font-family

- id: brand-font-weight
  description: A font weight.
  enum: [100, 200, 300, 400, 500, 600, 700, 800, 900]
  default: 400

- id: brand-font-style
  description: A font style.
  enum: [normal, italic]
  default: normal

- id: brand-font-google
  description: A Google Font definition.
  object:
    closed: true
    properties:
      google:
        anyOf:
          - string
          - object:
              closed: true
              properties:
                family:
                  description: The font family name, which must match the name of the font on Google Fonts.
                  schema: string
                weight:
                  description: The font weights to include.
                  maybeArrayOf:
                    ref: brand-font-weight
                  default: [400, 700]
                style:
                  description: The font style to include.
                  maybeArrayOf:
                    ref: brand-font-style
                  default: [normal, italic]
                display:
                  description: >
                    The font display method, determines how a font face is font face is shown
                    depending on its download status and readiness for use.
                  enum: [auto, block, swap, fallback, optional]
                  default: swap

- id: brand-font-file
  description: A method for providing font files directly, either locally or from an online location.
  object:
    closed: true
    properties:
      family:
        description: The font family name.
        schema: string
      files:
        maybeArrayOf:
          anyOf: [path, string]
        description: >
          The font files to include. These can be local or online.
          Local file paths should be relative to the `brand.yml` file.
          Online paths should be complete URLs.

- id: brand-font-family
  description: >
    A locally-installed font family name. When used, the end-user is responsible
    for ensuring that the font is installed on their system.
  schema: string

Font Customization in R and Quarto

Bootstrap

$font-family-sans-serif:  system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default;
$font-family-monospace:   SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default;
// --
$font-family-base:        var(--#{$prefix}font-sans-serif) !default;
$font-family-code:        var(--#{$prefix}font-monospace) !default;

// $font-size-root affects the value of `rem`, which is used for as well font sizes, paddings, and margins
// $font-size-base affects the font size of the body text
$font-size-root:          null !default;
$font-size-base:          1rem !default; // Assumes the browser default, typically `16px`
// --
$headings-font-family:    null !default;
$headings-font-style:     null !default;
$headings-font-weight:    500 !default;
$headings-line-height:    1.2 !default;
$headings-color:          inherit !default;
// --
$display-font-family:     null !default;
$display-font-style:      null !default;
$display-font-weight:     300 !default;
$display-line-height:     $headings-line-height !default;
// --
$input-btn-font-family:   null !default;
$input-btn-font-size:     $font-size-base !default;
$input-btn-line-height:   $line-height-base !default;
// --
$btn-font-family:         $input-btn-font-family !default;
$btn-font-size:           $input-btn-font-size !default;
$btn-line-height:         $input-btn-line-height !default;
// --
$input-font-family:       $input-btn-font-family !default;
$input-font-size:         $input-btn-font-size !default;
$input-font-weight:       $font-weight-base !default;
$input-line-height:       $input-btn-line-height !default;

bslib

---
output:
  html_document:
    theme:
      base_font:
        google: "Inter"
      code_font:
        google: "Fira Code"
      heading_font:
        google: "Roboto Slab"
---
R Markdown document example (source)
bs_theme(
  base_font = font_google("Inter"),
  code_font = font_google("Fira Code"),
  heading_font = font_google("Roboto Slab")
)
font_google(
  family,
  local = TRUE,
  cache = sass_file_cache(sass_cache_context_dir()),
  wght = NULL,
  ital = NULL,
  display = c("swap", "auto", "block", "fallback", "optional")
)
font_google() is exported from sass
Details
family
A character string with a single font family name.
local
Whether or not download and bundle local (woff2) font files.
cache
A sass_file_cache() object (or, more generally, a file caching class with $get_file() and $set_file() methods). Set this argument to FALSE or NULL to disable caching.
wght

One of the following:

  • NULL, the default weight for the family.
  • A character string defining an axis range
  • A numeric vector of desired font weight(s).
ital

One of the following:

  • NULL, the default font-style for the family.
  • 0, meaning font-style: normal
  • 1, meaning font-style: italic
  • c(0, 1), meaning both normal and italic
display
A character vector for the font-display @font-face property.

pkgdown

template:
  bootstrap: 5
  bslib:
    base_font: {google: "Roboto"}
    heading_font: {google: "Roboto Slab"}
    code_font: {google: "JetBrains Mono"}
Basic pkgdown example (source)
template:
  bslib:
    base_font:
      google:
        family: Open Sans
        wght: [300, 400, 500]
    code_font:
      google: Source Code Pro
    sans_font: Open Sans
    heading_font: Open Sans
    headings-font-weight: 300
Complicated font example (source)

Quarto

HTML

Provides mainfont and monofont in Basic Options. These are used by src/resources/foramts/html/pandoc/styles.html. Note that a corresponding setting for headings is not included.

@import 'https://fonts.googleapis.com/css?family=Lato';

h1, h2, h3, h4, p {
  font-family: 'Lato', Arial, sans-serif;
}
Quarto in-the-wild example (nhsr-quarto)

Presentations

Similar to HTML documents, it appears that Boostrap Sass variables have been replicated for revealjs, with some Sass variables of their own:

  • $font-family-sans-serif
  • $font-family-monospace
  • $presentation-heading-font
// fonts
$font-family-sans-serif: "Palatino Linotype", "Book Antiqua", Palatino,
  FreeSerif, serif !default;

$presentation-heading-font: "Palatino Linotype", "Book Antiqua", Palatino,
  FreeSerif, serif !default;
$presentation-heading-color: #383d3d !default;

Typst

Typst only supports mainfont

format:
  typst:
    mainfont: "Agbalumo"
    font-paths: myfonts

PDF

Uses mainfont, sansfont and monofont, which, for xelatex (the default LaTeX engine), need to be installed on the system. (Source)

Appendix - Variations

brand.yml (simple)
font:
  base: "Open Sans"
  headings:
    google: "Roboto Slab"
  monospace:
    google: "Fira Code"
brand.yml (full)
font:
  base: "Open Sans"
  headings:
    google:
      family: "Roboto Slab"
      weight: [600, 800]
      style: normal
      display: block
  monospace:
    google:
      family: "Fira Code"
      weight: 300
  galada:
    family: "Galada"
    files: "fonts/Galada-Regular.ttf"
  oswald:
    family: "Oswald"
    files:
      - https://github.com/vernnobile/OswaldFont/raw/master/3.0/Roman/700/Oswald-Bold.ttf
      - https://github.com/vernnobile/OswaldFont/raw/master/3.0/Roman/400/Oswald-Regular.ttf

Alternatively, the font property could be limited to just defining the fonts that should be installed on the system.

brand.yml (separate font and typography)
font:
  - google: "Fira Code"
  - google:
      family: "Roboto Slab"
      weight: [600, 800]
      style: normal
      display: block
  - family: "Galada"
    files: "fonts/Galada-Regular.ttf"
  - family: "Oswald"
    files:
      - https://github.com/vernnobile/OswaldFont/raw/master/3.0/Roman/700/Oswald-Bold.ttf
      - https://github.com/vernnobile/OswaldFont/raw/master/3.0/Roman/400/Oswald-Regular.ttf

typography:
  base:
    family: "Open Sans"
  headings:
    family: "Roboto Slab"
  monospace:
    family: "Fira Code"

Another approach would be to nest fonts under typography:

brand.yml (nested font and typography)
typography:
  fonts:
    - google: "Fira Code"
    - google:
        family: "Roboto Slab"
        weight: [600, 800]
        style: normal
        display: block
    - family: "Galada"
      files: "fonts/Galada-Regular.ttf"
    - family: "Oswald"
      files:
        - https://github.com/vernnobile/OswaldFont/raw/master/3.0/Roman/700/Oswald-Bold.ttf
        - https://github.com/vernnobile/OswaldFont/raw/master/3.0/Roman/400/Oswald-Regular.ttf
  base:
    family: "Open Sans"
    weight: 400
    line-height: 1.5
  headings:
    family: "Roboto Slab"
    color: "--primary"
  monospace:
    family: "Fira Code"
brand.yml (nested font and typography)
typography:
  fonts:
    - google: "Fira Code"
    - google: "Roboto Slab"
    - google: "Open Sans"
  base:
    family: "Open Sans"
    weight: 400
    line-height: 1.5
  headings:
    family: "Roboto Slab"
    color: "--primary"
  monospace:
    family: "Fira Code"
brand.yml (nested font and typography)
typography:
  base:
    family:
      google: "Open Sans"
    location: google
    weight: 400
    line-height: 1.5
  headings:
    family:
      google: "Roboto Slab"
    location:
      - fonts/Roboto Slab Regular.ttf
      - fonts/Roboto Slab Bold.ttf
    color: "--brand-primary"
  monospace:
    family:
      google: "Fira Code"
  h2:
    family: Open Sans
    weight: 300
    color: black

Or font could be a property of any typography element. This makes font- properties more consistent, e.g. font.family, font.weight, etc., but it also makes typography items more complex (which properties are nested under font and which aren’t?).

brand.yml (font in typography)
typography:
  base:
    font:
      family: "Open Sans"
      weight: 400
    line-height: 1.5
  headings:
    font:
      google:
        family: "Roboto Slab"
        weight: [600, 800]
        style: normal
        display: block
    color: "--primary"
  monospace:
    font:
      google: "Fira Code"