CSS background images skip every native optimization the browser gives a real <img> tag, so convert them to WebP or AVIF, serve responsive variants with image-set() and media queries, preload any hero background that is your LCP element, and move content imagery into actual <img> markup so Google can see it.
What this check flags
This audit flags images loaded through the CSS background-image property that are heavier than they need to be. That covers oversized files served at one giant resolution to every device, legacy formats like uncompressed JPEG or PNG where WebP or AVIF would be far smaller, single fixed images with no responsive variants, and hero backgrounds that hold up the Largest Contentful Paint because the browser cannot discover them until the CSS has been downloaded and parsed.
Why background images get missed
A regular <img> element comes with a toolbox: loading="lazy", srcset and sizes for responsive selection, fetchpriority for scheduling, and decoding="async". A CSS background image gets none of that. There is no native lazy loading, no srcset, and no priority hint on the declaration itself.
They are also invisible in two ways that matter. First, many image audits and plugins only scan <img> tags, so a 2 MB hero background sails straight past your optimization tooling. Second, the browser preload scanner reads HTML, not stylesheets, so a background image is only discovered after the CSS file arrives and the element renders. That late discovery is exactly why hero backgrounds are classic LCP killers. And because crawlers do not index CSS backgrounds as images, anything meaningful you put there is locked out of Google Images entirely.
How to fix it
1. Convert to modern formats
WebP and AVIF deliver substantially smaller files than JPEG or PNG at comparable visual quality, and both formats now enjoy support in every modern browser. Convert your background assets first; it is the single biggest win and requires no markup changes beyond the URL.
2. Use image-set() for format and resolution switching
The image-set() function is the background-image equivalent of srcset. It lets the browser pick the best supported format and the right resolution for the device pixel ratio. List formats in order of preference and the browser takes the first one it understands.
Bad: one massive desktop JPEG for everyone.
.hero {
background-image: url("/img/hero-4000px.jpg"); /* 2.4 MB for every visitor */
background-size: cover;
}Good: modern formats with fallback, picked by the browser.
.hero {
background-image: url("/img/hero.jpg"); /* fallback for old browsers */
background-image: image-set(
url("/img/hero.avif") type("image/avif"),
url("/img/hero.webp") type("image/webp"),
url("/img/hero.jpg") type("image/jpeg")
);
background-size: cover;
}3. Use media queries for size switching
image-set() handles pixel density and format, but it does not know your layout. Pair it with media queries so a phone never downloads the desktop crop.
.hero { background-image: url("/img/hero-800.webp"); }
@media (min-width: 768px) {
.hero { background-image: url("/img/hero-1600.webp"); }
}
@media (min-width: 1440px) {
.hero { background-image: url("/img/hero-2400.webp"); }
}Browsers only fetch the background that actually applies, so each breakpoint costs nothing extra.
4. Preload the LCP background
If a background image is your LCP element, the preload scanner cannot see it in the stylesheet. Tell the browser about it directly in the HTML head, and raise its scheduling priority with fetchpriority="high". Preload fixes late discovery; fetchpriority fixes low priority. You usually want both.
<link rel="preload" as="image"
href="/img/hero-1600.webp"
fetchpriority="high">If you serve different sizes per breakpoint, add a media attribute to each preload so only the matching one downloads.
5. Promote content images to real <img> tags
If the image is content rather than decoration, a product shot, a team photo, an illustration that carries meaning, it belongs in an <img> element, optionally positioned under text with CSS. You regain srcset, lazy loading, fetchpriority, alt text, and indexability in one move. Reserve background-image for genuinely decorative texture and patterns.
The SEO angle
Google does not index CSS background images as images. They cannot rank in Google Images, they carry no alt text, and they contribute nothing to how search engines understand your page. For a site where imagery drives discovery, keeping content photos in backgrounds is throwing away an entire traffic channel. Performance compounds the problem: a slow hero background drags LCP, and Core Web Vitals feed into how Google evaluates page experience.
How to diagnose
Run PageSpeed Insights and check the LCP element it reports; if the LCP is a node with a CSS background, you have a discovery delay. In Chrome DevTools, the Network panel filtered to images shows the format, transfer size, and start time of each background. Compare the start time of the background image against your CSS file to see the late-discovery gap. A site crawl that parses CSS, like the deep crawls SEO ProCheck runs, will surface background URLs that page-level image audits miss.
Common mistakes
Lazy loading the hero background with JavaScript, which delays your LCP instead of helping it. Preloading a background that is not actually the LCP element, which steals bandwidth from things that are. Shipping one retina-sized image to all devices because "background-size: cover handles it." Forgetting the plain url() fallback line before image-set() for older browsers. And preloading one URL while the CSS requests a different variant, which downloads the image twice.
FAQ
A: No. Purely decorative textures, gradients, and patterns are fine as CSS backgrounds. Promote an image to <img> when it is content you want users and search engines to see, or when it is your LCP element and you want the full set of native loading controls.
A: Yes. It reached Baseline browser support in 2023. Keep a plain background-image: url() declaration on the line before it as a fallback, and note that some Chromium versions historically used the -webkit-image-set prefix.
A: It helps when late discovery is the bottleneck, which is the usual case for CSS backgrounds. Measure before and after. If the image is enormous, compression and a modern format will matter more than any loading hint.
Need a full technical audit?
SEO ProCheck runs deep crawls that catch issues like this across your whole site.
Claude Vincent is a technical SEO consultant focused on crawlability, rendering, and AI-search visibility. He writes the field guides and case studies at SEO ProCheck, with a bias toward the durable, unglamorous work that decides whether search engines and AI answer engines can actually read and cite a site.
About SEO ProCheck
Technical SEO consulting and GEO strategy with 20 years of enterprise experience. Case studies, resources, and tools for search and AI visibility.
Work With Me
Technical SEO audits, GEO strategy, site migrations, and international SEO. Hourly consulting for teams who need hands-on support, not just reports.








