CSS viewport units and the calc(🔥) function

I love a clear, simple and well designed blog layout. A lot of white space, perfectly laid out, hand crafted typography and brilliant, vibrant images lighting up on my screen.

It needs skill to make something beautiful out of a fairly simple website form, like a blog.

One column, 100% width on smaller screens, a fixed width, centered on larger ones, containing text, videos and images.

A recent trend I’ve noticed, and to be honest, fallen in love with, are 100% view port width stretched images. An image breaking out of the normal content flow, displaying itself in its full splendor across the screen.

To have these images as part of your header, which doesn’t have to be inside the column’s width constrains is no biggie. But what if you want to have them in the middle of your actual content?

This is what our final product will look like. Image credit Oscar Keys

There are solutions for this. Most of you will probably already thinking about a way to solve this. Absolute positioning combined with a breeze of JavaScript was the one most of the people I’ve asked proposed to me.

I wasn’t happy about it. I wanted to avoid using JavaScript for this task and was sure there is a logical and elegant way to do so. And I was right, there is.

Before we begin, there are a few ground rules to lay out. This solution doesn’t support browsers below IE9, no Opera Mini in general, and no Android below 4.4.4.

We’re going to use viewport units and the CSS calc( ) function to accomplish our goal.

So let’s see what happens if we use 100vw as the width of our image.

As we can see, the image seems to be large enough, but it goes all the way to the right and we end up with a website with a horizontal scrollbar. So what are we missing?

The image isn’t filling up the left half of our screen. But how we going to do that without knowing how wide the user’s screen is?

This is the point where the combination of viewport units and the
CSS calc( ) function looks like magic … or JavaScript.

Let’s assume our content column is 33.3em wide.

.img--is-100vw-wide {
position: relative;
width: 100vw;
height: auto;
left: calc((-100vw + 33.3em) / 2);
}

The last line does a few things for us. On each page render, it takes the current screen width, subtracts the users actual font-size (because we never want to override user settings) multiplied by 33.3 and divides it by two. To move the image from the middle of the screen towards the left site we negate the whole operation. This gives us the width between the browser’s border and the column’s. Using this value for left positioning moves our image in the right direction.

Here’s an example how this could work across breakpoints:

.column {
width: 100%;
max-width: 33.3em;
margin: 0 auto;
padding-left: 1em;
padding-right: 1em;
@media screen and (min-width: 33.3625em) {
padding-left: 0;
padding-right: 0;
}
}
.img--is-100vw-wide {
width: 100vw;
height: auto;
position: relative;
left: -1em;
margin-bottom: 2rem;
@media screen and (min-width: 33.3625em) {
left: calc((-100vw + 33.3em) / 2);
}
}

Note: always leave 1 space between a value and an operator, otherwise the CSS calc( ) function doesn’t work.

The image always fills the entire screen width and stays within the content flow — logical and elegant.

On Coding

Thoughts about writing code

Kevin Lorenz (@verpixelt)

Written by

Frontend developer, type enthusiast, feminist ally, CSS Wizard @IDAGIO_official

On Coding

On Coding

Thoughts about writing code

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade