Shopify Refresh · Free, no signup · Last updated
Refresh Theme Typography CSS Variables
Refresh exposes `--font-heading-family`, `--font-heading-style`, `--font-heading-weight`, and the matching `--font-body-*` tokens on `:root` — overriding them is the cleanest way to swap typography without forking core theme files.
Refresh centralizes its entire typography system in six CSS custom properties on `:root`. Because a sport- and energy-leaning free theme tuned for high-saturation imagery and bold supporting copy., every page-level heading and paragraph reads from those tokens — meaning a single override block can retarget the whole site.
Generator
Live preview
Add to cart · Free shipping · 30-day returns
Drop a WOFF2 / WOFF / TTF file here to preview your actual font. The file stays in your browser — nothing is uploaded.
Paste these three blocks in order. They're independent files in your theme — copying one without the others won't break the store.
Step 1: @font-face CSS
Upload your font files to the theme's assets/ folder, then paste this at the bottom of assets/base.css. Shopify's asset_url filter resolves the file paths at render time.
@font-face {
font-family: "My Brand Sans";
src: url({{ 'my-brand-sans.woff2' | asset_url }}) format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}Step 1: @font-face CSS
Upload your font files to the theme's assets/ folder, then paste this at the bottom of assets/base.css. Shopify's asset_url filter resolves the file paths at render time.
@font-face {
font-family: "My Brand Sans";
src: url({{ 'my-brand-sans.woff2' | asset_url }}) format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}Step 2: settings_schema.json
Adds a Theme Editor section so non-technical merchants can toggle the font on or off.
{
"name": "My Brand Sans (primary custom font)",
"settings": [
{
"type": "header",
"content": "My Brand Sans typography"
},
{
"type": "paragraph",
"content": "Upload your font file (woff2) to your theme's Assets folder. The @font-face block will resolve them via {{ 'my-brand-sans.woff2' | asset_url }}."
},
{
"type": "font_picker",
"id": "my_brand_sans_heading_font",
"label": "Native Theme Editor heading fallback (only used if you don't upload custom files)"
},
{
"type": "font_picker",
"id": "my_brand_sans_body_font",
"label": "Native Theme Editor body fallback (only used if you don't upload custom files)"
},
{
"type": "checkbox",
"id": "my_brand_sans_use_for_both",
"label": "Use this font for both headings and body",
"default": true
},
{
"type": "select",
"id": "my_brand_sans_apply_to",
"label": "Apply My Brand Sans (only used when \"Use this font for both\" is unchecked)",
"options": [
{
"value": "headings",
"label": "Headings only"
},
{
"value": "body",
"label": "Body only"
},
{
"value": "both",
"label": "Headings and body"
},
{
"value": "off",
"label": "Disabled"
}
],
"default": "both"
},
{
"type": "paragraph",
"content": "font-display strategy: swap — controls how text renders while the font file is downloading. \"swap\" is the recommended default."
},
{
"type": "checkbox",
"id": "my_brand_sans_load_woff_fallback",
"label": "Also load WOFF fallback (legacy browsers)",
"default": false
}
]
}Step 3: CSS variable overrides
Retargets the theme's --font-heading-family / --font-body-family. Survives theme updates.
:root,
[data-shopify-section],
.shopify-section {
--font-heading-family: "My Brand Sans", sans-serif;
--font-heading-style: normal;
--font-heading-weight: 400;
--font-body-family: "My Brand Sans", sans-serif;
--font-body-style: normal;
--font-body-weight: 400;
}How to use this on Refresh
The six tokens are: `--font-heading-family`, `--font-heading-style`, `--font-heading-weight`, `--font-body-family`, `--font-body-style`, and `--font-body-weight`.
Refresh sets them in `base.css` from the values configured in the Theme Editor.
To swap them, you append a `:root { ... }` override to the bottom of `assets/base.css` — that override loads after the theme's defaults and wins by source order.
Selectors like .banner__heading, .button--primary pick up the change without any template edits, and the override survives Refresh updates because you're modifying values, not the cascade chain itself.
Typography Kit
Skip straight to a finished result
Every step above, already done for you on Refresh — a proven font pairing, the install code pre-built, the licensing confirmed, and a specimen so you see it before you ship it. One-time, instant download, no account.
Don't have a font yet? Creative Fabrica has 30,000+ web fonts with commercial licenses included — drop one into the @font-face block above and you're live. (affiliate)
Frequently asked questions
Which CSS variables control typography in Refresh?
Refresh sets six tokens on `:root`: `--font-heading-family`, `--font-heading-style`, `--font-heading-weight`, `--font-body-family`, `--font-body-style`, and `--font-body-weight`. Heading selectors read the heading triplet, body selectors read the body triplet — there's no per-section override.
What's the difference between --font-heading-family and --font-body-family in Refresh?
`--font-heading-family` is consumed by every heading-level rule, including .banner__heading, .button--primary. `--font-body-family` is consumed by paragraphs, list items, form copy, and the cart drawer in Refresh. Setting only one lets you mix a display heading face with the theme's default body face on body — a useful split when your custom font is large.
How do I override Refresh's typography without touching base.css directly?
Add a `:root { --font-heading-family: ... }` block at the bottom of `assets/base.css`. The cascade resolves the later declaration as the winner, so Refresh's defaults are overridden without removing them. This pattern survives Shopify's quarterly theme updates, which often modify `base.css` but rarely touch the trailing customization region.
Will a CSS-variable typography override survive a Refresh update?
Yes — provided you append the override at the bottom of `assets/base.css` rather than editing the original token declarations. Refresh ships theme updates that may rewrite the `base.css` defaults, but appended override blocks are preserved as long as they live below the auto-generated section. As a hardening step, paste the override behind a clearly marked comment so future you (or a subsequent developer) recognizes it as customization.