How to Fix LCP When the Hero Is a CSS Background Image

This guide addresses a common LCP anti-pattern within Image & Media Optimization, as part of Image Decoding & Placeholders. Hero sections are often built as a <div> with background-image: url(hero.jpg) and background-size: cover, usually so text can sit on top. Chromium counts background images as LCP candidates, so the hero background is frequently the LCP element — and one of the slowest kinds.

The browser's preload scanner reads HTML, not CSS rules, so it cannot discover a background image until the stylesheet has downloaded, been parsed, and the element has been styled and laid out. That means the image request starts after CSS, at low priority, with no srcset, sizes or fetchpriority available on the element. On mobile, the background hero's request commonly starts 600–1200ms later than an equivalent <img> would.

When the hero request starts: background vs img Timelines comparing when a hero image request starts if defined as a CSS background versus as an img element in the HTML. When the hero request starts: background vs img CSS background HTML CSS hero image (low prio) img in HTML HTML hero image (high prio) 0ms 400ms 800ms 1200ms 1600ms 2000ms 2400ms LCP 2.5s

Rapid Diagnosis

  • Identify the LCP element. In the Performance panel, if the LCP node is a div or section and the LCP entry's url is an image, it is a background image.
  • Check the initiator. In Network, the hero request's initiator is the stylesheet, not the document or a preload.
  • Check the start time and priority. It starts after CSS completes and at Low or Medium priority.
  • Check responsive handling. Background heroes often serve one large image to all devices, or switch via media queries with multiple full-size files.

Root Cause Analysis

1. Late discovery. The URL lives in CSS, so the request waits for CSS download, parse, style and layout.

2. Low priority. Background images are fetched at low priority by default.

3. No responsive sizing. srcset/sizes are not available; image-set() supports density and type but not width-based selection.

4. Hard to prioritise. You cannot put fetchpriority on a CSS background.

Hero implementation options Comparison of hero image implementations by discovery, responsiveness and prioritisation. Hero implementation options Implementation Discovery Responsive Priority control CSS background-image after CSS + layout media queries / image-set none Background + preload link early via preload imagesrcset on preload fetchpriority on preload img with object-fit: cover preload scanner srcset + sizes fetchpriority

Step-by-Step Resolution

1. Replace the background with an img and object-fit

html
<section class="hero">
  <img class="hero-bg" src="/img/hero-1200.avif"
       srcset="/img/hero-640.avif 640w, /img/hero-1200.avif 1200w, /img/hero-2000.avif 2000w"
       sizes="100vw" width="2000" height="1000" fetchpriority="high" alt="">
  <div class="hero-content"><h1>Spring collection</h1></div>
</section>
css
.hero { position: relative; min-height: 60vh; }
.hero-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.hero-content { position: relative; }
/* trade-off: the img is now in the accessibility tree; give decorative heroes
   alt="" so screen readers skip them. */

Expected outcome: the preload scanner finds the image during HTML parsing; LCP typically improves by 500ms–1s on mobile.

2. If the background must stay, preload it with the same responsive candidates

html
<link rel="preload" as="image" fetchpriority="high"
      href="/img/hero-1200.avif"
      imagesrcset="/img/hero-640.avif 640w, /img/hero-1200.avif 1200w, /img/hero-2000.avif 2000w"
      imagesizes="100vw">
<!-- trade-off: the CSS must request exactly the same URL the preload chose, or
     the image downloads twice. With media-query-based CSS this is hard to
     guarantee; the img approach avoids the problem. -->

3. Use image-set() for format and density at least

If CSS backgrounds remain for secondary images, image-set() with type() lets browsers choose AVIF or WebP and density variants.

css
.promo { background-image: image-set(url("/img/promo.avif") type("image/avif"), url("/img/promo.jpg") type("image/jpeg")); }
/* trade-off: image-set selects by type and density, not by layout width;
   small screens may still download a desktop-sized file. */

4. Keep text readable without depending on the image

Give the hero a background colour close to the image's dominant tone so text is readable from the first paint, before the image arrives.

Migrating a background hero Steps to convert a CSS background hero into a fast LCP image. Migrating a background hero Move the image into an img element position: absolute; object-fit: cover Add srcset and sizes Right-sized files for every viewport fetchpriority=high, no lazy loading The LCP image starts early and high Dominant-colour background on the section Text readable before the image paints 1 2 3 4

Verification

In a throttled trace, the hero request's initiator should be the parser (or a preload), starting within a few hundred milliseconds of the HTML, at High priority. The LCP element should be the <img>. In RUM, resourceLoadDelay for the hero should drop sharply, and LCP p75 should follow.

Worked Example: A Travel Brand's Homepage

A travel brand's homepage hero was a background-image set in a 160KB stylesheet, switching between three JPEGs via media queries. LCP on mobile was 3.8s; the hero request started at 1.4s. Converting to an <img> with AVIF srcset, sizes="100vw", fetchpriority="high" and object-fit: cover, plus a dominant-colour background on the section, moved the request start to 0.3s and LCP p75 to 2.1s. The visual design was unchanged.

Why Frameworks and Page Builders Produce Background Heroes

Background heroes are common because they are easy to author: page builders expose "background image" as a section setting, CSS frameworks provide hero classes, and designers think in layers. When the hero is a component, change it once: make the component render an <img> (or <picture>) layer with object-fit: cover under the content, with props for srcset, sizes and priority. Page-builder sites may need a custom block or a template override. The authoring experience stays the same; the output becomes discoverable.

Finding Every Background Hero on a Site

Background heroes hide in stylesheets, CMS block settings and inline style attributes, so find them systematically. In RUM, the web-vitals attribution build reports the LCP element and its URL; group LCP entries where the element is not an img, picture or video but a URL is present — those are background-image LCPs. In the codebase, search CSS for background-image: url( on selectors used in hero or banner components, and templates for inline style="background-image. Prioritise by traffic: one shared hero component used on every landing page is worth more than a dozen one-off backgrounds on rarely visited pages.

Common Mistakes

  • Preloading one URL while CSS picks another. Downloads twice.
  • Lazy-loading the replacement img. Defeats the purpose.
  • Forgetting alt="" on decorative heroes. Adds noise for screen readers.
  • Keeping parallax effects tied to background-attachment: fixed. They repaint on scroll; replicate with transforms on the img if needed.

Edge Cases

CSS-in-JS heroes. Background URLs in runtime-generated styles are discovered even later (after JavaScript runs); converting to <img> helps even more.

Art direction. Different crops per breakpoint need <picture> with <source media>, which still preserves early discovery.

Gradient overlays. Keep overlays as CSS on the content layer (linear-gradient backgrounds), separate from the image.

Video backgrounds. Apply the same idea with a poster <img>; see video poster images and LCP.

FAQ

Do CSS background images count for LCP?

Yes, in Chromium, background images on elements are LCP candidates sized by the element's visible area. That is why a large hero background is so often the LCP element.

Is object-fit: cover visually identical to background-size: cover?

For a full-bleed image, yes — both scale the image to cover the box and crop overflow. object-position replaces background-position for controlling the focal point.

Can 103 Early Hints help a background hero?

Yes, by preloading it before the HTML arrives, but the same URL-matching caveat applies. Converting to <img> is simpler and more robust.

What about lazy-loading below-the-fold backgrounds?

CSS backgrounds are fetched when their element is styled, regardless of position; use a class added by an IntersectionObserver to defer them — see lazy-loading CSS background images.

Does this affect SEO?

Content images in <img> with meaningful alt text are indexed in image search; decorative heroes with empty alt are not. Background images are not indexed as content images either, so the change is neutral or positive.

How do I keep the focal point on mobile?

Use object-position to set the focal point, or art-direct with <picture> and different crops per breakpoint.

Will moving to img change how the hero looks in old browsers?

object-fit is supported in all modern browsers. For very old browsers, the image still displays (stretched or letterboxed rather than cropped), which is an acceptable degradation for most sites.