DEV Community

Per for Scrimba

Posted on • Edited on • Originally published at freecodecamp.org

How to make responsiveness super simple with CSS Variables

Learn how to create the following responsiveness with CSS VariablesClick the image to get to the free full-length CSS Variables course.

If you haven’t heard of CSS Variables before, it’s a new feature of CSS which gives you the power of variables in your stylesheet, without having to do any setup.

In essence, CSS Variables allow you to skip the old way of setting styles:

h1 {  
  font-size: 30px;  
}

navbar > a {  
  font-size: 30px;  
}
Enter fullscreen mode Exit fullscreen mode

…in favour of this:

:root {  
  --base-font-size: 30px;  
}

h1 {  
  font-size: var(--base-font-size);  
}

navbar > a {  
  font-size: var(--base-font-size);  
}
Enter fullscreen mode Exit fullscreen mode

While the syntax might seem a bit weird, this gives you the obvious benefit of being able to change the font sizes across your entire app through only changing the--base-font-size variable.

If you want to learn CSS Variables properly, please check out my free and interactive CSS Variables course on Scrimba:

The course contains eight interactive screencastsThe course contains eight interactive screencasts.

Now let’s see how this new technology can make your life easier when building responsive websites.

The setup

We’re going to add responsiveness to a portfolio website which looks like this:

It looks nice when viewed on your desktop. However, as you can see on the left image below, this layout doesn’t work well on mobile.

How it looks on mobile initially.

How we want it to look.

On the right image, we’ve changed a few things on the styles to make it work better on mobile. Here’s what we have done:

  1. Rearranged the grid so that it’s stacked vertically instead of across two columns.
  2. Moved the entire layout a bit more up
  3. Scaled the fonts down

In order to do this, we needed to change the following CSS:

h1 {  
  font-size: 30px;  
}

#navbar {  
  margin: 30px 0;  
}

#navbar a {  
  font-size: 30px;  
}

.grid {  
  margin: 30px 0;  
  grid-template-columns: 200px 200px;  
}
Enter fullscreen mode Exit fullscreen mode

More specifically, we needed to make the following adjustments inside of a media query:

  • Reduce font size of the h1 to 20px
  • Reduce the margin above and below the #navbar to 15px
  • Reduce the font size inside the #navbar to 20px
  • Reduce the margin above the .grid to 15px
  • Change the .grid from from two-columns to one-column

Note: There is, of course, much more CSS in this application, even within these selectors. However, for the sake of this tutorial, I’ve stripped away everything which we aren’t changing in the media query. Check out this Scrimba playground to get the entire code.

The old way

Doing all of this would be possible without CSS Variables. But it would require an unnecessary amount of code, as most of the bullet points above would need their own selector inside the media query, like this:

@media all and (max-width: 450px) {  

  navbar {  
    margin: 15px 0;  
  }  

  navbar a {  
    font-size: 20px;  
  }  

  h1 {  
    font-size: 20px;  
  }

  .grid {  
    margin: 15px 0;  
    grid-template-columns: 200px;  
  }

}
Enter fullscreen mode Exit fullscreen mode

The new way

Now let’s see how this can be solved with CSS Variables. To begin with, we’ll rather store the values which we are reusing or changing inside variables:

:root {  
  --base-font-size: 30px;  
  --columns: 200px 200px;  
  --base-margin: 30px;  
}

And then well simply use these variables across the app:

#navbar {  
  margin: var(--base-margin) 0;  
}

#navbar a {  
  font-size: var(--base-font-size);  
}

h1 {  
  font-size: var(--base-font-size);  
}

.grid {  
  margin: var(--base-margin) 0;  
  grid-template-columns: var(--columns);  
}
Enter fullscreen mode Exit fullscreen mode

Once we have this setup, we can simply change the values of the variables inside the media query:

@media all and (max-width: 450px) {  
  :root {  
    --columns: 200px;  
    --base-margin: 15px;  
    --base-font-size: 20px;  
}
Enter fullscreen mode Exit fullscreen mode

This is much cleaner than what we had before. We’re only targeting the :root, as opposed to specifying all the selectors.

We’ve reduced our media query from four selectors down to one and from thirteen lines down to four.

And this is just a simple example. Imagine a full-blown website where, for example, the --base-margin control most of the free spacing around the app. It’s a lot easier to just flip the value of it, as opposed to filling your media query up with complex selectors.

To sum up, CSS Variables are definitely the future of responsiveness. If you want to learn this technology once and for all, I’d recommend that you check out my free course on the subject on Scrimba.

You’ll become a CSS Variables master in no time :)

Thanks for reading! I’m Per Borgen, front-end developer and co-founder of Scrimba. Feel free to reach out to me via Twitter if you have any questions or comments.

Top comments (12)

Collapse
 
nicolalc profile image
Nicola

The only issue related with css variables is IE (every time is IE the problem) compatibility.

I prefer to use vars only with SCSS, because I need to give IE compatibility for my projects.

Anyway nice examples, I love the new css grid system, expecially if combined with flexbox!

Collapse
 
nuxodin profile image
Tobias Buschor

You can try this polyfill:
github.com/nuxodin/ie11CustomPrope...

Collapse
 
bayuangora profile image
Bayu Angora • Edited

Also, CSS variable can't be rendered by Opera Mini with extreme mode. We have to use normal mode to render CSS variable with Opera Mini.

Collapse
 
nicolalc profile image
Nicola

Consider than I've never tested it on a mobile browser because is still a WIP, anyway thanks for the feedback.

Collapse
 
garrett profile image
Garrett / G66

This is exactly the post I needed today. Thank you!

Collapse
 
sawzarnilinhtay profile image
Zarni

"The only issue related with css variables is IE (every time is IE the problem) compatibility.

I prefer to use vars only with SCSS, because I need to give IE compatibility for my projects.

Anyway nice examples, I love the new css grid system, expecially if combined with flexbox!" by Nicola. ->>me too

Collapse
 
vusi47dev profile image
Vusi

Thanks a lot, this was really helpful because I've been struggling with responsiveness for a while now. Didn't realize how powerful CSS variables are.

Collapse
 
ryandotfurrer profile image
Ryan Furrer

Great post! I've just started messing with CSS Variables and hadn't thought of using them this way. It's so much cleaner and IMO makes responsiveness much less daunting.

Collapse
 
zachsaucier profile image
Zach Saucier

Or you could use this exact same approach with the rem unit and have better browser support.

Collapse
 
sebbdk profile image
Sebastian Vargr

Assigning css variables with media queries.. Bloody brilliant! Never thought of that. :)

Thanks!

Collapse
 
mjcoder profile image
Mohammad Javed

Awesome article. Variables are the way to go! Forget IE! 😝

Collapse
 
gnio profile image
Gnio

When a 2 minutes read beats rage-quitting.

Thank you!