paint-brush
Using viewport units to scale fixed layoutsby@sebastian.eberlein
14,013 reads
14,013 reads

Using viewport units to scale fixed layouts

by Sebastian EberleinMay 29th, 2017
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

There are plenty of ways to use <a href="https://hackernoon.com/tagged/viewport" target="_blank">viewport</a> units, covered in <a href="https://css-tricks.com/fun-viewport-units/" target="_blank">many</a> <a href="https://www.smashingmagazine.com/2017/05/fluid-responsive-typography-css-poly-fluid-sizing/" target="_blank">good</a> <a href="https://css-tricks.com/between-the-lines/" target="_blank">articles</a>. But the use cases are mostly limited to specific elements. In theory, you could use viewport units to scale the entire website layout relative to the viewport width. Of course, this does not work for most websites. But there are edge cases where you need a layout that is fixed, but also relative to the viewport width.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Using viewport units to scale fixed layouts
Sebastian Eberlein HackerNoon profile picture

There are plenty of ways to use viewport units, covered in many good articles. But the use cases are mostly limited to specific elements. In theory, you could use viewport units to scale the entire website layout relative to the viewport width. Of course, this does not work for most websites. But there are edge cases where you need a layout that is fixed, but also relative to the viewport width.

A real world example

Let’s take a look at Netflix’s website on a desktop browser. As you can see in the video below, the hero and other elements are scaled relative to the viewport width. This is especially important for the hero: The fixed layout ensures that the design is always as intended, which is definitely helpful for Netflix’s content designers. They can create the assets without having to worry that, for example, the tv show logo might overlay an important part of the hero image at a certain viewport width.

Netflix’s »Browse« page for logged-in users (July 2017, Firefox on Mac)

Implementation

The basic implementation is surprisingly straightforward. To keep it simple, this first example only includes the layout for large viewports.


Step 1:Define your root font-size in vw, for example 15px at a viewport width of 1000px:



html {font-size: 1.5vw;}


Step 2:Use rem values for everything that should grow or shrink relative to the viewport width. For example:




h1 {font-size: 2rem;margin-bottom: 0.75rem;}

Rem values are calculated from the root font-size, which in this example is a value that is relative to the viewport width. Thus, rem values are also relative to the viewport width. For some horizontal widths you would still use percentage values, though.


Step 3:Use pixel values for everything that should not be relative to the viewport width. For example:




header {font-size: 16px;padding: 20px;}

See the CodePen below for a simplified version of Netflix’s interface. Please note: It’s best to open the CodePen in a new tab, so you can resize your browser window. Also, the purpose of this example is to show the basic implementation of this technique — this is not production-ready code.

https://codepen.io/sebastianeberlein/full/VWNzZB

What I like about this technique: You can adjust the scale of the fixed layout simply by changing the root font-size. Or use a media query to only scale the fixed layout at a certain min-width. Example:

https://codepen.io/sebastianeberlein/full/VWJrRb

Alternative approach

If you don’t want to set the root font-size as a viewport unit, there is another technique with the same benefits as mentioned above:

Use a CSS variable and calc() likes this:



:root {--base-size: 2vw;}




h1 {font-size: calc(var(--base-size) * 2);margin-bottom: calc(var(--base-size) * 0.75);}

But this is complicated to write, so let’s use an SCSS function:



@function vw($value) {@return calc(var(--base-size) * #{$value});}




h1 {font-size: vw(2);margin-bottom: vw(0.75);}

Changing the CSS variable has the same effect as in the first approach. Just keep in mind that you need a fallback value for browsers that don’t support calc().

Another edge case

You might have seen magazines likes the one pictured below. They are often about art, fashion or some niche topic. Every layout is carefully crafted and takes hours of work and discussion. Design and content together form a visual experience.

http://sociodesign.co.uk/trace-magazine/

Translating this »experimental magazine design« to a website is a challenge. You need to make sure that every detail of the design is always as intended — regardless of the viewport width.

In the CodePen below is an example of such an experimental layout. There are three different layout versions for small, medium and large viewports. The layouts are fixed but scale relative to the viewport width.

https://codepen.io/sebastianeberlein/full/jwRLNP

Conclusion

Researching and testing a new technique is always fun. And as it turns out, there are edge cases where scaling a fixed layout with viewport units can be a viable solution.

But keep in mind the accessibility drawbacks: Text can get too small or large, if you don’t have enough breakpoints. Also, the browser zoom might not work as expected. So if you want to use this technique, the best approach might be a combination of a standard layout for small viewports and a scaled fixed layout for large viewports.