Layout best practice
Patterns that don't break — hierarchy, palette cap, padding cascade.
You've shipped a sample (B3) and a theme (B4). Now you'll meet the rules that keep both robust. These are distilled from THEME_BEST_PRACTICE.md (2800 LOC of audit history); the buyer-tier version below is what you need to ship and not regress.
The hierarchy is sacred
Every page is one of two stacks. Memorise both.
PageElement
└── BlockElement (a row)
└── ElementGroup
└── PElement | HeadingElement | ImageElement | ButtonElement | …- You can never put a leaf element directly inside
PageElement— it must be wrapped in aBlockElement. The Block owns the row's vertical rhythm. - You can never put a leaf element directly inside a
GridElement— it must be wrapped in aCellElementthen aBlockElement. Each column has its own internal stack. - You can never nest a Grid inside a Grid — break the inner Grid up into multiple Blocks, or use a single Grid with more cells.
Container width matrix
| Surface | Container width | Why |
|---|---|---|
| 600 px | Industry-standard since Outlook 2007. Wider than 600 risks horizontal scroll in Apple Mail / iOS narrow window. | |
| Form / checkout | 480 px | Forms read better at narrower widths — less eye-jump per field. |
| Landing page | 1200 px | Modern desktop reading width with adequate gutter. |
The shipped samples respect these widths via Page.template.html's outermost <table width> value. When you author a sample of a given kind, don't override the width unless you have a specific reason — buyers will see it in the wrong context (a 1000-px-wide email looks broken in Outlook).
Padding cascade
BlockElement carries the page's vertical rhythm:
The visual rhythm rule: rows should have uneven top/bottom padding only if they're acting as section separators (a hero row above + a body row below probably shares 20-30 px between them; a CTA row gets 30-40 px). Even padding (top = bottom) reads as a uniform stack; varied padding reads as deliberate sections.
The 4-colour palette cap
A sample (or theme) uses at most 4 distinct chromatic colours. Greyscale doesn't count toward the cap.
Acceptable: black, white, brand red, off-white grey, sub-text grey
└─ chromatic ─┘ └─ chromatic ─┘ └─── greyscale ───┘
That's 2 chromatic + 1 greyscale family. Pass.The 5-typography-tier cap
A sample uses at most 5 typography tiers. The canonical set:
| Tier | Font size (px) | Weight | Use |
|---|---|---|---|
| H1 | 32-36 | 700 | One per page. Hero headline. |
| H2 | 22-24 | 600 | Section heading. |
| H3 | 18 | 600 | Sub-section heading. |
| Body | 14-16 | 400 | Paragraphs. |
| Caption | 12 | 400 | Footer text, fine print. |
If you find yourself reaching for an 18 px H4 + a 16 px H5 in the same email, you've broken the cap. Fix: collapse to 4 tiers, or use one tier for both with bold/regular weight as the differentiator.
Edge alignment invariants
Every element edge in a Block must align with the page container's content edge OR with another element's edge. Three concrete rules:
- Headings + paragraphs are flush-left (or centered, for hero blocks). Never indented except via the Block's container padding.
- Images at full content width are flush-left + flush-right. If the image is narrower than content, it's centered.
- Buttons are centered or flush-left, never floating arbitrarily.
This is the difference between "designed" and "thrown together" — buyers spot the misalignment instantly even if they can't articulate why.
Explicit units
Every dimension is an integer in pixels. Never strings:
When to use a Grid vs stacked Blocks
Use a GridElement when:
- The row has logically parallel content in N columns (image + text split, 3-up product gallery).
- Each column has its own vertical rhythm (multi-block content per column).
Use stacked BlockElements when:
- The content is sequential down the page (most emails — hero → body → CTA → footer).
- One row would feel artificial if columned (a single CTA button below a hero is a Block, not a 1-column Grid).
When in doubt: stack Blocks. Grids cost more rendering (more EJS template invocations, more nested HTML), so don't reach for them when a Block does the job.
Common mistakes the audit catches
"My sample looks fine on desktop, broken on mobile" — almost always a fixed-pixel width on a Grid or an Image that exceeds 600 px. Email clients don't responsively scale by default; your samples must be designed for the narrowest realistic viewport.
"My new theme renders correctly but is rejected by Litmus's 22-client matrix" — you probably edited
Page.template.htmland dropped a Outlook-conditional comment block. Restore the original wrapper structure; brand changes go informatsoverrides."My H1 + H2 + H3 + H4 are all defined and the sample renders weird" — you've broken the 5-tier cap. Pick 5; promote the others to bold variants of an existing tier.
"My gradient background looks great in DevTools but ghosts in Outlook" — Outlook ignores most CSS3. Use solid colours for backgrounds; if you need a gradient, bake it into a hero image, not a CSS rule.
Did you make it?
You should now be able to:
- ✅ Recite the two valid hierarchy stacks without looking.
- ✅ Pick container width by surface (email vs form vs page).
- ✅ State the 4-colour + 5-typography caps + the units rule.
- ✅ Decide between Grid vs stacked Blocks by content shape.
What's next?
- → Build a custom Element ⭐ — graduate from theme to engine: subclass BaseElement and ship a Countdown component.
- 🔗
THEME_BEST_PRACTICE.md— the canonical 2800-LOC rule library this doc distils.