Reference guide · performance · Published 2026-08-16 · 4 min read
Preventing layout shift in forms
Forms and CLS: reserve field heights, stable inline errors, autofill and reCAPTCHA shifts, and the test steps that keep forms from jumping.
- ·The three jump points
- ·Reserve and stabilise
- ·Message patterns
Why forms shift
Forms are CLS magnets because their content is often unknown until the browser paints: error messages appear, autofill enlarges a select, reCAPTCHA loads with its own height, and a disabled submit becomes an enabled one with a different size. Each of those changes the vertical layout, and CLS counts every one. The layout shift metric punishes the total, and because forms sit at checkout and signup, a bad shift there travels through the whole funnel.
The three jump points
| Change | What happens | The fix |
|---|---|---|
| Inline error appears | A field grows, pushing everything below it | Reserve space or use a stable error slot |
| Autofill/autocomplete changes a select or fills a field | The select/DOM changes its height | Fix the height up front; give autofilled text a stable line-height |
| reCAPTCHA / widget loads | A stub with a wildly different rendered height | Give it a reserved height and place it out of the flow |
Reserve, don't rearrange
The principle for forms is the same as for images: let the browser know the size before the paint. Reserve each field's box:
.form-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
}
Two concrete reserves that avoid the jump:
- Preview content: a caption that can appear under an image sets
min-heighton the caption<div>, so the image does not move when the caption loads. - Error slot: give the error paragraph a fixed
min-heightunder the field, andaria-live="polite"so screen readers announce the change without a reflow:
<p class="field-error" aria-live="polite" style="min-height: 1.4em"></p>
An empty but sized slot holds zero visual weight, and the incoming message changes text, not layout.
The inline-validation trade-off
Inline validation that toggles a message or an icon in position: relative keeps the field at the same height, but text-based errors below the field get the layout difference. Decide once:
- Show errors inside the field's existing space (an icon + tooltip in the reserved corner) so no new height is created.
- Or show below in a fixed-height slot (the pattern above). Never mix: an error that appears below then moves next to the field causes a second shift.
Any error state that changes the field's border thickness, font weight, or the position of the label shifts in exactly the way the CLS formula punishes, because the position changed even if the page did not re-render the network request.
Autofill and the browser widget
- Autofill text can grow a field's height only if the field lacks
overflow. Keep fields at a fixed font size and set the sameline-heightfor the autofill pseudo-element, or the form jumps when a browser fills four fields at once. - Login forms with autofill are the classic repeated offender; measure before and after a form fill with a
beforeinputlistener logging the layout shift. autocomplete="off"is often ignored by browsers that autofill by design (Chrome and Safari refill payment and login). The stable-spacing fix works where the attribute does not.
reCAPTCHA and third-party elements
reCAPTCHA and its siblings introduce an iframe whose height is never known ahead of time. Reserve a min-height on the wrapper that matches the widget (about 78 px for the reCAPTCHA v2 checkbox) and center the badge; if the vendor changes the box, a wrapper:empty style keeps the placeholder gap consistent. The third-party script article explains why that iframe also loads mainly on the LCP path, so the reserve-and-load style wins twice.
Verify
- Record a lab run with the layout-shift recipe, fill the form slowly.
- Load with autofill enabled on desktop and mobile; measure the shift on the fields that autofill.
- Show and hide each inline error; confirm the text below the field never moves.
- Load a page with reCAPTCHA disabled in an ad-blocker context and confirm the reserve keeps the layout.
The form-specific impact of a stable layout is a direct input to the set of images and fields that make a page shift. The accessible-form patterns article is the sibling that keeps the stable markup accessible, and the web vitals reference explains the counting rule that makes the above fixes matter.