Skip to content

Font Management

Armonia allows you to define base fonts and computed fonts that derive from them.

Define Fonts

A Font object contains the family name, size (in pixels or rem), weight, and italic style. It can also include optional letter spacing.

from armonia import Theme, typography

theme = Theme()

# Define base fonts
# Font(family, size, weight, italic, letter_spacing=None)
theme.set_font("body", typography.Font("Inter", 16.0, 400, False))
theme.set_font("heading", typography.Font("Georgia", 32.0, 700, False, letter_spacing="-0.02em"))

Computed Fonts

Derived fonts inherit the family from their source but can vary in size, weight, italic style, and letter spacing.

from armonia import fontfunctions as ff

# weight 400 -> 700
theme.set_computed_font("body_bold", ff.bolder("body", 300))

# italic enabled
theme.set_computed_font("body_italic", ff.italic("body"))

# size 16px -> 12px
theme.set_computed_font("body_small", ff.adjust_size("body", -4.0))

# size 16px -> 24px
theme.set_computed_font("body_large", ff.scale_size("body", 1.5))

# adjust multiple properties at once
theme.set_computed_font("caption", ff.adjust("body", size_delta=-3.0, weight_delta=-100))

Font Functions

Function Description
ff.scale_size(key, factor) Multiply size by factor (must be > 0).
ff.adjust_size(key, delta) Add delta pixels to size.
ff.bolder(key, amount=100) Increase weight, clamped to 1000.
ff.lighter(key, amount=100) Decrease weight, clamped to 1.
ff.italic(key) Enable italic style.
ff.roman(key) Disable italic style (upright).
ff.adjust(key, size_delta, weight_delta, make_italic, letter_spacing) Adjust multiple properties at once.
ff.alias(key) Reference another font by name.

Computed fonts can also be chained — a computed font can derive from another computed font.

Listing Fonts

Retrieve and sort all theme fonts:

# Sort by name, size, weight, or family
for entry in theme.get_all_fonts(sort_by="size"):
    style = "italic" if entry.font.italic else "roman"
    ls = f" (ls: {entry.font.letter_spacing})" if entry.font.letter_spacing else ""
    print(f"{entry.name}: {entry.font.family} {entry.font.size}px w{entry.font.weight} {style}{ls} ({entry.source})")