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.

Flat editorial illustration showing a speedometer gauge with a rising needle, clean tick marks and small trailing dots.
Illustration: this article at a glance.

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

ChangeWhat happensThe fix
Inline error appearsA field grows, pushing everything below itReserve space or use a stable error slot
Autofill/autocomplete changes a select or fills a fieldThe select/DOM changes its heightFix the height up front; give autofilled text a stable line-height
reCAPTCHA / widget loadsA stub with a wildly different rendered heightGive 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:

<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:

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

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

  1. Record a lab run with the layout-shift recipe, fill the form slowly.
  2. Load with autofill enabled on desktop and mobile; measure the shift on the fields that autofill.
  3. Show and hide each inline error; confirm the text below the field never moves.
  4. 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.

Need a website built, fixed, optimised, migrated or replaced?

This technical resource is written by CSMBAC, a small design and development studio. If you would rather hand the problem to a professional, the website service page explains how we build enquiry-ready websites.

Explore website services