How to Add a Background Image in CSS: A Complete Guide

Adding a background image in CSS is one of the most common styling tasks in web development — and one of the most flexible. The background-image property gives you precise control over how images appear behind your content, with a range of sub-properties that affect size, position, repetition, and behavior across different screen sizes.

The Core Property: background-image

The starting point is always the same:

element { background-image: url('your-image.jpg'); } 

You can apply this to nearly any HTML element — body, div, section, header, and so on. The url() value accepts relative paths, absolute paths, or full URLs to hosted images.

Relative path example:

body { background-image: url('images/hero-bg.jpg'); } 

External URL example:

body { background-image: url('https://example.com/images/background.jpg'); } 

If the path is wrong or the file doesn't exist, the browser fails silently — you'll just see no background image, with no error displayed on screen.

Essential Supporting Properties

background-image rarely works alone. These companion properties control how the image actually behaves: 🎨

background-size

Controls how the image is scaled within the element.

ValueWhat It Does
coverScales the image to fill the entire element, cropping if needed
containScales the image to fit entirely within the element without cropping
autoKeeps the image at its natural size
100% 100%Stretches the image to fill the element exactly (can distort)
300px 200pxSets a fixed width and height

cover is the most commonly used value for full-page or section backgrounds because it ensures no empty space regardless of screen size.

background-repeat

By default, CSS tiles a background image to fill available space. You can change this with:

background-repeat: no-repeat; /* Show it once */ background-repeat: repeat-x; /* Tile horizontally only */ background-repeat: repeat-y; /* Tile vertically only */ background-repeat: repeat; /* Default — tile in all directions */ 

background-position

Determines where the image is anchored within the element:

background-position: center center; /* Centered both ways */ background-position: top left; background-position: 50% 20%; /* Percentage-based */ background-position: 0px 100px; /* Pixel offset */ 

Combined with cover, centering the position ensures the most visually important part of an image stays visible when it crops.

background-attachment

Controls whether the image scrolls with the page or stays fixed:

background-attachment: scroll; /* Default — moves with the page */ background-attachment: fixed; /* Parallax-style — stays in place */ background-attachment: local; /* Scrolls with the element's own content */ 

fixed creates a parallax-like effect that can look polished — but it has known performance and rendering issues on mobile browsers, where it may appear static or behave unexpectedly.

The Shorthand Approach

You can combine all background properties into a single background declaration:

body { background: url('bg.jpg') no-repeat center center / cover fixed; } 

The format is: urlrepeatposition/sizeattachment. The slash before size is required when both position and size are present. Shorthand keeps your CSS concise, but the long-form approach is easier to read and debug, especially for beginners.

Full-Page Background Image Example

This is the most common pattern — a full-viewport background behind a page's main content:

body { background-image: url('background.jpg'); background-size: cover; background-position: center; background-repeat: no-repeat; background-attachment: scroll; min-height: 100vh; } 

Setting min-height: 100vh ensures the element is tall enough to actually show the image, which is a detail beginners frequently miss.

Multiple Background Images

CSS supports layering multiple background images on a single element:

div { background-image: url('overlay.png'), url('main-bg.jpg'); } 

Images are stacked front-to-back — the first url() sits on top. This is useful for combining a semi-transparent texture or gradient overlay with a full photograph underneath, without needing extra HTML elements.

Using Gradients Alongside background-image

You can mix a gradient with a background image using the same multi-layer syntax:

div { background-image: linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)), url('photo.jpg'); background-size: cover; } 

This darkens the photo behind text — a practical technique when white or light-colored text needs to remain readable over a photograph.

Variables That Affect Your Results 🖥️

How well a background image implementation performs depends on several factors:

  • Image file size and format — Large uncompressed images slow page load. Modern formats like WebP offer better compression than JPEG or PNG at comparable quality.
  • Element dimensions — A background image on an element with no defined height won't be visible unless the element has content or explicit sizing.
  • Responsive behaviorcover and contain handle most cases, but heavily detailed images may need background-position tweaking at different breakpoints via media queries.
  • Browser compatibility — All major modern browsers support these properties, but background-attachment: fixed is a known exception on iOS Safari, where it renders differently or not at all.
  • Performance context — High-resolution images used as backgrounds on mobile can consume significant bandwidth. Serving different image sizes via media queries or CSS variables is worth considering for performance-sensitive projects.

Different Setups Lead to Different Outcomes

A simple portfolio site with one hero image and desktop-first design has very different requirements from a content-heavy site that needs responsive backgrounds across dozens of sections on varying device types. What works cleanly in the first case — a single background: url() cover center no-repeat on the body — may need media query overrides, multiple image sources, or a CSS custom property system in the second.

The right combination of background properties ultimately depends on the structure of your HTML, the content sitting on top of the image, the viewport sizes you're targeting, and how much control you need over the visual result at each breakpoint.