Lesson Weekend

In Intro to Programming we learned about responsive web design, and how it ensures websites look great on all screen sizes.

In this lesson we'll review and learn more about media queries, and how they create layouts that dynamically change based on viewport sizes.

Also, keep in mind this week will focus only on implementing the media query code that make a site responsive. We won't explore how to make informed design choices for how a site you and a pair make should be built responsively until next week.

Media Queries

According to the Mozilla Developer Network Documentation on Media Queries:

”A media query consists of a media type and at least one expression that limits the style sheets' scope by using media features, such as width, height, and color. Media queries, added in CSS3, let the presentation of content be tailored to a specific range of output devices without having to change the content itself.”

In plain English, a media query is a block of CSS applied only when certain conditions about a user's viewport are true. For instance, CSS in a media query with a 500px maximum width declared would only be applied when the user's viewport width is below 500px.

Here is an example of them in action:

@media screen and (min-width:600px) {
  nav {
    float: left;
    width: 25%;
  }
  section {
    margin-left: 25%;
  }
}

@media screen and (max-width:599px) {
  nav li {
    display: inline;
  }
}

When the screen is at least 600px, the first query above is activated and would make our example layout look like this. Notice how the sizes, position, and margins of the nav and section areas reflect the styles declared in that first query:

exhibit a media query example

Yet if that viewport becomes/is 599px or less wide, the second query is activated, styling the page like this:

exhibit b media query example

Brush up on the basic structure of media queries and how they work by referring to this lesson.

Media Query Review

We briefly covered media queries in Intro. However, because they're such a cornerstone concept let's review them before advancing.

The following is from the Media Queries and Responsive Design lesson in week one of Intro. Carefully review it now. (You'll likely find it makes far more sense this time around!)

Media Query Practice

Let's walk through creating media queries...We'll create a project directory named media-query-practice. Within it, we'll need a .html file named media-query-site.html, and another directory named css. In the css directory we'll create a file called styles.css.

The project structure should look like this:

  media-query-practice
  ├── css
  │   └── styles.css
  └── media-query-site.html

Next, let's add simple HTML:

media-query-site.html
  <!DOCTYPE html>
  <html>
    <head>
      <link href="css/styles.css" rel="stylesheet" type="text/css" media="all">
      <title>Media Queries</title>
    </head>
    <body>
      <h1>Media Queries</h1>
      <div class="column">
        <p>Media queries allow us to make our sites <em>responsive</em>. We can use media queries to apply CSS styling only when certain conditions apply. For instance, our sites can look different depending on the size of the screen, or <em>viewport</em> a user is viewing our content with. We can also change the way our site appears if a user is printing our website, or using a screen-reader! </p>
      </div>
      <div class="column">
        <p>Using media queries and responsive design allows us to ensure that our site looks and works great no matter <em>how</em> the user is viewing it.</p> And, as more and more people use more and more devices to browse the internet, integrating media queries into websites is becoming a common, widespread practice!
      </div>
      <div class="column">
        <p>Are you beginning to see the possibilities here? Media queries are awesome!</p>
      </div>
    </body>
  </html>

If we load our media-query-site.html file in the browser, it should currently look like this:

basic-site-no-queries

Basic Structure

Media queries are located in CSS stylesheets. Because CSS cascades, they should be located at the bottom of the file, to prevent other style rules from overriding them.

They begin with @media, and contain a set of parenthesis and curly braces:

styles.css
  @media () {

  }
  • @media tells the browser this is a media query.

  • The parenthesis will eventually define when this query's CSS should be applied. We'll get to this in a moment.

  • The curly braces will eventually contain the CSS that will be applied when conditions are true.

Media Type

Media queries often specify something called a media type, which refers to the type of media-viewing device the user is viewing our site with. We have the following options to choose from:

  • all: any and all devices.

  • print: Refers to viewing our site in "print preview" mode. For instance, if we had a website with a dark-colored background that users may want to print, we could use a print media query that removes the dark-colored background to make our website's information more legible in a printed format.

  • screen: Refers to color screens.

  • speech: Refers to screen readers that assist visually-impaired users.

If you do not explicitly specify a type, media queries will default to all.

We can add the media type to our query like this:

styles.css
@media screen () {

}

By including the media type screen we're instructing our site to only apply the CSS this media query will contain to the site when/if a user is viewing it through a screen.

Media Features

Next, our media query requires we include something a Media feature. These are specific properties and details about the manner the user is viewing content. The most commonly-used media features are:

  • height: Describes the height of the viewport in pixels. It can also have a min or max prefix. We can say max-height to specify the maximum height a media query's CSS should apply to. Or min-height to define a minimum height.

  • width: Describes the width of the viewport in pixels. Like height, it may also have a min or max prefix.

  • orientation: Indicates whether the viewport is landscape (wider than it is tall) or portrait (taller than it is wide).

  • You can learn about the additional, less common features in the MDN Documentation on Media Queries.

Let's use the width media feature in our query. We'll also include the max prefix to specify a maximum width:

styles.css
  @media screen and (max-width: 768px) {

  }

We've done a couple things here:

  • First, we add the word and between our screen media type, and the parenthesis containing our new media feature. When using both a media type and a media feature this is required.

  • Then, we include max-width: 768px in our parenthesis.

    • width is our media feature.
    • The max prefix specifies that the CSS we will eventually include in this media query should only be applied to viewports with a maximum width of 768px.
  • 768px simply refers to size (in pixels) we'd like to define as the maximum. When defining pixel sizes in CSS, the px suffix is required.

Breakpoints

This means the CSS we will include in this query will only be applied when the user's viewport is under the max width of 768 pixels. This is known as a breakpoint.

A breakpoint is the point when a media query's condition becomes true. For instance, our media query has a max-width of 768px, so it will apply its styles only when the viewport is less than 768px wide. 768px is therefore the breakpoint, because it is the point when the query is "activated".

Media Query CSS Rules

We can include any valid CSS in a media query. The only difference is that it will only be applied when the defined conditions are met.

Let's add basic styles to see when they're being applied:

styles.css
@media screen and (max-width: 768px) {
    body {
        background-color: black;
        color: white;
    }   
}

Here, we're saying that if the user is viewing our site on a screen, whose viewport is no larger than 768 pixels, the background will be black and the font will be white.

If we refresh the page, we can see it still looks the same:

basic-site-query-not-applied

However, slowly make the browser window narrower. When it's narrower than 768 pixels the media query is activated; our background turns black, and our text turns white!

media-query-applied

Multiple Media Queries

We can also use multiple media queries at once to address a variety of viewport sizes and media types. Let's add another query:

styles.css
  @media screen and (max-width: 768px) {
    body {
      background-color: black;
      color: white;
    }   
  }

  @media screen and (max-width: 480px) {
    body {
      background-color: teal;
    }
  }

If we refresh our page we can see it still has a white background if its width is over 768 pixels, and a black background between 480 pixels and 768 pixels. But thanks to our second query our background is now teal if the site is fewer than 480 pixels wide!

second-query-activated

Notice the font color is still white after the background turns teal, even though the second media query did not specify a font color. This is because the viewport width is still technically less than 768 pixels; so unless we override the color property with a new property, it will remain white.

Sometimes multiple media queries can apply at once. For instance if a viewport is under 480 pixels both media queries will apply because a size under 480 pixels is under both the maximum width value of 768 and the maximum value of 480.

When multiple media queries apply, the most-recently applied query's CSS will override the other queries' CSS if they contain the same selectors and properties. In the example above background-color defined in the first media query is being overridden by the background-color property in our second media query when the viewport is narrower than 480 pixels.

Defining Viewport Ranges

We can also apply both minimum and maximum values to a media query. This can especially come in handy if we don't want to worry about multiple media queries applying at once.

We could add a min-width feature to one of our existing queries like this:

styles.css
  @media screen and (max-width: 768px) and (min-width: 600px) {
    body {
      background-color: black;
      color: white;
    }   
  }

  @media screen and (max-width: 480px) {
    body {
      background-color: teal;
    }
  }

Notice there is another and between the two media features in parenthesis, just like the and between our media type and first feature. This first query instructs our site to apply a black background and white text when the viewport is between 768 and 600 pixels wide.

Now, our site begins with a white background, and no styling applied:

largest-size

As we slowly reduce the width of its browser window, its background turns black, and text turns white at 768px:

smaller-size

But now, once its width is smaller than 600px (but below the 480 pixel width that will activate another media query), it reverts back to white:

almost-smallest

Yet, once it reaches 480 pixels or smaller, it still turns teal:

second-query-activated

More CSS in Media Queries

You can define any CSS in a media query; not just background colors! For instance, we learned how to create columns in a previous lesson. Oftentimes, sites will display text in multiple columns on larger screens, then condense it into a single column for easier reading on smaller devices as seen in this example.

Let's create another media query. This time, we'll use the min prefix on the width feature. We'll specify that any viewport above 768px should float our text into columns. This means that any viewport below the size of this breakpoint will display text in a single column:

styles.css
@media screen and (min-width: 768px) {
  .column {
    width: 300px;
    float: left;
    padding: 20px;
  }
}

@media screen and (max-width: 768px) and (min-width: 600px) {
  body {
    background-color: black;
    color: white;
  }   
}

@media screen and (max-width: 480px) {
  body {
    background-color: teal;
  }
}

And look! Larger screen sizes see our text in columns:

text-in-columns

But if we resize to a smaller viewport, text is condensed into a single column:

single-column-text

Lesson 10 of 36
Last updated more than 3 months ago.