ScreenshotNeo

BlogHow-to

How to Make a Website Background Image Fill the Page

Use CSS background-size: cover to fill a page without distortion. Learn cropping, positioning, responsive layouts, troubleshooting, and screenshot automation.

By the ScreenshotNeo team1 October 20268 min read

Use background-size: cover on the element that should be filled. It scales the image proportionally until the element has no uncovered area. If the image and container have different aspect ratios, some of the image is cropped. Set background-position to control which part remains visible.

1. Fill the entire page

Apply the background to html (or another page-level container), give it a fallback color, disable tiling, and choose a position:

html {
  min-height: 100%;
  background-color: #172033;
  background-image: url("/images/background.jpg");
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}

body {
  min-height: 100vh;
  margin: 0;
}

cover preserves the image ratio while making both dimensions cover the container. The tradeoff is cropping when the proportions differ. See the MDN background-size reference.

Shorthand version

html {
  background: #172033 url("/images/background.jpg") center / cover no-repeat;
}

In the shorthand, the slash separates background-position from background-size.

2. Fill one section instead of the whole page

A background belongs to the element that receives the declaration. A section must have a height created by content, padding, or an explicit minimum height; the image itself does not create layout height.

<section class="hero">
  <div class="hero__content">
    <h1>Product launch</h1>
    <p>A readable foreground over a full-bleed image.</p>
  </div>
</section>
.hero {
  min-height: 70vh;
  padding: 4rem 1.5rem;
  color: white;
  background-color: #172033;
  background-image: url("/images/hero.jpg");
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
}

.hero__content {
  max-width: 60rem;
  margin: 0 auto;
}

Use min-height when the section may grow with content. Use height only when clipping or a fixed composition is intentional.

3. Understand cover, contain, and stretching

Value What it does Use it when Tradeoff
cover Scales proportionally until both container dimensions are covered. You need edge-to-edge coverage. Parts of the image can be cropped.
contain Scales proportionally until the full image is visible. The complete image matters more than filled edges. Uncovered space can remain.
100% 100% Sets width and height independently. Only when intentional distortion is acceptable. The image can look stretched.
/* Full image visible; bars or the fallback color may show */
.card {
  background: #172033 url("/images/map.jpg") center / contain no-repeat;
}

MDN describes cover as scaling while preserving the ratio and leaving no empty space. Explicit width and height values can stretch a background, so avoid 100% 100% for photographs or artwork.

4. Keep the important subject in view

background-position chooses the point that remains aligned while the excess is cropped. Start with center, then move the focal subject:

/* Subject near the left edge */
.hero {
  background-position: 25% center;
}

/* Subject near the top */
.banner {
  background-position: center 20%;
}

/* Exact percentage coordinates */
.art-directed {
  background-position: 70% 35%;
}

Keywords such as top, right, and bottom are also valid. Percentage coordinates are useful when a person or product sits away from the center. See the MDN background-position reference.

5. Make the layout responsive

The same image can crop differently as the viewport changes. Keep the subject in a safe area, or use art direction with media queries:

.hero {
  min-height: 60svh;
  background-position: 65% center;
  background-size: cover;
}

@media (max-width:  fortyrem) {
  .hero {
    min-height: 28rem;
    background-position: 72% center;
  }
}

Replace fortyrem with a valid numeric breakpoint such as 40rem:

@media (max-width: 40rem) {
  .hero {
    min-height: 28rem;
    background-position: 72% center;
  }
}

For substantially different mobile and desktop compositions, switch files:

.hero {
  background-image: url("/images/hero-wide.jpg");
}

@media (max-width: 40rem) {
  .hero {
    background-image: url("/images/hero-tall.jpg");
  }
}

6. Choose scrolling or fixed attachment

With the default background-attachment: scroll, the background moves with its element. With fixed, the positioning area is the viewport, so the image can remain stationary while content scrolls.

body {
  background: #172033 url("/images/background.jpg") center / cover no-repeat;
  background-attachment: fixed;
}

Use fixed attachment only when that visual behavior fits your design. Test it on touch devices and with long pages; a section background and a viewport-fixed background do not use the same positioning area. The MDN background reference documents these layers and positioning rules.

7. Add overlays for readable content

A dark overlay improves contrast without editing the source image. A pseudo-element keeps the image decorative and lets content remain above it:

.hero {
  position: relative;
  isolation: isolate;
  min-height: 70vh;
  color: white;
  background: #172033 url("/images/hero.jpg") center / cover no-repeat;
}

.hero::before {
  position: absolute;
  z-index: -1;
  inset: 0;
  background: rgb(0 0 0 / 38%);
  content: "";
}

.hero__content {
  position: relative;
}

You can use a gradient directly in the background layer:

.hero {
  background-image:
    linear-gradient(rgb(0 0 0 / 45%), rgb(0 0 0 / 20%)),
    url("/images/hero.jpg");
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
}

8. Accessibility and semantics

CSS backgrounds are decorative and have no alt attribute. If the image communicates information needed to understand the page, use a semantic <img> with useful alternative text instead, or describe the meaning in surrounding content. MDN recommends keeping meaningful imagery in the document rather than communicating it only through a CSS background.

<figure>
  <img src="/images/chart.jpg" alt="Quarterly revenue rises from Q1 through Q4">
  <figcaption>Revenue increased each quarter.</figcaption>
</figure>

For decorative backgrounds, provide a solid fallback color and preserve readable text contrast. Respect reduced-motion preferences if you add animated background effects:

@media (prefers-reduced-motion: reduce) {
  .hero {
    background-attachment: scroll;
  }
}

9. Complete runnable example

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Full-page background</title>
    <style>
      :root {
        color-scheme: dark;
      }

      * {
        box-sizing: border-box;
      }

      html,
      body {
        min-height: 100%;
        margin: 0;
      }

      body {
        min-height: 100vh;
        color: white;
        font: 1rem/1.5 system-ui, sans-serif;
        background-color: #172033;
        background-image: url("https://picsum.photos/id/1018/1600/900");
        background-position: center;
        background-repeat: no-repeat;
        background-size: cover;
      }

      main {
        min-height: 100vh;
        display: grid;
        place-items: center;
        padding: 2rem;
        background: linear-gradient(rgb(0 0 0 / 38%), rgb(0 0 0 / 38%));
      }

      article {
        max-width: 42rem;
      }
    </style>
  </head>
  <body>
    <main>
      <article>
        <h1>A page-filling background</h1>
        <p>Resize the window to see proportional scaling and cropping.</p>
      </article>
    </main>
  </body>
</html>

Replace the example image URL with an asset you control in production. The CSS pattern is the same for a local file, CDN URL, or generated image.

10. Troubleshooting checklist

Symptom Likely cause Fix
The image appears only behind a short strip. The element has little or no height. Add content, padding, min-height, or min-height: 100vh to the intended container.
Empty bands remain. contain is active, or the image does not cover the container. Use cover when edge-to-edge coverage is required.
The subject is cut off. cover is cropping the image around the center. Adjust background-position, use a focal-point percentage, or provide a mobile-specific image.
The image repeats. The default repeat behavior is still enabled. Set background-repeat: no-repeat.
The image looks distorted. Width and height were set independently. Use cover or contain instead of 100% 100%.
Nothing loads. The URL is wrong, blocked, or unavailable. Open the URL directly, inspect the browser network panel, and keep a fallback background-color.
The background covers the wrong area. The declaration is on a child or a fixed-attachment positioning area is being used. Move it to the page-level element or section you intend to fill; review background-attachment and background-origin.
Text is hard to read. The image has insufficient contrast. Add a translucent overlay or gradient and verify contrast at the crop positions.
The page becomes slow. The source image is unnecessarily large or decoded at high cost. Serve an appropriately sized, compressed asset, avoid loading backgrounds that are never shown, and use responsive sources where the design needs them.

11. Performance and reliability notes

  • Choose a sensible source size. A background should be large enough for the largest display you support, but an oversized original increases transfer and decode work.
  • Use a fallback color. It appears while the image loads and in uncovered or transparent areas.
  • Keep critical text independent of the image. Layout and meaning should remain usable if the request fails.
  • Consider loading behavior. A hero background requested from CSS can compete with other resources. Reserve backgrounds for decoration; use an image element when the image is content or needs explicit loading behavior.
  • Expect different crops. Aspect ratio changes are a design concern, not a browser bug. Test the focal point at narrow and wide containers.

12. Verify the result with screenshots

Capture the page at representative viewport sizes and check the crop, contrast, loading state, and fallback behavior. You can use browser automation locally, or compare rendered captures in CI.

Or skip the browser setup

ScreenshotNeo returns a website screenshot from one GET request, so you can inspect your page without maintaining browser-capture code. Its clean-shot flow accepts consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be disabled. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response reports the result with X-Page-Verdict and X-Billed headers. An MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

See the ScreenshotNeo API documentation for all options. This request captures a rendered page as WebP:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
require('node:fs').writeFileSync('shot.webp', image);

ScreenshotNeo includes full-page capture with lazy images loaded, custom CSS and JavaScript, viewport and device presets, retina scale, waiting controls, request blocking, headers and cookies, caching, signed links, asynchronous jobs, bulk capture, and PDF output. There are 1,000 free screenshots each month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

13. FAQ

Does background-size: cover stretch an image?

No. It preserves the aspect ratio and crops overflow when necessary.

Why does my page background not fill the viewport?

The background fills its element. Give that element a viewport-sized minimum height, such as min-height: 100vh, and remove default body margins.

How do I show the whole image?

Use background-size: contain, accepting that uncovered space may remain, or use an <img> when the image is meaningful content.

Can I keep the background fixed while content scrolls?

Yes. Set background-attachment: fixed on the relevant element, then check the behavior on the touch devices you support.

How do I stop the focal point moving on mobile?

Set a deliberate background-position and use a separate mobile asset when the composition cannot survive the narrower crop.

14. Final checklist

  • Apply the background to the element whose area should be filled.
  • Give that element enough height.
  • Use background-size: cover for proportional, edge-to-edge coverage.
  • Set background-position around the subject.
  • Set background-repeat: no-repeat.
  • Provide a fallback color and a readable overlay when needed.
  • Use semantic image markup when the image conveys information.
  • Check narrow and wide crops, loading failure, and text contrast.