Skip to content

UX Strategy

Landing page audit: find the friction that stops visitors acting

Audit a landing page for the friction that stops visitors acting: unreachable buttons, unlabelled forms, slow loads and blocking overlays.

Your UX Agent teamProduct
15 min read

A landing page audit looks for what stops a visitor who already wants to act. The button is covered or too small to tap. The form hides what it wants, or what went wrong. The page loads late or jumps. A banner will not let them past.

Each of these can be checked on the live page and fixed in code. Below is a friction checklist, a fix for each defect, and which kind of testing can find it.

How to run a website UX audit covers the same work across a whole site, from templates to re-checks.

What a page audit can tell you

A landing page has one job: to turn a visit into an action, such as a sign-up, a booking or a download. Two kinds of problem get in the way.

  • Persuasion problems. The offer is unclear, the headline does not match the ad that brought the visitor, or the page does not earn their trust. The visitor never decides to act.
  • Defects. The visitor has decided, and the page stops them anyway: the button they reach for is under something, the form rejects them without saying why, the page moves as they tap.

This post is about defects. A defect has a place on the page or a measured value, and a known fix, and a re-check shows whether it is gone. Persuasion problems need other evidence, covered in what a CRO audit adds. Fix the defects first: testing a new headline tells you little while the button under it is covered on phones.

The friction checklist

Run each check in a real browser at a phone width and a desktop width, on the page as a new visitor meets it: a fresh private window, consent banner unanswered. In brackets is who can decide it: a tool, a person, or both. For the rest of the site, use the per-template checks in our UX audit checklist.

  • Main content appears quickly (both). The largest image or text block in view is painted within 2.5 seconds for at least three in four visits. A lab run guides; field data decides.
  • Nothing moves after it appears (both). Cumulative Layout Shift is 0.1 or less for at least three in four visits. A lab run sees only the shifts during load.
  • The call to action is uncovered (both). Nothing sits on top of the main button at any width, and it is on screen without scrolling sideways.
  • Text is readable (both). No banner, image or header is painted over it. A tool finds fully covered text; a person, partly covered text.
  • Focus is never fully hidden (both). A control reached with Tab is never entirely hidden by a sticky header, footer or banner (2.4.11).
  • The consent banner lets visitors past (both). It has a reject or necessary-only button, it closes, and nothing it leaves behind covers content. A person judges the wording.
  • Every button can be tapped (both). Each target is at least 24 by 24 CSS pixels or spaced well enough (2.5.8). A person judges the exceptions.
  • Every field has a visible label (both). Each field has a label or instructions (3.3.2), tied to the field in the markup (1.3.1). Keep the label in text that stays visible while you type, which a placeholder is not.
  • Errors say what went wrong (person). A rejected field is identified and the problem described in words (3.3.1). Submit the form empty, then with wrong values.
  • Fields fit the data (both). Fields for the visitor’s own details carry the matching autocomplete value (1.3.5), and an email field uses type="email".

The sections below take the defects in turn, with code. For the measurement itself, see how a browser measures covered controls, layout shift and tap targets.

The main content arrives late

Largest Contentful Paint is the moment the largest image or text block in view is painted. web.dev counts a page as good when it happens within 2.5 seconds, at the 75th percentile of page loads, on mobile and desktop separately. On a landing page it is often the hero image, and a common reason it is late is that the browser finds it late or is told to wait.

Before: the hero image waits for layout
<img src="/img/hero.jpg"  alt="Booking an appointment on a tablet"  loading="lazy">
After: the browser fetches it first, at the right size
<img src="/img/hero-1600.jpg"  srcset="/img/hero-800.jpg 800w,          /img/hero-1600.jpg 1600w"  sizes="100vw"  width="1600" height="900"  alt="Booking an appointment on a tablet"  fetchpriority="high">

Why it works: web.dev’s advice is “Never lazy-load your LCP image”, because a lazy image is requested only once layout shows it is near the viewport. fetchpriority="high" moves it ahead of other downloads; use it on one or two images at most, or it stops helping. The image is in the HTML, where the browser finds it at once, not in a CSS background, which it finds only after the stylesheet arrives. srcset lets the browser pick the smallest file that is sharp enough for the screen, and the width and height reserve its space.

Can a tool detect this? Partly. Our own rule core-web-vitals-lcp reports a Largest Contentful Paint over 2.5 seconds in a single throttled mobile lab run. A lab run is one load on one simulated device. The 2.5-second threshold is meant for real visits, which only field data from your own visitors shows.

The page moves while the visitor reaches for it

A visitor goes to tap the button, an image above it finishes loading, and the button drops away from their thumb. Cumulative Layout Shift measures this movement, and web.dev counts 0.1 or less as good. Two common causes are images with no dimensions and content inserted above what is already there, such as a promotion bar filled in after the page renders.

Before: nothing reserves space
<!-- a script fills this after load --><div id="promo"></div><img src="/img/product.png"  alt="The booking calendar on a phone">
After: the space is held before anything arrives
<style>  #promo { min-height: 48px; }  img { max-width: 100%; height: auto; }</style><div id="promo"></div><img src="/img/product.png"  width="640" height="480"  alt="The booking calendar on a phone">

Why it works: with width and height set, the browser knows the image’s proportions and holds its box until the file arrives; height: auto keeps them when the image is scaled down. The promotion slot has its height before the script fills it, so filling it pushes nothing. web.dev calls cookie notices at the top of the screen “a very common source of layout shift”, and suggests reserving their space or showing them as an overlay.

Can a tool detect this? Partly. Our own rule core-web-vitals-cls reports a Cumulative Layout Shift above 0.1 in the same lab run, and image-dimensions-missing reports images with no declared width and height. A lab load sees only the shifts that happen while it watches.

Something sits on top of the button or the text

At a phone width, things that sat side by side on a desktop start to overlap: artwork over the call to action, a chat launcher over the submit button, a sticky header over the section a link just jumped to. A tap on a covered button reaches whatever is on top.

Before: the artwork is stacked above the button
.hero { position: relative; }.hero-art {  position: absolute;  right: -40px;  bottom: 0;  width: 320px;  z-index: 2;}.hero-cta { position: relative; z-index: 1; }
After: the artwork sits behind, and in the flow on phones
.hero {  position: relative;  isolation: isolate;}.hero-art {  position: absolute;  right: 0;  bottom: 0;  width: min(320px, 40vw);  z-index: -1;}@media (max-width: 600px) {  .hero-art {    position: static;    width: 100%;    max-width: 320px;  }}

Why it works: isolation: isolate gives the hero its own stacking context, so z-index: -1 puts the artwork behind the hero’s content without dropping it behind the page. On a phone the artwork joins the normal flow (place it after the button in the HTML), so it cannot overlap it. For a sticky header that hides the target of an in-page link, such as “Book a demo” jumping to the form, reserve the header’s height:

A 72px sticky header no longer hides a jump target or a focused field
html { scroll-padding-top: 72px; }

Can a tool detect this? Mostly. Our own rule occluded-interactive reports a control in the screen the page opens on with another element over its centre, at each tested screen size. A control covered only at its edge, or lower down the page, is not reported. content-occluded reports text in the opening screen with something opaque painted over every line; partly covered text needs a person. Our focus-obscured rule presses Tab and reports a control covered at its centre and at four points near its corners as it takes focus (2.4.11). It runs after the consent banner is declined, so a banner hiding focus needs a person, and so does a section hidden after a jump.

The consent banner is often the first thing a visitor meets, and it can stop them in three ways. It offers no way to decline, so they accept or go looking for settings. It cannot be closed at all. Or, once closed, it leaves a floating cookie button on top of the content.

Before: accepting is a button, declining is a hunt
<div class="consent">  <p>We use cookies to improve    your experience.</p>  <button class="btn-primary">Accept all</button>  <a class="fine-print"    href="/cookie-settings">Manage settings</a></div>
After: both choices are buttons of the same weight
<div class="consent" role="region"  aria-label="Cookie choices">  <p>We use cookies for analytics.    You can accept or reject them.</p>  <button class="btn">Accept all</button>  <button class="btn">Reject all</button>  <a href="/cookie-settings">Choose by category</a></div>

Why it works: both choices use the same element and style, so declining takes one tap, like accepting, and the text says what the cookies are for. Reserve the banner’s space, or show it as an overlay such as a sticky footer, as web.dev suggests, rather than inserting it at the top without reserved space, where it pushes the page down. Whether a banner meets data-protection law is a separate question; this section covers only the friction.

Can a tool detect this? Yes, for the mechanics. Our own rules report a banner with no reject, decline or necessary-only action (consent-no-reject), one still there after repeated attempts to decline (consent-not-dismissable), and a floating consent control that covers content after the banner is gone (consent-widget-obstruction). A banner that covers much of the screen or stops scrolling before a choice is reported as advisory. Whether the wording is clear and fair needs a person.

Buttons too small to tap

Landing pages collect small targets: the close button on a pop-up, carousel dots, a tight row of social icons. 2.5.8 Target Size (Minimum) asks for at least 24 by 24 CSS pixels, or enough space that a circle 24 CSS pixels across, centred on each small target, does not overlap another target or another small target’s circle, with exceptions for an equivalent control, targets in a sentence or sized by the line height of the text around them, controls whose size the browser sets and the author has not changed, and a presentation that is essential or legally required. 2.5.5, at Level AAA, asks for 44 by 44.

Before: a 16px close button
.popup-close {  width: 16px;  height: 16px;  padding: 0;}
After: the icon stays 16px, the target grows
.popup-close {  display: inline-grid;  place-items: center;  min-width: 44px;  min-height: 44px;  padding: 0;}

Why it works: the target is the button’s box, not the icon inside it. Growing the box to 44 pixels clears both the 24-pixel minimum and the Level AAA size, and the design does not change.

Can a tool detect this? Mostly. Our own rule touch-target-minimum reports targets under 24 pixels that fail 2.5.8’s spacing test as measured findings, and small-touch-target reports targets under 44 pixels as advisory. axe-core’s target-size rule runs the same circle test in Level AA and AAA audits when axe is on, as it is by default. Our rule judges a target by its rectangular box; whether an equivalent control or the essential exception applies needs a person.

The form hides what it wants, or what went wrong

A landing page form is often short, and each field can still stop a visitor. A placeholder used as the label disappears once they start typing. An error shown only in red, or in a message nothing ties to the field, leaves them guessing what is wrong.

3.3.2 Labels or Instructions asks for labels or instructions where input is needed, but not that they are tied to the field in code; that is 1.3.1 Info and Relationships. 3.3.1 Error Identification asks that an automatically detected error identify the field and describe the problem in text; colour may add to the text, not replace it.

Before: a placeholder for a label, a vague error tied to nothing
<input type="text" placeholder="Email"><span class="error" style="color: red">Invalid</span>
After: a label, the right input type, and an error tied to its field
<label for="email">Work email</label><input id="email" name="email"  type="email" autocomplete="email"  aria-invalid="true"  aria-describedby="email-error"><p id="email-error" class="error">  Enter an email address with an @,  such as name@example.com</p>

Why it works: the label stays visible while the visitor types and names the field. type="email" brings up the email keyboard on phones and autocomplete="email" lets the browser fill it in. aria-describedby makes a screen reader read the message with the field, and aria-invalid, set only while the error shows, marks the field as wrong. The message says in words what is wrong and how to put it right.

When to show the error is where good sources disagree. GOV.UK’s validation pattern says “Do not validate when the user moves away from a field”: wait until they try to move on, then show an error summary at the top, move focus to it, and put each message next to its field. Baymard Institute recommends checking a field when the visitor leaves it, and removing the message as soon as the input is valid. Both agree: never tell someone they are wrong while they are still typing.

Can a tool detect this? Partly. axe-core’s label rule accepts a placeholder as a field’s name, so a placeholder-only field passes it; our own rule control-label does not count a placeholder, and reports the field as unlabelled. Our form-error check types into fields without submitting and reports an error message nothing ties to its field; it is off unless you switch it on. No check of ours decides 3.3.1: whether a label is clear and a message describes the problem needs a person.

What a CRO audit adds that a page audit cannot

A conversion rate optimisation (CRO) audit asks a wider question: not what is broken, but why visitors do not act, and what would change that. It needs evidence a page audit does not have.

  • Where visitors drop out. Analytics show which step loses people, on which devices and from which sources. A page audit sees one page, not the traffic.
  • Whether the page matches the visit. The ad, email or search that brought someone sets an expectation. Judging the match needs the campaign, not only the page.
  • Why visitors hesitate. Session recordings, on-page surveys and usability tests with real people show doubt about the price, the offer or the next step. A browser cannot measure doubt.
  • Whether a change helps. An A/B test with enough traffic compares two versions on the outcome you care about. It is how you find out whether a new headline or a shorter form changes what visitors do.

The two fit together. A covered button or an unlabelled field is worth fixing without a test to justify it. Whether the fix changes your conversion rate is a question for your data, not for an audit. And once the defects are gone, an experiment measures the persuasion it was meant to measure, not a broken page.

To see which of these defects your own landing page has, scan your landing page free, without signing up. The free scan covers one public page; the form-error check does not run on it.

Frequently asked questions

What is a landing page audit?

A review of one landing page for what stops a visitor who already wants to act: content that loads late or moves, a button that is covered or too small to tap, a consent banner with no way past, and a form with missing labels or unclear errors. Each defect has a place on the page or a measured value, and a fix.

How is a landing page audit different from a CRO audit?

A landing page audit finds defects on the page itself, which you can measure and fix. A CRO audit also uses analytics, user research and A/B tests to find out why visitors do not act and whether a change helps. Fix the defects first, so that a test measures the offer rather than a broken page.

Can a landing page audit be automated?

Partly. A browser can measure loading and layout shift in a lab run, covered controls and text, tap target sizes, consent banner buttons and fields with no label. Whether the copy is clear, whether an error message explains the problem and whether the page persuades need a person, and often real visitors.