How to create a responsive full-height image with pure CSS.

Mark Brehaut
UX Milkshake
Published in
6 min readMay 11, 2016

--

via uxmilkshake.com

How to create a responsive full-height image with pure CSS

Images are a necessary part of web development, but they can sometimes be a pain in the buns to work with.

Photos, GIFs, and illustrations are awesome because they can engage your users in a visually appealing way. In order to make sure they look sharp across different heights, widths, screen sizes and devices, it’s important to always maintain the aspect ratio of the image*.

* Otherwise, you can end up with some blurry stretched out fat faces or long heads. Unless that’s your thing, then you can stop reading here.

In this tutorial post, I’ll cover how to maintain an image aspect ratio for an image that covers the full height of the user’s screen or viewport (as Medium made hugely popular a couple years ago).

Lesson learning level: Super easy

Full height background images can make your page pop. Here are a few beautiful examples to give you some inspiration:

Urban Influence screenshot

They’re great for overlaying post titles and meta content on blogs (urbaninfluence.com)

Momentum app screenshot

Google Chrome’s Momentum extension

Invision app screenshot

Invision App responsive site

I’ll lay out 2 separate techniques for accomplishing this effect. First: the JavaScript way (aka the way I don’t use anymore after doing it this way for years)

Let’s lay out the basic HTML:

<body>
<div class="full-bg-img" style="background-image:url('your-image-source.jpg');"></div>
</body>

As you’ll notice in the HTML above, the key is NOT using an <img> tag and instead assigning the image as a background-image to the <div> we’ll style below. This technique will allow us to avoid setting the height and width of the image itself and will also make it much easier to overlay content on top of the image (as you see in the examples above).

For the styling, I create a SASS helper mixin that I can easily reuse that I put in my _helpers.scss file**.

** If you are not familiar with SASS, not to worry — this is a very basic SASS mixin and can also be used as vanilla CSS.

SASS:

@mixin full-bg-img {
background-size: cover;
background-position: center;
}
.full-bg-img {
@include full-bg-img;
}

Yup, that's all you need for the styling to accomplish this effect (for the JavaScript technique that is):

  • background-size is the primary piece here. We use ‘cover’ to tell the browser that this image should cover the entire width of the screen no matter what — even if you have to stretch it.
  • background-position is used to place the location of the image in relation to the viewport. For the most part, I set this value to ‘center’. If you really want to get specific, you can set the value as percentages or pixels to control its vertical and horizontal position.

If you stopped here and tried this for yourself, you'll notice (or not notice) that the image doesn't actually appear. That's because we need to also set the height of the image. Aka this is where the magic comes in.

There are 2 techniques that I've used to set the height of the background image to maintain its aspect ratio. The first is through JavaScript/jQuery:

JS:

$(function(){
$('.full-bg-img').css({
height: $(window).innerHeight()
});
})

As you can see, this function is very simple and readable.

We are using the innerHeight() function to dynamically set the height of the <div> element that we assigned our background image to, to the window height. Combined with the element's background-size set to 'cover', this tiny function will now expand our image to the full height and width of the viewport. The beauty of this is that if the browser's width is larger than the original width of the image, it will still maintain the aspect ratio by also increasing its height. For example, you have a medium sized image at 960 x 640, but your viewport is 1600 x 860. That's a big jump. Of course your image will not be as clear as its original dimensions, but its aspect ratio will remain in tact without displaying fat faces or long heads.

But wait. If we leave our code like this, there could be a problem. What if the user shrinks their browser window after the page loads? Or, what if they are using a mobile device and they turn their tablet or phone from portrait to landscape to get a better look at your sweet photo? The height of the element will NOT adjust and may, and probably would, look pretty silly.

Can we solve this problem? Of course we can. Let's bring in the resize() function and attach it to the window.

JS:

$(function(){
$('.full-bg-img').css({
height: $(window).innerHeight()
});
$(window).resize(function(){ // add resize() to adjust to browser
$('.full-bg-img').css({
height: $(window).innerHeight()
});
});
})

This tells the browser to dynamically resize to the height of the element to the window even after the page loads. This way you can turn your tablet around like a steering wheel and your image will adjust its height while maintaining its original aspect ratio.

Pretty cool huh? I think so too, that's why I used to employ this technique all the time.

Yes, there is an easier way to accomplish this without using any JavaScript at all... And the only thing you need to do is add one line to your stylesheet:

SASS:

@mixin full-bg-img {
background-size: cover;
background-position: center;
height: 100vh; /* vh = viewport height */
}
.full-bg-img {
@include full-bg-img;
}

Super cool, super simple, and no JavaScript necessary. Try it and resize the browser all you want, the image will maintain its aspect ratio while adjusting to the height of the window.

If you've never seen or used 'vh' in your styles before, it is short for viewport height***. vh units measure from 0 - 100 where the value is set to the percentage of the viewport's height. For example, if your window is 600px tall and your element is set to 50vh, your element's height will equal 300px.

*** In addition to vh, there is also vw = viewport width, vmin = viewport minimum, vmax = viewport maximum.

Once upon a time, I carried that same JavaScript function from project to project until I came across this little diddy. And then: NO MORE! Using pure CSS (or SASS) is cleaner, more efficient, and more elegant. The best part is this technique is supported by all modern browsers. I have yet to see a disadvantage in using this technique for accomplishing the full-height background image. If you know of one, please share your thoughts in the comments below.

So there you have it: a couple different ways to accomplish a Medium-like full height background image effect while maintaining the original aspect ratio. I hope you get as much use out of this as I have.

Afterthoughts:

  • TIP: For overlaying content on a background image, create a darker overlay mask on the image so the text or buttons pop. If you need help with this, leave a comment below or shoot me an email (through the contact page)
  • If you are new to SASS, or are interested in how to structure SASS modules, here are a couple articles I’ve found very helpful to my process:
  • How to structure a SASS project
  • Architecture for SASS project
  • To learn more about vh, vw, vmin, and vmax, check out this article on tutorialzine. They also explain different uses for these units including font sizes and margins.

--

--

Mark Brehaut
UX Milkshake

CPO @Icebrkrdating. Relationship academic turned product designer turned entrepreneur. Human enthusiast. Master self-deprecator.