premium training

Managing Breakpoints & Media Queries Dynamically with SCSS

This is a premium training for Inner Circle members only.

More about this video

Managing breakpoints and media queries in vanilla CSS sucks pretty bad:

  1. Writing @media queries is annoying, and they’re separate from your main element styling.
  2. You can never remember the breakpoint values.
  3. CSS variables don’t work in media queries.
  4. Using standard media queries breaks scalability & maintainability.
  5. Issues are amplified when switching between max-width and min-width queries.

Managing breakpoints and media queries in SCSS is light years better.

It is also the perfect tutorial opportunity for learning the basics of maps and mixins in SCSS.

In this tutorial you’ll learn:

  • What a SCSS map is
  • How to create a SCSS map
  • How nested media queries work
  • What a mixin is
  • How to create a mixin
  • What the @content placeholder is for
  • How to get values from a map
  • How to create a max-width media query mixin
  • How to create a min-width media query mixin
  • How to use your mixins

Q: Kevin, can you provide the code snippets?

No, I no longer provide code snippets for tutorials because it hampers your progress. The best way to learn is to force yourself to write it from scratch. Even if you’re copying it word for word, writing it helps your brain learn faster than copying and pasting.

***** NOTICE FOR ACSS USERS *****

You don’t need to do this manually. I’m about to release a tutorial showing how to hook into ACSS’s mixins and use them directly without creating and managing them yourself.

Video Transcript

0:00:00
A lot of you have been asking for more Sass tutorials, so that’s exactly what I’m going to bring you. And I think today’s tutorial is a great first step in that direction because even if you’re a beginner with Sass, like an ultra beginner, I think you’re gonna be able to follow along with this. And it introduces concepts like maps and mix-ins, but it’s going to do it in a way that is not really very convoluted. Like it’s a small map, it’s a small mix-in, it’s very easy to follow along with.

0:00:29
And at the same time, it solves a very real common challenge with Vanilla CSS in the sense that breakpoints and media queries are very difficult to manage with Vanilla CSS. Not difficult to manage, but definitely not scalable, not maintainable, and SaaS opens the door for proper management of breakpoints and media queries. So let’s go ahead and share the screen and let’s dive in. First thing I wanna talk about is problems with media queries in Vanilla CSS, all right?

0:01:03
First of all, number one, writing the media queries is annoying, you have to write a lot of them, you’re gonna write them over and over and over again, and what you’re gonna see is that you can never remember the breakpoint values. That’s number two. It’s like, unless you memorize the breakpoints of every single website that you’re working on, which nobody really does, and you’re gonna see in a minute when I try to show you the manual way that this is done, I’m gonna have to look up the breakpoint value because I don’t memorize the breakpoint values of my websites.

0:01:32
Number three is that CSS variables don’t work in media queries. So if you have the idea that, hey, I think what we can do is use a variable in place of a static value and that’s going to solve everything. Well, you can’t do that because it doesn’t work in CSS. And I’m going to demonstrate that that does not work in CSS. Using standard media queries. This is number four. Using standard media queries breaks scalability and maintainability.

0:01:55
So like I said, your standard media queries and vanilla CSS are going to have static values in them. If your breakpoints ever change, you’ve got to go update every single media query manually. And we don’t want to do that because that’s chump-like behavior, right? So we’re gonna, this is gonna help you break out of that chump-like behavior using the power of SAS. Number five is that issues are amplified when switching between max-width and min-width media queries.

0:02:22
Sometimes it’s more efficient to write a max-width media query, which means I want these changes to take effect at this break point and below. Sometimes, actually very often, it’s more efficient to write a min width media query, which is also referred to as a mobile first media query, where we say we want these changes to take place at this break point and above. And so with SAS, we’re going to be able to easily swap between the two, whereas in Vanilla CSS, it can get a little bit more convoluted. Okay, so the first thing we have to take a look at is what does the old way look like?

0:02:55
So I’ve got this page right here where I have a logo, and at the L breakpoint, we want this logo to have a really ugly five pixel solid red border, just so that we can see something happen, okay? So what I’m gonna do is I’m gonna come down here and under logo, and this is Vanilla CSS. This is a Sass style sheet, but remember, you can write Vanilla CSS in a Sass style sheet. So we’re gonna write the Vanilla CSS version first, then I’m gonna show you a more Sass-like version, but still with limitations, and then we’re gonna go ahead and build out the ultimate thing that we want to have happen.

0:03:36
Okay, so a regular Vanilla CSS, underneath the instruction for your logo, you would then write a media query. And you’re gonna open the media query with parentheses, and this is where you’re gonna put your instructions, like what is the breakpoint that we are targeting? I wanna target the L breakpoint. So at the L breakpoint and below, I wanna see a five pixel solid red border. The problem is, and this is what I alluded to up here, you can never remember the breakpoint values.

0:04:05
This is one of the problems with media queries. So I actually have to go into Bricks and look up, like I’ve got to hover over this and get the value of the media query. That’s 991. So I’m gonna say 991 pixels. We’re gonna open the curly brackets because now we want something to happen at that breakpoint and below. Whatever we put in here, this is what’s going to happen at that break point and below. So I said I want a five pixel solid red border. So border five pixels solid red. Oh, but we can’t do that. I forgot we’re not nesting in SAS. We’re doing this in vanilla.

0:04:42
So what I actually have to do is write my logo statement over again to make sure that CSS knows, hey, I’m, I really want to target the logo and I want to make the logo have a border of five pixels solid red. Now I’m going to flip over to the front end and we’re going to see that I do in fact, look at that, at that break point, you see a five pixel solid red border appear. So this is how you would write it in Vanilla CSS. Notice that this statement is completely disconnected, disjointed from this statement up here.

0:05:14
I had to rewrite the targeting instruction. And so if you’ve got a lot of CSS going on and a big style sheet, these media queries, it’s very hard to understand which, like what blocks they belong to and so on and so forth. So SAS actually solves a lot of this with nested media queries. This is just a normal SAS superpower. So if you don’t really know a lot of SAS like in terms of functions and mixins and all this other stuff that’s going on, you should still write your CSS in a SAS style sheet simply for the nesting benefit. Let me show you exactly what I mean.

0:05:51
So what we’re going to do is we’re going to I’ll leave this here for a second, we’re just going to come down here. So within the logo targeting, I can write a media query in SAS. And I’m gonna say, media max width, and then 991 pixels, and then open. And notice I won’t have to target the logo instruction again, right? I don’t have to target that selector again. I’m already targeting it here. SAS is smart enough to know that this media query is for this selector, and therefore this is going to work just fine. I’m going to comment this out and demonstrate this. So we’re going to save. We’re going to go back to the front end and see that we get the exact same effect except with much more efficient CSS, right? Now my media query is actually contained within my component so it’s never going to get lost. It’s never going to become disconnected. That’s really, really powerful.

0:06:51
And I never had to target the selector again, right? Just a plain media query is able to get this done. So I’m gonna delete this, that’s fantastic. But the problem is, we now still have a static value as our media query, and that’s really where we’re losing things here. Because like I said before, if we ever need to change our breakpoint values, my gosh, every single media query in your CSS style sheets has to be edited manually. You have to go in and find all of those and then replace them with the new value. We don’t want to be in that kind of situation. And of course you still have the issue of knowing what the value is in the first place when you’re writing these queries. What I find is I constantly have to look them up. And I don’t want to constantly have to look up media queries, I just want to be able to flow through without any workflow issues when I’m writing my media queries. So what we really need to do is make this dynamic and we are going to use the power of SAS to do that. Now for those of you who are wondering, well Kevin why can’t you just make a variable for your breakpoint just like we always do in CSS.

0:08:05
So I could say something like breakpointL, and then I could give it a value of 991 pixels. So I just made a variable in CSS. This is different from a SAS variable by the way, but I just made a variable in CSS called breakpointL with a value of 991 pixels. Theoretically, what I should be able to come in here and do is say hey VAR breakpoint L is my L breakpoint and now we’re all good because it should just insert it should swap this effectively to 991 pixels, so I’m gonna go ahead and save and we are gonna refresh and Womp womp right it does not take effect, and this is because vanilla CSS does not, I don’t know why, it would be really good if they did. I don’t know why they don’t, but they do not support variables in media queries. So only 991 pixels here will work. Now I do want to show you one thing with SAS. So I can make a SAS variable called breakpoint L right there and then we’re going to go on the front end and there you go we do have a working one so SAS is able to handle variables in media queries but this is still not the best way to handle it because what you’re going to end up doing with this method is you’re going to have to be just create a lot of them like this, basically all your break points.

0:09:39
And that’s not bad, it’s not wrong, it’s not that it wouldn’t work, but there is a better way to handle this and a way that will give you added functionality going forwards off into the future. It’s kind of like the best practice way to handle this, let’s say. And that is by creating a SaaS map. And what a SaaS map is, is effectively like a fancy list.

0:10:04
So you can actually have just lists in SAS of things, or you can have maps of things, and a map is just a fancy list. So what I’m gonna do is show you how to create a map, and then you’re gonna see what this actually brings us to be able to do. So here’s how you write a variable. The way that you write a map in SAS is exactly the same way. I’m gonna take away the value of this variable, and I’m gonna replace it with parentheses, and then I’m gonna hit enter.

0:10:35
So you see that the structure of a map is exactly the same as the structure of a variable. You can think of a map as like an advanced variable, okay? And so I have this, I had a variable with a value, now I have a variable with an open parentheses so that I can put basically a group of things, right? I said it’s an advanced list. The way the list is structured is that there is a key and a value. A key is like a label or a name or whatever, right?

0:11:02
So we’re making a map called breakpoints. So I’m just gonna change the name to breakpoints. This is gonna be all of our breakpoints, okay? So what are the keys? The keys are all of my breakpoints. So if I go here, I’m gonna have an XL breakpoint, an L breakpoint, an M breakpoint, and an S breakpoint. Basically the same things we already know from automatic CSS. So I’m gonna say here’s my XL. Now null is a it’s an okay value. It’s an acceptable value in SAS. So until I’m ready to put in my values, I’m just gonna put the word null. And what you’re also going to notice is that I’m not putting semicolons at the end of these like I would with normal variables because this is a list.

0:11:46
And in a list, it makes sense to delimit the list with a comma instead of like an actual semicolon as if this is the end of something. The semicolon is down here, noting this is the end of the map. Commas are used within the map to separate out all the key value pairs. Okay, so we have xllm is gonna be null and s is gonna be null. I have now effectively created a map in SAS.

0:12:16
It’s like that easy, okay? It’s not really, really, really complicated. You just have to be introduced to the concepts and understand how they work in the real world. This is a way of organizing variables basically. Okay, now I want to talk about this last comma right here. It can be used or not used. It doesn’t matter, that’s not going to break anything. But if you don’t use these commas, your map will break. So you can have a comma on the last one or you can not have a comma on the last one, that really doesn’t matter. So I’m going to go ahead and save here and now what I’m going to do is plug in my values. So we’re gonna say 1279 and then we’re gonna come in here and grab the next one which is 991 and then we’re gonna come in and grab the M breakpoint value which is 767 and then we’re gonna come in and grab the S value which is 479 and now guys we have a fully created SAS map for our breakpoints.

0:13:14
Now, here’s what we want to do. What is the goal? Before we go any further in this, we need to know what the goal is. What is our CSS going to look like? I showed you the vanilla way to do it, and now I’m gonna show you the dynamic way to do that. Here’s what we eventually wanna do. We wanna be able to say, at include, and I’m gonna explain exactly what this means in just a second, breakpoint, and then put parentheses, and just tell it the break point we want and just say like, hey, the L break point like this.

0:13:45
And then what I can do is open up and I can put in my instruction like border five pixel solid red. And in terms of nesting, we can do it either way. You can do it either way. You could say logo, like do it the old school way and then put your border five pixel solid red in or you could have a nested instruction where we’re targeting our logo with stuff like I could just bring this in right here and instead of writing an actual an actual media query there I would do my at include breakpoint L and then hit save and that’s all see I don’t need to know any values I don’t need to remember any values if the values ever need to change this is all going to update dynamically.

0:14:26
I just need to know the label of the break point I’m targeting. Just like you do with utility classes, just like you have it up here in the builder where it’s XL, L, M, and S very easy to understand. It works between all these different websites. You never have to know the values of your break points. You don’t even have to know how to write the media queries. Like if you’ve written them once the at include, it’s all done for you. All you have to remember is I wanna do a break point thing here, so I at include a break point, here’s the break point I wanna target, you just use the name of the break point and then write your instructions and you are good to go my friend.

0:15:04
So this is eventually what we wanna get to right here. I’m gonna go ahead and delete all of this. Obviously that’s not gonna work yet because we haven’t set up everything. But we are a little bit of the way. We’ve got our map created. I’m gonna go ahead and delete this as well. Let’s get rid of this media. Let’s go back kind of to our starting point. And I’m gonna take this and it says, step one, create a map for our breakpoints.

0:15:29
And we have done that. There is our map right there. Step two, it says create mix-ins to generate the media queries. Okay, perfect. So what we’re gonna do is create a mix in for our first media query. We need two media queries. We’re gonna have one for max width, which means this break point and down.

0:15:49
We’re gonna have another media query for min width, which means this break point and up. They’re both gonna use the same labels. They’re still gonna pull the same values. We’re gonna use them in the exact same way. Let’s get it done, okay? So the way that you create a mix-in, and let me explain what a mix-in is. A mix-in is like a recipe. It’s like preset instructions.

0:16:11
If you were baking, right, you’re gonna follow a recipe. Take part of that recipe where it says like, put X, Y, Z in a bowl and mix and yada yada. Take that, if you could just like copy paste that into actually like an action, like let’s say there was a robot, right, doing the cooking, and you could just plug that set of instructions into the robot and the robot does it, that’s basically what a mixin does. It just takes preset instructions and applies them where you want them applied.

0:16:39
So we’re gonna create a preset for our media query, all right, so what we’re gonna do is create a mixin by writing at mixin, that’s it, it’s very easy, right? You just, hey, I wanna create a mixin. Okay, at mixin. Then you give the mixin a name. We’re gonna give this the name of breakpoint. Then you can use parentheses to pass arguments to the mixin. These are called arguments, but really what it is is we’re passing data into the mixin, okay?

0:17:05
That’s the way that I think about it. We’re just passing data into the mixin. So I’m gonna open this. Now what data are we going to need to pass into the mixin? We’re gonna need to tell the mixin what breakpoint I want to target. So you could literally say this could be like name, it could be label, it could be like, these, think of these, it could be key, right? It could be whatever you want.

0:17:28
It’s whatever you want these things right here, these keys, they’re officially called keys, but it’s whatever you want them to be called, okay? So we could say key, we could say label, we could say name, we could say extension, right? So I’ll say, let’s just say name. We’re gonna name our breakpoints, MLS whatever, all right? So we’re gonna get the name. Now, what we’re gonna do is write the actual media query. So we do add media, and then we do max width, and then we need a value, remember 991 pixels, and then we open up our curly brackets, and this is where you would write your instructions, right?

0:18:05
But this brings us to a point of like, how do we know what needs to go inside the media query? We don’t, we actually need it to be open ended. We need a way to dynamically insert whatever content we want and in SAS, here’s a really, really great way to do this. You write the word at content, like, Hey, my content’s going to go here eventually. Okay. Just like, this is the recipe, but I don’t know what’s going to go in here yet. So it needs to be whatever I want at the time I’m using the mix in.

0:18:38
So I use this placeholder called at content. And that means I can put anything there that I want as if I’m writing CSS at the time. Okay. You’ll see how this all comes. Well, I already showed you how it all comes together, but you’ll see it again in working fashion in just a second. The real problem here is this value. We all know we cannot use a static value right here. This defeats the purpose. Why am I creating a mixin with a static value?

0:19:05
I could have just written a media query with a static value, right? So this has to be dynamic. So what do we do? We need a way to get the value of each breakpoint Dynamically from the map and this is what a map allows you to do, right? If we weren’t using a map, we really wouldn’t be able to do this All right The fact that I put this in I put all these breakpoints in a map gives us this superpower So if I want to get something from a map in SAS I’m saying that very, very slow.

0:19:39
If I want to get something from a map in SAS, I need to use a function called map get, okay? If I want to get something from a map, I need to use a function called map get. And so what I’m going to say is map get, and then you open parentheses. When you want to get something from a map in SAS, you need to tell it what map you need to get the thing from, okay? The map is called breakpoints.

0:20:05
We gave the map a name called breakpoints. I’m going to tell it, hey, get something from breakpoints. Then I’m going to create a comma here, and I’m going to tell it, you know what you need to get? You need to get the name that I’m passing dynamically in the mixin. And it’s automatically going to get the value. So if I tell you, here’s the map, here’s the name, it already knows I want the value okay so we’re gonna pass the name in and then this function is gonna run basically and say all right we’re gonna go look in breakpoints for that name right there we’re gonna get the value and this whole statement right here is going to get replaced with the value of whatever this is okay all right perfect so we have created my friends our first mixin now what we need to do is test our mixin. So we’re going to come down here and we’re going to grab our initial code. We’re going to bring it down. Here’s our testing center. Okay and we’re going to look and make sure do we still have a logo that’s centered? Is it still 20 rem? Yes. All of that stuff is going on. Can we make it a border 5 pixel solid red just to make sure we’re still in tune and everything is working.

0:21:13
Yes, it is five pixels solid red. Okay, so now it is time to use our mixin and see if we can dynamically create a media query. So I’m gonna enter, enter, give us some space to work with here. And what am I gonna say? Am I gonna say at media and all that? No, no, no, I don’t have to do that anymore. What I need to do is call my mixin. And the way you call a mixin is with the word include. So it’s at include. So I’m including my mixin in these other instructions. Here’s the instructions. I’m gonna include my mixin as well. And so my include, what mixin do I want? Well I gave it a name. Remember?

0:21:52
Breakpoint. So breakpoint. And then I need to tell it what breakpoint. I’m gonna open my curlies, but I’m gonna tell it what breakpoint I want to target, right? So let’s just say L. See how fantastic that is? I don’t need to know that L is 991 pixels, I don’t care. Right? So you’re thinking about three month rule and all of this. Yeah, it’s perfect for the three month rule because you don’t need to know any static values. You just need to know what the names of your breakpoints are which are the names of the breakpoints in ACSS, which are the names of the breakpoints that you use on every single website you build.

0:22:26
Okay, so include breakpoint L. What do I wanna include? Well, I wanna include the instruction, border five pixel solid red. I don’t have to target the logo selector again because I’m nesting it. I’m using another SAS superpower of nesting to keep my CSS very efficient. And now what we’re gonna do is go to the front end. Oh gosh, look at this.

0:22:50
It is all working, my friends. Okay, so we’ve got our mixin working. We’ve got our nice little map. Hey, if you ever need to add a breakpoint, like, hey, I need to add an XXL, you just add a key and a value to this map and suddenly your mixins all now support this new breakpoint. You can start using this new breakpoint everywhere, just like that, okay?

0:23:14
All right, so now I’m gonna come down here, we need one more step, and that is creating our min width breakpoint, okay? So we’re gonna come down, create a mix in, and I’m just gonna change the name, this is gonna be breakpoint up. So I breakpoint, which is gonna affect here and down, I breakpoint up, which is gonna affect here and up. Make sense? All right, so now everything else is the same, the name, and then in the media query, all I need to do is change max to min because that’s what creates the difference between down and up.

0:23:46
Max width goes from here down, min width goes from here up. So there we go. I just copied, pasted, changed a couple names. I now have a second media query that I can use. And so now we’re gonna see if I change this to break point up and I hit save, I can go back here to the front end now and I’m gonna have my border everywhere at all these desktop sizes but the minute I get to the L breakpoint the border actually goes away it works in reverse now right because I said at the L breakpoint and up I want a five pixel solid red border so all these mobile breakpoints down here no red border but the minute I get to 991, right there, it comes in.

0:24:30
And then I have it everywhere from that point forwards. That is a mobile first media query or a min width media query. Okay, so fantastic. Let’s do, it’s all working. This is the end of the tutorial. If you got it, if you’re good, you can feel free to stop now. But for everybody else who’s maybe more on the beginner side of things, I just want to reiterate, go over everything one more time very, very cleanly.

0:24:56
So what do we do first? Create a map. What is a map? A map is like an advanced list. It is kind of like a variable, but with more variables inside of it. And then we have to make sure that we give things a name and a value. That’s a key and a value. We use commas to separate those. Our map for this is very, very, very simple. Then we come down and we create a mixin.

0:25:20
What is a mixin? A mixin is like a recipe. It’s like a predetermined set of things that we can include in our CSS. And so we created our mixins for our breakpoints. We gave it a name. This is the name of the mixin. And then we pass an argument, which is basically just an instruction for what data to get.

0:25:40
And we called that name because it’s the name of our breakpoint right here. Then we wrote a media query and we wrote a map get statement because we wanted to get the value of a key from our map. So we wrote a map get function that said, hey, go look for the map called breakpoints, grab the name that I just passed to you inside of the mixin, inside of the include statement. And then I’m using the at content placeholder to say, I don’t know what is supposed to go here yet.

0:26:10
It’s actually whatever I want it to be. So let’s just use a placeholder called at content. I did the same thing for making a breakpoint up mixin. And then when we use them down here, you can use them the way you would use them, use a media query in vanilla CSS by putting it down here with another targeting instruction, or you can use SAS nesting to just put your mixin inside the block you’re already working on, and it’s going to all work exactly the same way.

0:26:43
But obviously, with this method of nesting, it’s more efficient and it’s more organized. Everything stays together kind of as one CSS unit. All right, let me go back to camera. I really hope that, you know, I think this is a perfect kind of first tutorial for introducing maps and mix-ins and things like that. But obviously, if you have any questions, if I was unclear on any part of that, go ahead and drop comments below.

0:27:09
I’m happy to jump in and help. And if you love this, if you wanna see more SAST magic like this, then definitely vote down below in the comments. Tell me you want to see more and I will bring you more SaaS tutorials. All right guys, that’s it, peace.