32px, the editor saves a CSS reference such as var(--heading-size).
When the theme value changes, every linked use updates without editing the content again.
Define a theme setting
Create settings inconfig/settings_schema.json. The editor looks up each control’s presets by group name, matched exactly — Typography and type do not match typography:
Connect the setting to a CSS variable
Declare a CSS custom property inlayouts/theme.liquid and read the setting into it:
- It sits inside a
{% style %}or<style>block. - It is a custom property reading the setting:
--anything: {{ settings.heading_size }}.
{{ settings.heading_size }} anywhere else — a meta tag, an inline style attribute, or a plain font-size: output — renders the value but registers no variable, so the preset does not appear.
The variable name does not need to match the setting ID. The link comes from the settings.heading_size reference. Matching them is still worth doing: when the editor writes a variable for a setting it manages, it names it --<setting_id>, and matching keeps one convention in the file.
When the editor links the preset, it saves the complete var() expression:
--heading-size as a property value.
Make presets responsive
Keep the saved content linked to one variable and change the variable in the cascade:var(--content-gap) now adapts without separate mobile and desktop content.
Control typography
Each typography preset can resolve size, family, and weight independently. For the schema rules behind these presets — which group becomes preset cards, what separates a preset from a font or a weight, and which setting types the theme panel renders — see writing settings schema. For new size settings, userole: "heading" or role: "body". Existing setting IDs that begin with font_size_h continue to behave as headings when no role is present.
Use explicit references when a size preset should follow separate font settings:
- Family: explicit reference, literal value, then the font for the setting’s role.
- Weight: explicit reference, literal value, then the default for the role.
- Size: the setting value and its
unit, defaulting topx.
var(--heading_size_font_family) — named for the preset, not for the font it uses today. Repointing the preset to another font rewrites that one declaration, and every piece of content already styled with it follows. Read the same variable in your own CSS, with the referenced setting as a fallback:
var(--heading-font) alone is the most common reason a merchant repoints a preset and the theme’s own headings do not move.
Understand value precedence
The editor chooses the first available value:- An unsaved value in the theme panel
- The saved theme value
- The setting’s schema default
- The editor fallback
Unsaved values reach the text and color preset menus in the rich-text toolbar, so those follow live theme edits before you save. The corner-radius, spacing, and section-level color controls read saved values, so a new setting or a changed value appears there only after you save the theme.
Link radius and padding
Put radius and spacing settings in thecorner_radius and padding groups. Declare a CSS variable for each setting:
var(--card-radius) and var(--section-gap). A linked all-sides control applies the selected preset to every side or corner.
Unlink a preset
Choose Manual Settings in a preset menu when one content item needs a fixed value. The editor resolves the current CSS values and exposes the individual controls. Choose Link Variables to return to the theme-driven preset workflow. Add Preset saves the current values as a new preset instead.Troubleshoot linked presets
When a preset menu is empty, merchants apply values by hand and the content stops following the theme — so treat a missing variable as a bug in the theme, not a limitation of the editor.
For the broader configuration flow, see root theme configuration. For the schema shape these presets are built from, see writing settings schema.