Free
lesson

Frontend.FYI PRO gives you instant access to all lessons of this and future courses! €149 one time, no subscription.

Learn about PRO

Responsiveness without media queries

This first lesson isn’t about Framer Motion, but might very well be the most enlightening lesson in this module.

Skip the media query entirely

This doesn’t mean you have to go all over board with super complicated CSS to prevent writing media queries. Just like everything in web development it is a balance between complexity and maintainability.

There are however quite some ways of writing your styles in a way that you don’t need media queries. These are what I want to show you in this lesson.

The web is responsive by default

If you just add a div on a page and add some text in there, it will be responsive. This is how the web was built. It’s only when us humans step in and think we can write the best code ever, we start messing it up.

I mean – just resize me. The text will automatically adjust. No media queries needed at all. (The resizing only works on desktop 😉)

Back when the very first mobile phones and later tablets were introduced, we started to look into solutions to make our websites fit onto the screens of those devices. It was then when things like “Mobile First” and media queries in general became a more commonly used thing.

Libraries like Bootstrap started to use terms like “small” and “medium” to define specific breakpoints for your styles. Naming conventions that aren’t very descriptive of when they will be applied. But on top of that, they also force you to think in fixed sizes / breakpoints.

Don’t think in fixed sizes

The web is a fluid medium. It has no fixed breakpoints, unless we define them. And you know what? The web also becomes so much better of we try to use these fixed breakpoints as little as possible. Let me show you.

Min- and max-width/height

It sounds so easy, but these four properties don’t get enough love. Take a look at the two snippets below — for most situations they do the exact same thing. However, the second option skips media queries entirely.

1
.container {
2
width: 50%;
3
}
4
5
@media (min-width: 768px) {
6
.container {
7
width: 768px;
8
}
9
}
1
.container {
2
max-width: 768px;
3
width: 50%;
4
}

If you’re thinking about responsive sizes where you need a media query, think if there’s a way you can combine width, min-width and max-width to achieve the same result without the media query. You’ll be amazed in how many situations you can skip the media query entirely.

CSS Grid or Flexbox

With the introduction of CSS Grid and Flexbox, we have even more options to make our layouts responsive without media queries.

Take a look at the code below, and resize the container via the handle on the right. You’ll see that the items will automatically adjust to the available space, and never become smaller than 100 pixels.

repeat(auto-fit, minmax(100px, 1fr));

This single line of code is all you need to make your grid items responsive. No media queries needed. It tells the grid to fit as many items as possible in the available space, and to never make them smaller than 100 pixels. If they become smaller, they will wrap to the next line so they can grow again.

1
.container {
2
display: grid;
3
grid-template-columns:
4
repeat(auto-fit, minmax(100px, 1fr));
5
}
Resize the container:

With flexbox we can achieve a somewhat similar result by using flex-wrap: wrap. This will make the items wrap to the next line when they don’t fit anymore.

1
.container {
2
display: flex;
3
flex-wrap: wrap;
4
}
5
6
.child {
7
width: 100px;
8
}
Resize the container:

The result is different though! The items will not grow to fill the available space, but will instead keep their fixed width. There is however another Flexbox property that can help us with that: Flex grow.

1
.container {
2
display: flex;
3
flex-wrap: wrap;
4
}
5
6
.child {
7
width: 100px;
8
flex-grow: 1;
9
}
Resize the container:

Learning these flexbox and grid properties will definitely make your life easier.

Use all these fancy CSS units

On the web we have a lot of different units to use. Pixels and percentages might be common to you, but have a look at this page on MDN and be amazed by the amount of units we have at our disposal.

Having so many units definitely makes it a bit confusing. However, it’s good to know what types of units are out there because they can definitely help you in writing less media queries.

Let’s take a look at two of my favorites:

  • 1ch is equal to the width of the character 0 in the current font. By using ch values instead of pixels or percentages, you are for example able to give your text a max width based on the content itself. max-width: 50ch will make the element as wide as 50 0 characters.
  • 1cq* Container query units are a more recent addition to CSS units. And they are so exciting! By using container queries you make your component be a percentage in width or height or any parent element (it’s container). This means that you can make your component be 50% of the width of its (grand) parent, without having to know the width of the parent. This is a game changer for responsive design. Check my video on the topic to learn more about container queries itself.

CSS Math functions

Did you know you can do some real math in CSS too? It is not as powerful as JavaScript, but it can do many useful things.

calc()

The most common used math function in CSS is calc(). It allows you to do simple math operations in your CSS.

1
.wrapper {
2
width: calc(50% - 20px);
3
}
4
5
.wrapper {
6
width: calc(50vw / (16 * 9));
7
}

clamp()

clamp() is a new math function that allows you to set a value based on a minimum, maximum and preferred value. In the example below we set the width of our image to a preferred size of 480 pixels. On top of that the image will never be smaller than 50% of the available space, and never larger than 100% of the available space.

1
.image {
2
width: clamp(50%, 480px, 100%);
3
}

min() and max()

min() and max() are two other math functions that can be very useful in responsive design. They allow you to set a value based on the minimum or maximum of two values.

min() will always take the smallest value of the two options, and max() will always take the largest value.

1
.video {
2
width: min(50%, 480px);
3
}
4
5
.video {
6
width: max(50%, 480px);
7
}

Conclusion

As you could see, there are many alternatives to writing media queries. The next time you are about the write a media query, come back to this page and see if there’s any alternatives.

That being said, of course there are still valid use cases for media queries. So let’s continue to the next lesson and learn how to use Framer Motion to animate our responsive designs.