Appearance
Formula Styling
Style every visual detail of a Formula option — how the measurement fields are grouped and laid out, the boxes customers type into, units, labels and range hints, optional stepper buttons, and the calculated result shown under the fields — using per-type templates.
Overview
Read Types Settings first if you haven't created a template before. In the Style Settings modal this type is labeled Formula.
The editor's left navigation has 8 sections, in this order: Field layout, Separator, Input (Structure, Typography, Colours), Unit, Labels & hints, Stepper controls, Calculation (Breakdown, Empty state), and Responsive — matching the sections below.
The measurements aren't here — but the layout is
Each field's name, unit, Lowest, Highest, decimals and default, the formula, the result unit and the pricing all belong to the option itself — configure them on the option (see Formula). The template only controls how they're shown.
It works the other way for layout: Fields per row, and how the fields rearrange on phones, live only here, in the template — not on the option.
Three states: Idle, Focused and Error
A measurement field has nothing to hover or select, so the states you style are Idle, Focused (the field the customer is typing in) and Error (an invalid value). All three are on the same pane under Input → Colours, each under its own heading — there's no state switcher to click through.
A new template starts from your shop's Global styles: text, input background and input border colors seed from your Colors, and border width, input corner radius and shadow from Borders & Shapes. The Focused and Error backgrounds and the Focused border are derived from those colors so each state differs from Idle out of the box; the Error border is a fixed red. The defaults listed below are what you get when the matching Global value isn't set.
What a Formula template doesn't style
The option's own title above the fields and its help text are not part of the template. The title follows your Global styles, and help text follows the store-wide Help Text Display Mode. The Label settings below style each measurement field's name (Width, Height…), not the option title.
Contrast warnings
Many color fields warn when the color would be hard to see against what's behind it — for example "Low contrast with … Text needs 4.5:1 to stay readable." for text, and "… Icons and indicators need 3:1 to stay visible." for separators, stepper icons and focus indicators. The check follows your current layout, so the same color can warn in one grouping and not another.
Field Layout
The structural choices. Pick Field grouping and Direction first — they decide which settings appear in several other sections.
| Setting | Options (default) | What it controls |
|---|---|---|
| Field grouping | Separate (default) / Joined | Separate gives each measurement its own bordered box. Joined joins the boxes into one strip, divided by thin lines. In-app help: Separate gives each measurement its own bordered input. Joined joins the inputs into one strip, divided by thin lines. Where the fields stack, the labels move inside the boxes and the hints below the strip. |
Separate only
| Setting | Options (default) | What it controls |
|---|---|---|
| Gap between fields | 0–32px (12px) | Space between the fields, across and down |
Joined only
| Setting | Options (default) | What it controls |
|---|---|---|
| Divider colour | color (#e5e7eb, from your Global Input Border) | The lines between the boxes |
| Divider thickness | 1–4px (1px) | Thickness of those lines |
| Border width | 0–4px (1px, from your Global General Border) | The strip's outer edge |
| Border colour | color (#e5e7eb, from your Global Input Border) | Color of the outer edge |
| Corner radius | 0–30px per corner (8px, from your Global Input Radius) | Rounding of the strip's outer corners |
How Joined handles labels and hints
In a row, the labels sit above the strip and each range hint sits below its own box. Wherever the fields stack instead — Direction Column, a fixed Fields per row with more fields than fit on one row, a phone layout that stacks them, or the fit check — the strip stays one block: each label moves inside its box, and the range hints and error messages gather below the whole strip, each starting with its field's name (for example Width: 10–300 cm).
Direction
| Setting | Options (default) | What it controls |
|---|---|---|
| Direction | Row (default) / Column | Row puts the fields side by side. Column stacks them one per row, each the full width |
| Fields per row | Automatic (default) / 2 / 3 — Row only | In-app help: Automatic lets the fields share the row evenly. A fixed count wraps them onto a grid. |
| Field width | Equal (default) / Fit content — Row with Fields per row Automatic only | Equal gives every field the same share of the row. Fit content keeps each field only as wide as its longest value needs (worked out from its Highest and decimals, between about 3 and 16 characters), so the fields don't stretch to fill the row |
Fields per row counts columns, not fields
A template doesn't know how many fields each option turns on. With 3 per row, a two-field option leaves the third column empty. With 2 per row, a three-field option puts the third field on a second row (in Joined, that last box stretches across the row so the strip stays a rectangle). If one template is shared by options with different numbers of fields, Automatic is the safe choice.
Separator
The mark drawn between fields — × by default. It's only drawn between Separate fields sharing one row, so the pane shows a sentence instead of the controls in every other layout:
- Direction: Column — the section is marked not applicable: Separators sit between fields laid out in a row. Set Field direction to Row to style them.
- Field grouping: Joined — Joined fields are divided by the dividers between their boxes (under Field layout), not by separators. Set Field grouping to Separate to style them.
- Fields per row: 2 or 3 — Separators sit between fields in a single row, and a fixed Fields per row puts the fields on a grid. Set Fields per row to Automatic to style them.
Your separator settings are kept and come back when you return to Separate, Row, Automatic.
| Setting | Options (default) | What it controls |
|---|---|---|
| Separator | None / Multiply (default) / Dot / Custom | Multiply draws ×, Dot draws ·, Custom draws your own text. In-app help: Drawn between fields laid out in a row. Two fields have one separator, three have two. |
| Separator text | text, up to 3 characters (empty — the box shows e.g. by as an example) — Custom only | The text drawn between the fields |
| Separator colour | color (#9ca3af, from your Global Text) — not shown for None | Color of the separator |
| Separator size | 8–24px (14px) — not shown for None | Size of the separator |
The separator lines up with the middle of the boxes, not the labels above them. It's also hidden whenever the fields wrap or stack on the storefront — on phones (see Responsive) or when the fields are too narrow (see Fields that don't fit).
Input
The boxes customers type into, in three panes.
Structure
| Setting | Options (default) | What it controls |
|---|---|---|
| Height | Automatic (default) / Custom | Automatic works the height out from the padding and font size |
| Height | 28–64px (40px) — Custom only | Minimum height of each box |
| Padding | 0–24px per side (8px top and bottom, 12px left and right) | Space between the box's edge and the value |
| Text alignment | Left (default) / Centre / Right | Alignment of the typed value (and of an Inside label) |
Separate only — in Joined these come from the strip's settings under Field layout instead:
| Setting | Options (default) | What it controls |
|---|---|---|
| Border width | 0–4px (1px, from your Global General Border) | Each box's border |
| Corner radius | 0–30px per corner (8px, from your Global Input Radius) | Each box's corner rounding |
| Shadow | No Shadow (default) / Subtle / Medium (from your Global Shadow) | Drop shadow under each box |
Typography
| Setting | Options (default) | What it controls |
|---|---|---|
| Font size | 8–28px (14px) | Size of the typed value |
| Font weight | Light / Regular (default) / Medium / Semibold / Bold | Weight of the typed value |
| Tabular figures | toggle (on) | In-app help: Gives every digit the same width, so the value stops shifting as the shopper types. It applies to the numbers in the calculated result too |
Colours
Three headings on one pane. Idle is the resting field, Focused is the field the customer is typing in, Error is a field with an invalid value.
Idle
| Setting | Options (default) | What it controls |
|---|---|---|
| Text colour | color (#1f2937, from your Global Text) | The typed value |
| Background | color, transparent allowed (#ffffff, from your Global Input Background) | Box fill (in Joined, the whole strip's fill) |
| Border colour | color, transparent allowed (#e5e7eb, from your Global Input Border) — Separate only | Box border. In Joined the strip's Border colour and Divider colour take its place |
Focused
| Setting | Options (default) | What it controls |
|---|---|---|
| Text colour | color (#1f2937, from your Global Text) | The typed value while focused |
| Background | color, transparent allowed (#f9fafb — your Global Input Background shifted slightly toward your Text color) | Box fill while focused |
| Focus indicator | Ring (default) / Border | How a focused field shows focus — one indicator, never two. The fields below switch with it |
| Ring width | 1–4px (2px) — Ring only | Ring thickness |
| Ring colour | color (#3b82f6) — Ring only | Ring color |
| Border colour | color, transparent allowed (#6b7280 — your Global Text color eased toward your Input Background) — Border only | The border (Separate), or a line just inside the box's edge (Joined), while focused |
- Ring draws a ring around the focused box and leaves the border at its Idle color. In Separate the ring sits just outside the box; in Joined it's drawn just inside the box's edge, so the neighbouring box can't cover it.
- Border changes the border (or, in Joined, the inside line) to the Focused Border colour, with no ring.
Border can still add a ring
If the Focused Border colour is too faint to see on its own, the store's own focus ring is added around the field so keyboard users can still see where they are. The pane says so under the color: If this colour is too faint to show focus on its own (below 3:1), your store's focus ring is added around the field so keyboard users can still see where they are. Pick a stronger colour to drop it. The same happens with a transparent focus border, or a Border width of 0 in Separate.
Error
| Setting | Options (default) | What it controls |
|---|---|---|
| Text colour | color (#1f2937, from your Global Text) | The typed value while invalid |
| Background | color, transparent allowed (#f9fafb — derived like the Focused background) | Box fill while invalid |
| Border colour | color, transparent allowed (#dc2626) | The border (Separate), or a line just inside the box's edge (Joined), while invalid |
| Tint background | toggle (off) | In-app help: Washes the input with the error colour instead of a separate background colour. With it on, the Error Background above isn't used |
Why the text color starts the same in all three states
The border, ring and background carry the state; the typed value stays your Global text color so it stays readable — including on a dark storefront. When a field is both invalid and focused, it keeps the Error colors and still shows focus: the ring with Ring, or a 1px thicker error line with Border.
A field switches to its Error colors once its value is invalid — after the customer has typed in it or left it, or when they press Add to cart with a required field empty. The message text is styled under Labels & hints → Errors.
Unit
Where each field's unit (cm, in…) appears. The unit text itself is set per field on the option.
| Setting | Options (default) | What it controls |
|---|---|---|
| Unit placement | Inside (default) / Add-on / In label / Hidden | In-app help: Where the field's unit appears. Display only — no conversion is applied anywhere. |
- Inside — the unit sits inside the box at its right end, after the value.
- Add-on — the unit sits in its own shaded block attached to the right end of the box.
- In label — the unit is added to the field's label (for example Width (cm)), and the box holds only the number.
- Hidden — no unit next to the field.
Inside and Add-on
| Setting | Options (default) | What it controls |
|---|---|---|
| Unit colour | color (#6b7280, from your Global Text) | Unit text color |
| Unit size | 8–20px (13px) | Unit text size |
| Distance from edge | 4–24px (12px) — Inside only | Space between the unit and the box's right edge |
Add-on only
| Setting | Options (default) | What it controls |
|---|---|---|
| Add-on background | color, transparent allowed (#f3f4f6) | The add-on block's fill |
| Add-on border | toggle (on) | A line between the value and the add-on |
| Add-on border colour | color (#e5e7eb, from your Global Input Border) — Add-on border on | Color of that line |
| Add-on padding | 0–20px per side (8px top and bottom, 12px left and right) | Space inside the add-on block |
In label only
| Setting | Options (default) | What it controls |
|---|---|---|
| Label format | Width (cm) (default) / Width – cm / Width cm | How the unit is joined to the label |
| Unit colour in label | color (#6b7280) | The unit's color inside the label |
Hidden only hides it beside the field
Hidden removes the unit from the box and the label, nothing else. It still appears in the range hint (10–300 cm), in the calculated result's measurements, and on the cart line. A field with no unit set shows none, whichever placement you pick.
Labels & Hints
One pane with three parts: each field's label, its range hint, and error messages.
Label
| Setting | Options (default) | What it controls |
|---|---|---|
| Label position | Above (default) / Inside / Left / Hidden | Where each field's name sits |
- Above — the label sits above its box.
- Inside — the label sits inside the box, on one line above the value, and follows Text alignment.
- Left — the label sits beside its box, in a column as wide as Label width. In Joined, the label is drawn inside each box, before the value.
- Hidden — no visible label. Screen readers still announce it.
Above isn't offered in a joined column
In Joined with Direction Column, Above and Left would look the same, so Above is hidden (a template that already stores Above shows Left selected). The pane explains: In a joined column the labels sit inside the boxes, so Above is not offered. Left lines the values up at the label width; Inside puts a smaller label above each value.
| Setting | Options (default) | What it controls |
|---|---|---|
| Label width | 40–200px (70px) — Separate with Left; Joined with Above or Left | Separate: width of the label column beside each box. Joined, in-app help: When the fields stack one per row, the labels inside the boxes line up at this width. |
| Gap to input | 0–16px (6px) — not shown for Hidden | Space between a label and its value: below an Above label, beside a Left label, above the value for Inside |
| Label size | 8–24px (13px) — not shown for Hidden | Label text size |
| Label weight | Light / Regular / Medium (default) / Semibold / Bold — not shown for Hidden | Label text weight |
| Capitalisation | None (default) / Uppercase / Capitalise — not shown for Hidden | Label letter case |
| Label colour | color (#374151, from your Global Text) — not shown for Hidden | Label color |
Long labels
In Separate, Above and Left labels wrap onto more lines. In Joined, labels above the strip stay on one line and are cut off with "…" if they don't fit, so the boxes stay in line. Inside labels are always one line.
Hints
The range hint is built from each field's Lowest and Highest on the option, plus its unit: 10–300 cm, 10+ cm with no Highest, ≤ 300 cm with no Lowest. A field with neither has no hint.
| Setting | Options (default) | What it controls |
|---|---|---|
| Range hint | None / Below field (default) / In field | In-app help: Where each field's minimum and maximum are shown, for example 30–300 cm. In field shows it as the empty box's placeholder text |
| Hint size | 8–18px (12px) — Below field only | Hint text size |
| Hint colour | color (#6b7280, from your Global Text) — Below field only | Hint text color |
In field disappears once there's a value
In-app note: Shown as the field's placeholder, so it disappears once the field has a value — including a default value. Use Below field if your fields start with defaults.
Errors
| Setting | Options (default) | What it controls |
|---|---|---|
| Error colour | color (#dc2626) | Error message text — both the message under a field and the message under the whole option |
| Error size | 8–18px (12px) | Error message size |
Messages always appear below the field — there's no tooltip choice. A field's own message (for example Enter 300 or less) sits under its box; a message about the whole option (for example These measurements can't be calculated. Check the values.) sits under all the fields. Errors don't show on a field the customer hasn't reached yet. See Error Messages for the full list.
Stepper Controls
Optional buttons that nudge a field's value up or down.
| Setting | Options (default) | What it controls |
|---|---|---|
| Stepper buttons | None (default) / Attached / Side buttons / Arrows | Optional buttons that raise or lower the value by 1 |
- Attached — − and + buttons inside the box at either end, divided from the value by thin lines and enclosed by the same border.
- Side buttons — round − and + buttons outside the box, one on each side.
- Arrows — ▲ and ▼ stacked at the right edge, inside the box.
| Setting | Options (default) | What it controls |
|---|---|---|
| Icon colour | color (#6b7280, from your Global Text) — not shown for None | The −, +, ▲ and ▼ |
| Button size | 20–48px (32px) — not shown for None | Button size; the icon scales with it |
| Button background | color, transparent allowed (transparent, from your Global Input Background) — Attached and Side buttons | Button fill |
| Divider colour | color, transparent allowed (#e5e7eb, from your Global Input Border) — Attached and Arrows | The line between the buttons and the value |
Each press moves the value by one whole unit (120 → 121) and stops at the field's Lowest and Highest; a value never goes to 0 or below. On an empty field, + starts at the field's Default (or its Lowest) and − does nothing. Customers type anything finer than a whole unit.
Arrows are half height
The two arrows share one button's height, so each is half as tall as Button size — 16px at the default 32px. For a touch-friendly control use Attached or Side buttons, or raise Button size.
Attached buttons follow the field's state
On a fresh template the attached buttons share the box's fill, so they take the Focused and Error backgrounds along with it. Give them a different Button background and they keep that color in every state.
Calculation
The result shown under the fields, in two panes: Breakdown and Empty state.
What the readout shows
The readout depends on the option's pricing as well as the template. With 120 cm × 80 cm, formula x * y / 10000 and result unit m²:
| Breakdown | No pricing | Add fee or Link variant ($45.00) |
|---|---|---|
| Inline | Calculated result, then 0.96 m² | Calculated result, then 0.96 m² (+$45.00) |
| Rows / Card | Calculated result, then a row: 120 cm, 80 cm … 0.96 m² | The same, plus a Price row: Price … $45.00, with a divider above it |
The heading is the template's Result heading. In Rows and Card, each row has a label on the left (the measurements entered, or Price) and a value on the right. The result shows at most 4 decimal places. The price is the option's fixed price — it doesn't change with the measurements, and no per-unit rate is shown.
Breakdown
| Setting | Options (default) | What it controls |
|---|---|---|
| Show measurement | toggle (on) | The calculated result (and its heading) |
| Show price | toggle (on) | The option's price beside or below the result. Off leaves the price to the product price and the totals below the form. On an option with No pricing there's no price to show either way |
| Result heading | text, up to 60 characters (Calculated result) — Show measurement on | In-app help: Shown above the calculated result. Leave it empty to hide it. |
| Breakdown | Inline (default) / Rows / Card — while Show measurement or Show price is on | In-app help: How the measurement and its price are laid out below the fields. Inline puts everything on one line under the heading. Rows stacks label and value pairs. Card is Rows on its own bordered panel |
With both switches off the rest of the pane is replaced by a note: Nothing is shown below the fields. Turn on Show measurement or Show price to show the result; the option still calculates and still charges.
A fourth "Hidden" card
Breakdown can also show a Hidden card, but only on a template that already has it selected, so you can move off it. For a new template, turn both switches off to remove the readout — or use Breakdown on mobile → Hidden under Responsive to remove it on phones only. Either way the option still calculates, still charges, and still records the measurements on the cart line.
Card only
| Setting | Options (default) | What it controls |
|---|---|---|
| Card background | color, transparent allowed (#f9fafb, from your Global Input Background) | Panel fill |
| Card border width | 0–4px (1px, from your Global General Border) | Panel border |
| Card border colour | color (#e5e7eb, from your Global Input Border) | Panel border color |
| Card corner radius | 0–24px per corner (8px, from your Global Input Radius) | Panel corner rounding |
| Card padding | 0–32px per side (12px top and bottom, 16px left and right) | Space inside the panel |
Rows and Card (also with Breakdown on mobile set to Rows) — Show measurement on
| Setting | Options (default) | What it controls |
|---|---|---|
| Row spacing | 0–16px (6px) | Space between rows |
| Divider above price | toggle (on) — Show price on | A line above the Price row |
| Divider colour | color (#e5e7eb, from your Global Input Border) — Divider above price on | Color of that line |
Spacing and typography — shown whenever the readout has something in it
| Setting | Options (default) | What it controls |
|---|---|---|
| Spacing around | 0–32px per side (12px top, 0 elsewhere) | Space around the readout — the top value is its distance from the fields |
| Font size | 8–20px (13px) | Size of the heading, labels and result |
| Label colour | color (#6b7280, from your Global Text) — Show measurement on, or Rows and Card | The heading and the row labels |
| Value colour | color (#1f2937, from your Global Text) — Show measurement on | The calculated result |
Price — Show price on
| Setting | Options (default) | What it controls |
|---|---|---|
| Emphasise price | toggle (on) | Gives the price its own size and weight |
| Price size | 10–28px (16px) — Emphasise price on, Rows and Card only | Price text size. Inline keeps the price on the result's line at the readout's Font size |
| Price weight | Regular / Medium / Semibold (default) / Bold — Emphasise price on | Price text weight |
| Price colour | color (#111827, from your Global Text) | Price color, with or without emphasis |
The Price settings apply to every option using the template
A template doesn't know whether an option is priced. On an option with No pricing, the Price settings simply have nothing to style.
Empty State
What the readout area shows before the customer's measurements give a result — while a field is still empty, or while a value is invalid. Not available while Breakdown is Hidden.
| Setting | Options (default) | What it controls |
|---|---|---|
| Before all fields are filled | Show nothing / Show a prompt (default) / Dim the readout | In-app help: What the breakdown shows while the shopper still has a measurement to enter. |
| Prompt text | text, up to 60 characters (Enter your measurements to see the result) — Show a prompt only | The prompt shown under the fields |
| Prompt colour | color (#9ca3af, from your Global Text) — Show a prompt only | Prompt color |
| Dim amount | 10–90% (40%) — Dim the readout only | The faded readout's opacity — a lower value is fainter |
- Show nothing — nothing appears under the fields until there's a result.
- Show a prompt — your prompt text appears in place of the readout, at the readout's Font size and Spacing around.
- Dim the readout — the readout is shown faded, with — in place of the result and no price until there is one. This card is hidden while Show measurement is off, because there'd be nothing to dim (a template that already stores it shows Show nothing selected).
Responsive
Overrides for phones — screens 768px wide and under.
| Setting | Options (default) | What it controls |
|---|---|---|
| Direction on mobile | Same as desktop (default) / Column — desktop Direction Row only | Column stacks the fields one per row, full width, on phones |
| Fields per row on mobile | Automatic (default) / 1 / 2 — desktop Direction Row, with Direction on mobile Same as desktop | 1 or 2 puts the fields on a grid on phones. Automatic keeps the desktop layout |
| Font size on mobile | 8–28px (empty) | The typed value's size on phones. In-app help: Leave empty to use the desktop size. |
| Breakdown on mobile | Same as desktop (default) / Rows / Hidden | Rows shows the readout as rows on phones — from an Inline desktop it switches to rows, from a Card desktop it drops the panel. Hidden removes the readout on phones only |
With a desktop Direction of Column the fields are already stacked on phones, so only Font size on mobile and Breakdown on mobile are shown.
When the phone layout stacks or grids the fields, the separators between them are hidden. With Same as desktop and Automatic, the desktop row is kept on phones, separators included — unless the values don't fit (below).
Fields That Don't Fit
On the storefront, and in every preview, each field is measured against what it actually shows: the value typed, or while it's empty, its In field hint (or a single digit). If any field is too narrow for that:
- Three fields first wrap two to a row, with the third underneath
- If those are still too narrow, every field gets its own row
Two fields go straight to one per row. Separators are hidden while the fields are wrapped or stacked, and Joined stays one strip. The check runs again as the customer types and as the screen resizes, so a long value can step the row down and deleting it brings the row back. It applies at every screen width, with or without a template, and takes priority over the layout you've picked.
Wide gaps, units and steppers use up the row
Three fields with units, stepper buttons, a large Gap between fields or a Left label column all take width away from the values. If a layout keeps stepping down in the narrow preview, try the Mobile device preview or a wider Custom width to see how it behaves at real product-page widths.
Options Without a Template
A Formula option left on Global styles renders with these built-in defaults: separate boxes side by side in one row with × between them, the unit inside each box, labels above, the range hint below each box, and no stepper buttons. Boxes use your Global input background, input border and input radius. Underneath, the readout is Inline with the heading Calculated result — 0.96 m², or 0.96 m² (+$45.00) when priced — and before there's a result it shows Enter your measurements to see the result.
On screens 480px wide and under, the fields stack one per row and the separators are hidden. (With a template, phones follow the Responsive settings instead.) The fit check applies too.
To change the heading or the prompt text, or anything else here, assign the option a template.
How to Style Formula
- Open the Style Settings modal (see Customization Overview)
- Click Types → Formula
- Create a new template or click an existing one to edit it
- Set Field grouping and Direction under Field layout first — they decide which settings the Separator, Input, Labels & hints and Responsive sections show
- Use the left navigation to jump between Field layout, Separator, Input, Unit, Labels & hints, Stepper controls, Calculation, and Responsive
- Set each state's colors under Input → Colours — Idle, Focused and Error are all on that one pane
- Switch the Live Preview to Mobile to check your Responsive settings
- Click Manage preview above the Live Preview to change the measurements it shows — see Sandbox & Live Preview
- Click Save in the contextual save bar
Assign the template on the option itself: open a Formula option, click Style Settings, and pick a template card (or Global styles). Then save the option set.
Related
- Formula (option type) — how to add a Formula and configure its fields, formula and pricing
- Types Settings — how templates work and how to assign one to an option
- Sandbox & Live Preview — preview test measurements while styling
- Help Text Display Mode — how the option's help text is shown
- Accordion Styling
- Checkbox Styling
- Radio Styling
- Swatches Styling
- Tabs Styling
- File Upload Styling
- Slider Styling
- Date Range Styling
- Time Picker Styling
- Modal Styling
- Short Text Styling
- Short Text Group Styling