Browse documentation
Documentation

Font faces

Edit this guide on GitHub

Creates a FontFace with CSS @font-face syntax. Write descriptors as name: value; in any order. Include at least font-family and src:

font_face! {
    font-family: "Inter";
    src: url("/fonts/inter.woff2") format("woff2");
}

Literal values are checked at compile time. Invalid values, such as an out-of-range weight or an unknown format, cause a compile error.

Descriptors

font-family

The family name, given as a string literal:

font_face! {
    font-family: "Inter";
    src: local("Inter");
}

Learn more on MDN.

src

List sources in preference order, separated by commas. Use local("Family Name") for an installed font or url("...") for a font file to download. Optional format(...) and tech(...) hints help the browser skip unsupported files:

font_face! {
    font-family: "Inter";
    src: local("Inter"), url("/fonts/inter.woff2") format("woff2") tech("variations");
}

The format(...) and tech(...) hints may appear in either order. Literal keywords are checked at compile time.

These arguments also accept Rust expressions. Pass a family name to local(...), a URL to url(...), a FontFormat to format(...), or a FontTech to tech(...). A url(...) argument can also be an Asset, resolved when the face is rendered. Sources containing expressions are built at runtime.

font_face! {
    font-family: "Inter";
    src: local(installed), url(href) format("woff2");
}

Learn more on MDN.

font-weight

A single weight, or a space-separated range carried by a variable font. Weights are integers in 1..=1000 or the keywords normal (400) and bold (700):

font_face! {
    font-family: "Inter";
    src: local("Inter");
    font-weight: 400;
}

A range declares the weights available from a variable font:

font_face! {
    font-family: "Inter";
    src: local("Inter");
    font-weight: 1 1000;
}

The range must start at or below its end. Keywords may be mixed with numbers in a range, so font-weight: normal bold is equivalent to 400 700.

Learn more on MDN.

font-style

Use normal, italic, or oblique. An oblique face can include a slant angle or, for a variable font, an angle range. Angles must be within -90deg..=90deg:

font_face! {
    font-family: "Inter";
    src: local("Inter");
    font-style: oblique 14deg;
}

A bare oblique keyword and an angle range are both accepted:

font_face! {
    font-family: "Inter";
    src: local("Inter");
    font-style: oblique 0deg 12deg;
}

Learn more on MDN.

font-display

Controls how text appears while the font loads. For example, swap lets the browser show fallback text until the font is ready:

font_face! {
    font-family: "Inter";
    src: local("Inter");
    font-display: swap;
}

Learn more on MDN.

unicode-range

One or more U+ ranges, separated by commas, restricting the face to a subset of code points. A bare U+0041 covers a single code point; U+0041-005A covers an inclusive range:

font_face! {
    font-family: "Inter";
    src: local("Inter");
    unicode-range: U+0000-00FF, U+0131, U+2000-206F;
}

Learn more on MDN.

Rust Expressions

Use Rust expressions to build descriptors from runtime data. Each expression must match the descriptor's type:

DescriptorType
font-familyA value convertible into String
srcA value convertible into FontSources, such as Vec<FontSource>
font-weightFontWeightRange
font-styleFontStyle
font-displayFontDisplay
unicode-rangeUnicodeRanges
let family = String::from("Inter");
let sources = vec![FontSource::local("Inter")];

font_face! {
    font-family: family;
    src: sources;
    font-weight: FontWeightRange::from_u16(400, 700);
}