Absolutely Responsive Full-Screen Background Images

The conventional wisdom is that big images sell. Somewhat more subjective opinions tell us that big images are pretty. Whatever the reason, we like our big images. What's more, we really like to put them in the background, and put big text on top of them.

I'm not here to debate whether or not we should do this. Even if I thought that big background images were the bane of web design (which I don't), people would keep on using them. That includes me. They're big. They're pretty. What's not to like?

They have their place in our collective toolbox, but we need to do them right. I'm not just talking about picking the right images, that's up to you. I'm talking about making sure that our images don't murder people's bandwidth. If we're really going to be designing "mobile-first", that has got to include our images.

The problem

Right now, when people want to fill the background of a page, or even just a pretty large div, they often just use CSS like this (I'm using each property separately for clarity):

body, .bigdiv {
background-image: url(path/to/image.jpg);
background-size: cover;

Now, this is fine for desktops and any Internet connection with limitless data, but what if the increasingly large number of mobile users want to play? Are you really going to let them download that potentially massive .jpeg onto their phones, costing them actual money?

    We have three solutions that give us responsive background images:
  1. Media queries
  2. The image-set property
  3. Absolutely responsive background images (more on that later)
Media queries

This one is the obvious solution. You define a small background image. Then, for increasingly large screen sizes, you use media queries to define increasingly large background images.

For example, you'd use CSS like this:

body {
background: url(images/small-image.jpg);
@media screen and (min-width: 700px) {
body {
background: url(images/larger-image.jpg);

It's the obvious solution, really. We're using the pure CSS, with no changes to markup.


This method comes with a problem: mobile browsers, especially older ones, will tend to download all of the images, defeating the purpose of the exercise. The good news is that there are workarounds. The bad news is: they are workarounds. They are a bit bloated by default.

Still, they work well enough. If you want to learn them anyway, check this out: Media Query & Asset Downloading Results


All image-set does is provide a list of images which are usually all identical except for the size. As with the srcset HTML attribute, the browser will decide for itself which image is best to download, based on the device.

I'm including source files for both of these solutions, so you can see them in action. You can download those below. For now, here's what you need to know:


<!DOCTYPE html>
< html lang="en">
<meta charset="UTF-8">
<title>Pure CSS Responsive Background Image Demo</title>
<h1>Pure CSS Responsive Background Image Demo</h1>
The (basic) CSS

body {
background-image: image-set(
url(regular-image.jpg) 1x,
url(double-sized-image.jpg) 2x

Let's just set aside, for a moment, the fact that browser support for the image-set property is not nearly where it needs to be. Let's ignore the vendor-prefixes you need to make this work. The real problem is that images are not chosen based on the size of the screen/viewport, but based on the pixel density.

That means it's great for switching between retina screens and the regular kind. Need a bigger image for those massive iMac screens? The image-set function is here to help. If this is all you need, then image-set is for you.

You could use it for images that are small anyway: icons, profile pictures, and other things of that sort. Those are small enough that they won't break a mobile user's data plan. But hey, we want massive background images, right? So this solution is not yet ready.

Absolutely responsive background images

So by now, we all see the what we need: responsive images, chosen based on screen/viewport size, and we want the browser to only download one of them. Guess what? We can do that.

The bad news is that it requires a change to your markup. This change is minimal, however. All you need to do is add a div, and the background image itself.

This whole thing works on two concepts: absolute positioning, and the srcset HTML attribute. Absolute positioning has been around for a while, and it just works like it should. Nothing to worry about there. The srcset attribute, on the other hand, is newer, and less-well supported.

However, according to the latest usage statistics, srcset is supported by, well, some mobile browsers. "Some" is not ideal; but in the browsers where it works, good things will happen. Users of those browsers will receive the benefits of responsive images. Other users will get what they would have gotten anyway.

Hurray for progressive enhancement! Below, you'll find the basic HTML and CSS you need to make this work. And do check out the included zip file with the source code.

absolutely responsive background imageThis is just a screenshot


<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>Absolutely Responsive Background Image Demo</title>
<!-- Note that I have chosen a middle ground as far as the default image size goes, just as a fallback. -->
<div class="bodybg">
<img src="images/medium-background-image.jpg"
src-set="images/small-image.jpg 500w,
images/medium-image.jpg 1000w, images/large-image.jpg 2000w"
<h1>Pure CSS Responsive Background Image Demo</h1>

Note: The CSS part of this solution was adapted from this demo: http://codepen.io/ErwanHesry/pen/JcvCw/

/* This solution doesn't just work for whole pages. It can be adapted to smaller containing elements as well. For now, we're making it the size of the viewport. */

.bodybg {
position: relative;
overflow: hidden;
width: 100%;
height: 100vh;
.bodybg img {

/* These properties make sure that the "background image" covers all available space. */

position: absolute;
top: 0;
right: 0;
bottom: 0;
min-width: 100%;
min-height: 100%; /* This bit centers the image. */
left: 50%;
transform: translateX(-50%);

/* Here, we make sure that nothing sticks out on the side that shouldn't. */

overflow-x: hidden;
Going forward

Absolutely responsive background imagesTM (kidding) is an admittedly imperfect solution, but we're working with imperfect browsers. When and where it works, it'll be saving you (and everyone else) precious bandwidth. Can't really argue with that.

You can download the source files below:

About the author

Copyright © All Rights Reserved