Media Queries: Responsive Design with CSS

This chapter will explore media queries, a fundamental tool in responsive web design. Media queries allow you to apply CSS styles based on various conditions, such as screen size, resolution, orientation, etc. This ensures your web page looks great on all devices, from phones to desktops.

What are Media Queries?

Media queries are a CSS feature that enables you to apply styles conditionally. They consist of a media type and one or more expressions that check for the conditions of a particular device environment. If the conditions are met, the styles within the media query will be applied.

The basic syntax of a media query is as follows:

@media (condition) {
  /* CSS rules here */
}

Common Media Query Conditions

There are more options than what we will cover here for media queries, but I wanted to show you a couple of the most common ones you'll usually reach for (especially when it comes to responsive layouts:

max-width and min-width

  • max-width: Applies styles if the viewport is less than or equal to the specified width.
  • min-width: Applies styles if the viewport exceeds or exceeds the specified width.
/* Apply styles if the viewport is 600px or narrower */
@media (max-width: 600px) {
  .container {
    background-color: lightblue;
  }
}

/* Apply styles if the viewport is 601px or wider */
@media (min-width: 601px) {
  .container {
    background-color: lightgreen;
  }
}

Test it out by opening this CodePen and resizing your window to see the colors change when the thresholds are hit.

Testing Responsiveness in the Browser

As a slight detour, testing responsiveness is important for creating flexible applications. Luckily, most browsers have developer tools that will help you (Chrome, Firefox, and Safari).

Here's how to use them:

  1. Open Developer Tools:

    • Press F12 or Ctrl+Shift+I (Windows/Linux) or Cmd+Option+I (Mac). Or right-click on the web page and select "Inspect".
  2. Switch to Responsive Mode:

    • Click the device toolbar icon (phone/tablet icon) or press Ctrl+Shift+M (Windows/Linux) or Cmd+Shift+M (Mac). Or click the tab shown below:

Showing the devtools open with the mobile icon highlighted to show where to press.

You'll then be able to one of two things:

  1. Select a Device Preset:

    • Choose a device from the dropdown menu (e.g., iPhone, iPad, Galaxy).
  2. Adjust Screen Dimensions:

    • Manually resize the viewport by dragging the edges.
    • Enter custom dimensions in the width and height fields.

Combining Multiple Conditions

You can combine multiple conditions using logical operators such as and, or, and not.

/* Apply styles if the viewport is between 600px and 800px wide */
@media (min-width: 600px) and (max-width: 800px) {
  .container {
    background-color: lightblue;
  }
}

/* Apply styles if the viewport is less than 600px or more than 800px wide */
@media (max-width: 599px), (min-width: 801px) {
  .container {
    background-color: lightgreen;
  }
}

/* Apply styles if the viewport is not in landscape mode */
@media not all and (orientation: landscape) {
  .container {
    background-color: lightcoral;
  }
}

Responsive Layout Example

As always, let's create something more tangible. We will make a simple responsive layout that changes based on the viewport width. We'll start with a basic design and then use media queries to adjust it for different screen sizes.

HTML Structure

<div class="container">
  <header class="header">Header</header>
  <nav class="nav">Navigation</nav>
  <main class="main">Main Content</main>
  <aside class="aside">Sidebar</aside>
  <footer class="footer">Footer</footer>
</div>

CSS Styles

/* Base styles */
.container {
  display: grid;
  grid-template-areas:
    "header"
    "nav"
    "main"
    "aside"
    "footer";
  gap: 10px;
}

.header, .nav, .main, .aside, .footer {
  padding: 10px;
  background-color: lightgray;
}

.header { grid-area: header; }
.nav { grid-area: nav; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }

/* Styles for screens 600px or wider */
@media (min-width: 600px) {
  .container {
    grid-template-areas:
      "header header"
      "nav main"
      "aside main"
      "footer footer";
    grid-template-columns: 1fr 3fr;
  }

  .nav {
    background-color: lightblue;
  }

  .main {
    background-color: lightgreen;
  }

  .aside {
    background-color: lightcoral;
  }
}

/* Styles for screens 900px or wider */
@media (min-width: 900px) {
  .container {
    grid-template-areas:
      "header header header"
      "nav main aside"
      "footer footer footer";
    grid-template-columns: 1fr 3fr 1fr;
  }

  .header, .footer {
    grid-column: span 3;
  }

  .nav {
    background-color: lightgoldenrodyellow;
  }

  .main {
    background-color: lightseagreen;
  }

  .aside {
    background-color: lightsalmon;
  }
}

In this example, the layout changes based on the viewport width: For screens 600px or wider, the navigation moves to the left of the main content, and the sidebar moves below it.

  • For screens 900px or wider, the navigation, main content, and sidebar are arranged in three columns, and the header and footer span all three columns.

And here's the code to play with.

With this section complete, you can see how, with a single CSS sheet and combining some of the techniques we have learned, we can create layouts that work on any device of any size.

As always, don't forget to practice these new skills.

BeginnerCSS
Avatar for Niall Maher

Written by Niall Maher

Founder of Codú - The web developer community! I've worked in nearly every corner of technology businesses: Lead Developer, Software Architect, Product Manager, CTO, and now happily a Founder.

Loading

Fetching comments

Hey! 👋

Got something to say?

or to leave a comment.