Browse the docs ▾

Agent guides

Design responsive pages

Good results come from a few decisions made early, and from knowing how styles behave at each screen width.

Decide the design before the ops

Write a short design direction before building: who the site is for, one main action, a palette, a type pairing and a spacing rhythm. Avoid defaults that make every site look alike. Choose fonts and colours that suit this business, and repeat a small set of sizes throughout.

How breakpoints work

set_style writes to common, desktop, tablet, mobile, hover or focus, which shows while a field, button or link has the keyboard's focus. Desktop, tablet and mobile values override common, and builder-made nodes often have all of them. So a change sent only to common can seem to do nothing.

Same value everywhere

breakpoints: ["desktop","tablet","mobile"] in one op.

Different layouts

One op for each group of breakpoints.

Clearing a value

Send value: null for that breakpoint.

Reading what's there

get_node shows a node's styles per breakpoint.

Set shared styles first

set_theme

Brand colours, fonts, corners and button style. Prefer it to set_token for brand colours, as shades follow.

Text styles

add_text_styles in set_theme, up to 10 in a call. Apply them with set_style_links text_style.

Text colour

A text's colour isn't a style. Use set_style_links color_key.

Tokens in set_style

{colors.primary} is written as its value at that moment, so a later theme change won't reach it. Style links and theme colour keys do follow the theme.

Fonts

A text style can't use a font added in the same set_theme op. Add the font in an earlier op.

Page background

The theme's background colours the sections. The cart, checkout, sign-in, order and policy pages keep the shop's light grey.

Layouts that stack

Columns

add_element kind: "columns" with 2, 3, 4, 6, 1-2 or 2-1.

Grids

display: "grid" and gridTemplateColumns, with one column on phones.

Rows of items

display: "flex" and flexWrap: "wrap", with gap.

Placing items

flex, flexGrow, flexBasis, order, gridColumn, gridRow, gridTemplateRows and gridAutoFlow place items in a row or a grid.

Limited width

maxWidth with marginLeft and marginRight set to auto.

Fluid sizes

clamp(), min() and max() work in lengths and text sizes.

Not allowed

calc(), url(), var() and !important. They are refused.
get_element_catalogue lists every accepted property, and which ones do nothing on a text or an image. Effects work within limits: transform scales up to 3, filter blurs up to 40px, and set_background takes up to 3 gradient layers, radial and striped ones too.

Pictures

objectFit: "cover" with a fixed height keeps images in a row level. Use set_settings load: "page_load" for the picture at the top of a page, and leave the rest lazy. Give each image meaningful alt text with set_image.

Text

A phone needs comfortable size, not just a smaller desktop. Keep body text at 16px or more, watch long headlines on narrow screens, and limit line length to around 70 characters on desktop. Use WebkitLineClamp to keep card summaries level.

Checks before you call it done

1

One clear heading and main action in the first screen, on desktop and phone.

2

Nothing overflows sideways at phone width.

3

Text contrast holds on every background, including over images.

4

Tap targets are large enough, and the phone menu has every link.

5

Spacing is consistent between sections, and across pages.

6

No sample words or placeholder pictures remain.
A child with its own background covers its parent's. If a set_background seems to do nothing, check the children, then take a screenshot.

One layout, three widths

{ "op": "set_style",
  "ref": "home/features/row",
  "property": "gridTemplateColumns",
  "value": "repeat(3, 1fr)",
  "breakpoints": ["desktop"] }

{ "op": "set_style",
  "ref": "home/features/row",
  "property": "gridTemplateColumns",
  "value": "repeat(2, 1fr)",
  "breakpoints": ["tablet"] }

{ "op": "set_style",
  "ref": "home/features/row",
  "property": "gridTemplateColumns",
  "value": "1fr",
  "breakpoints": ["mobile"] }

Fluid section padding

{ "op": "set_style",
  "ref": "home/features",
  "property": "paddingTop",
  "value": "clamp(48px, 8vw, 112px)",
  "breakpoints": [
    "desktop", "tablet", "mobile" ] }