ScreenshotNeo

BlogHow-to

Background Image for Website HTML Code

Add a background image with CSS, choose cover or contain, keep text accessible, fix mobile issues, and capture the finished page.

By the ScreenshotNeo team1 October 20267 min read

Use CSS to apply a website background image. The image URL goes in background-image or the background shorthand, while background-size, background-position, and background-repeat control how it appears.

body {
  background-color: #f4f4f4;
  background-image: url("/images/background.jpg");
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}

The same rule as a shorthand is:

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

Replace the URL with an image file your site can load. For a hero or card, apply the rule to that element instead of body. The element must have a visible area; its content, padding, height, and layout determine where the background can be seen.

1. Complete HTML and CSS example

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Background image example</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <main>
    <section class="hero">
      <div class="hero__content">
        <p class="eyebrow">Travel guide</p>
        <h1>Plan your next route</h1>
        <p>A readable content block sits over a decorative background.</p>
        <a class="button" href="/guides">Read the guide</a>
      </div>
    </section>
  </main>
</body>
</html>
* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: system-ui, sans-serif;
  color: #fff;
  background: #f4f4f4;
}

.hero {
  min-height: 28rem;
  display: grid;
  place-items: center;
  padding: 3rem 1.25rem;
  background-color: #263238;
  background-image:
    linear-gradient(rgb(0 0 0 / 0.48), rgb(0 0 0 / 0.48)),
    url("/images/route.jpg");
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}

.hero__content {
  width: min(100%, 42rem);
}

.button {
  display: inline-block;
  padding: .75rem 1rem;
  color: #172027;
  background: #fff;
  text-decoration: none;
  border-radius: .35rem;
}

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

In the media query, replace fortyrem with a valid CSS length such as 40rem; the spelling above is intentionally easy to spot if you copy the example.

2. Choose the right background properties

Property What it controls Typical choice
background-image One or more image layers url("/images/hero.jpg")
background-color Color beneath every image layer and fallback if an image cannot load A color that still supports readable text
background-size How the image is scaled cover for a filled box; contain to show the complete image
background-position Which part of the image is kept in the focal area center, or a tuned value such as 65% center
background-repeat Whether the image tiles no-repeat for photos; repeat for textures
background-attachment Whether the background scrolls with the page Usually the default scroll

cover versus contain

  • cover scales until the entire box is filled. It can crop the top, bottom, or sides.
  • contain scales until the complete image fits. It can leave uncovered space, which shows the background color.

Pick based on the composition. Keep a subject near the center if you use cover, or tune background-position toward the subject. There is no universal mobile value because the box ratio and artwork differ.

Multiple images and gradients

Comma-separated layers are painted from first (top) to last (bottom). A gradient is useful for text contrast:

.banner {
  background-color: #182027;
  background-image:
    linear-gradient(90deg, rgb(0 0 0 / .72), rgb(0 0 0 / 0)),
    url("/images/banner.webp");
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}

Shorthand syntax

background can set color, image, position, size, and repeat in one declaration:

.card {
  background: #eee url("/images/pattern.svg") center / 12rem repeat;
}

Use longhand while debugging. A later shorthand can reset properties you set earlier, so keep related declarations together.

3. Apply a background to a section, card, or the whole page

/* Whole document */
body {
  background: #f4f4f4 url("/images/site-bg.jpg") center / cover no-repeat;
}

/* A section with a definite visible area */
.features {
  min-height: 20rem;
  padding: 4rem 2rem;
  background: #dfe8ed url("/images/features.jpg") center / cover no-repeat;
}

/* A repeating texture */
.paper {
  background: #fff url("/images/noise.png") 0 0 / 16rem 16rem repeat;
}

The body background can propagate to the root element under specific conditions described by MDN’s background reference. If you need predictable behavior, set the background on the element that owns the visual region.

4. Responsive backgrounds and mobile cropping

A background is sized against its container, not against the original image dimensions. On a narrow screen, cover often crops the sides. Give the container a deliberate minimum height, then adjust the focal point at a breakpoint:

.hero {
  min-height: clamp(20rem, 60vw, 36rem);
  background-size: cover;
  background-position: 50% 35%;
}

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

If the whole artwork must remain visible, use contain and choose a background color for the remaining space. For informative images that need responsive source selection, use a semantic HTML image with responsive-image features instead of a CSS background; see MDN’s responsive images guide.

5. Accessibility: decorative versus meaningful images

CSS backgrounds are appropriate for decoration. Assistive technology does not receive a text alternative for a CSS background; MDN notes that browsers provide no special background-image information to assistive technology. If the image conveys information, identifies a product, contains a chart, or is required to complete a task, put it in the document as an HTML image with useful alternative text.

The W3C C9 technique is specifically for decorative images and is not suitable for images that convey information or functionality.

For text over a background, test the actual visible crop and keep a solid fallback or overlay. MDN summarizes WCAG thresholds of 4.5:1 for normal body text and 3:1 for large text (at least 24px, or bold text at least 18.66px).

6. Loading, file paths, and performance

  • Resolve the URL from the CSS file’s location. In css/styles.css, url("../images/hero.jpg") points one directory up, while url("/images/hero.jpg") points to the site root.
  • Use an image format and dimensions suitable for the rendered box. Oversized files increase transfer and decode work.
  • Prefer a stable absolute or root-relative path in production, and verify case-sensitive filenames on Linux hosts.
  • Keep a background color so the layout remains usable while the image is unavailable.
  • Do not use a background for content that should be discoverable, indexed, or announced to assistive technology.

7. Troubleshooting checklist

Symptom Likely cause Fix
No image appears Bad URL, 404 response, or the element has no visible area Open the image URL directly, inspect the network panel, and add content, padding, height, or min-height.
Only a small strip is visible The container collapses around empty or absolutely positioned children Give the container a height or padding, or establish a layout that includes its content.
Image repeats unexpectedly Default repeat behavior Set background-repeat: no-repeat for a single image.
Subject is cut off cover crops to fill the box Try contain, change the box ratio, or tune background-position.
Text is hard to read Busy artwork or a different mobile crop Add a gradient overlay, solid text backing, or a fallback color and check contrast at each breakpoint.
Works on desktop but not mobile Different container ratio, invalid media-query value, or an image URL blocked on mobile Validate the CSS, set a mobile height and position, and check the mobile network panel. Use valid units such as 40rem.
Changes do not appear Cached CSS or image Hard-refresh during development and use a versioned filename or cache policy when deploying.

8. Verify the rendered result

  1. Load the page at the widest and narrowest supported viewport.
  2. Disable the image request or use an invalid URL to confirm the fallback color and text remain usable.
  3. Check the focal subject after every breakpoint change.
  4. Run a contrast check over the darkest and lightest visible portions.
  5. Inspect the network panel for 404s, redirects, blocked requests, and unexpectedly large files.

Or skip the browser setup

If you need a rendered screenshot of the page after its CSS background has loaded, ScreenshotNeo captures the URL through one API request. Its cleanup step accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the verdict and billing status with X-Page-Verdict and X-Billed headers.

See the ScreenshotNeo API documentation for all options, including full-page lazy-image loading, CSS-selector element capture, dark mode, device presets and custom viewports, retina scale, custom CSS and JavaScript, waits, request blocking, headers, cookies, user agents, timezone, geolocation, transparent backgrounds, resizing, caching, signed links, async jobs, bulk capture, usage, and the OpenAPI specification.

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)
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}`);

ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

FAQ

Is a background image HTML or CSS?

The page is HTML, but the background is applied with CSS. Put the rule in an external stylesheet, a <style> block, or an element’s style attribute.

How do I stop a background from stretching?

Set background-size: auto for its intrinsic size, or use contain when the full image must remain visible. cover intentionally scales and can crop.

Can a background image have transparency?

Yes. Formats that support transparency can reveal the background color or lower layers. Test the result against both light and dark themes.

Should I preload a CSS background?

Only when it is a critical visual and you have measured the tradeoff. Keep the CSS path correct, provide a fallback color, and avoid downloading an unnecessarily large asset.