3

Media Queries – Supporting Differing Viewports

This chapter will look in detail at CSS media queries, hopefully providing all that's needed to fully understand their capability, syntax, and future development. Where appropriate, we will use media queries to adjust the basic layout of our test site, adding relevant styles for wider screen sizes.

We ended the last chapter with a design for the https://rwd.education/ website. For the sake of this chapter, I have written some preliminary markup and added some corresponding basic "mobile" styles.

If you open the index.html file inside this chapter's start folder in a web browser, you will see that the design looks acceptable on devices with slim viewports, such as mobile phones:

Figure 3.1: The design looks fine at smaller viewports

However, it quickly starts to look a little stretched when you widen the browser window:

Figure 3.2: We definitely need to change the styles for wider viewports

The initial styles are written using a fluid/proportional approach. This means widths are generally written as percentages rather than fixed pixel sizes—the upshot being that the content at least grows and shrinks to fill the browser window regardless of how large or small it gets.

However, this still leaves you with the problem that when you go wide enough, you need to do something a little more drastic than just making things wider still!

We can fix this problem with media queries.

Media queries allow us to target specific CSS styles depending upon the capabilities of a device. For example, with just a few lines of CSS we can change the way content is displayed based upon things such as viewport width, screen aspect ratio, orientation (landscape or portrait), and so on.

In this chapter, we will:

  • Understand the use of the viewport meta tag to make media queries work on mobile devices
  • Learn why media queries are essential for a responsive web design
  • Understand the media query syntax
  • Learn how to use media queries in links, in @import statements, and within CSS files
  • Understand what device features we can test for
  • Consider whether to author similar media queries in one block or wherever it suits
  • Consider the latest capabilities added in Media Queries Level 4 that we can use today—media features like pointer, hover, and prefers-color-scheme

Back in Chapter 1, The Essentials of Responsive Web Design, we inserted a meta tag into the head of our web page to make it work on mobile devices. At that point, I made the promise that Chapter 3 would explain exactly what that tag was, what it does, and why we still have it. It's time to make good on that promise.

The viewport meta tag

When Apple released the iPhone in 2007, they introduced a proprietary meta tag called the viewport meta tag. Its purpose was to provide a way for web pages to communicate to mobile browsers how they would like the web browser to render the page.

Without this meta tag, iPhones would render web pages as a 980px wide window that the user would then have to zoom in or out of.

With this meta tag, it's possible to render a web page at its actual size and then adapt the layout to provide the kind of web page we now all expect to see when we browse the internet on our phones.

For the foreseeable future, any web page you want to be responsive, and render well across small screen devices, will still need to make use of this meta tag as Android and a growing number of other platforms also support it.

As you are now aware, the viewport <meta> tag is added within the <head> tags of the HTML. It can be set to a specific width (which we could specify in pixels, for example) or as a scale, for example, 2.0 (twice the actual size). Here's an example of the viewport meta tag set to show the browser at twice (200 percent) the actual size:

<meta name="viewport" content="initial-scale=2.0,width=device-width" />

Let's break the preceding <meta> tag down and understand what's going on. The name="viewport" attribute tells the browser this tag is dealing with the viewport. The content="initial-scale=2.0 section is then saying, "scale the content to twice the size" (where 0.5 would be half the size, 3.0 would be three times the size, and so on), while the width=device-width part tells the browser that the width of the page should be equal to device-width. The <meta> tag can also be used to control the amount a user can zoom in and out of the page. This example allows users to go as large as three times the device's width and as small as half the device's width:

<meta name="viewport" content="width=device-width, maximum-scale=3, minimum-scale=0.5" />

You could also disable users from zooming at all:

<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />

user-scalable=no is the relevant part here.

However, with zooming being an important accessibility requirement, it would rarely be appropriate to prevent zooming. In addition, many browsers disable the ability to prevent zooming for that very reason.

Right, we'll change the scale to 1.0, which means that the mobile browser will render the page at 100 percent of its viewport. Setting it to the device's width means that our page should render at 100 percent of the width of all supported mobile browsers. For the majority of responsive web design cases, this <meta> tag would be appropriate:

<meta name="viewport" content="width=device-width,initial-scale=1.0" />

That should be all you need to know about viewport meta tags from a responsive design perspective. In short, ensure you have one added or things are unlikely to look and behave as you might expect! To be certain everything is in order, ensure you test at some point on an actual device.

Noticing the ubiquity of the viewport meta element, the W3C has attempted to bring the same capability into CSS. Head over to http://dev.w3.org/csswg/css-device-adapt/ and read all about the @viewport declaration. The idea is that rather than writing a <meta> tag in the <head> section of your markup, you would declare the viewport settings in the CSS instead. To exemplify, something like @viewport { width: 320px; } in the CSS would set the browser width to 320 pixels. However, browser support is scant. As I write this, there seems little value in adding this to your CSS when all browsers understand the viewport meta tag.

Why media queries are needed for a responsive web design

If you head over to the W3C specification of the CSS3 media queries module (http://www.w3.org/TR/css3-mediaqueries/), you'll see that this is their official introduction to what media queries are all about:

A media query consists of a media type and zero or more expressions that check for the conditions of particular media features. Among the media features that can be used in media queries are 'width', 'height', and 'color'. By using media queries, presentations can be tailored to a specific range of output devices without changing the content itself.

While a fluid layout, created with percentages rather than fixed widths, can carry a design a substantial distance (we cover fluid layouts in full in the next chapter), given the gamut of screen sizes we have to cover, there are times when we need to revise the layout more substantially. Media queries make this possible—think of them as basic conditional logic for CSS.

Basic conditional logic in CSS

True programming languages all have some facility in which one of two or more possible situations is catered for. This usually takes the form of conditional logic, also known as "control flow," typified by an if/else statement.

If programming vernacular makes your eyes itch, fear not; it's a very simple concept. You probably dictate conditional logic every time you ask a friend to order for you when visiting a cafe, "If they've got triple chocolate muffins I'll have one of those; if not, I'll have a slice of carrot cake." It's a simple conditional statement with two possible results.

At the time of writing, CSS does not facilitate true conditional logic or programmatic features. Loops, functions, iteration, and complex math are still the sole domain of CSS preprocessors (did I mention a fine book on the subject of the Sass preprocessor, called Sass and Compass for Designers?). However, media queries are one mechanism that allows us to author basic conditional logic—styles applied depending upon whether certain media-based conditions are met.

Media query syntax

So what does a CSS media query look like and more importantly, how does it work?

Following is a complete but simple web page with no content but some basic styles and media queries:

<!DOCTYPE html>
<html class="no-js" lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Media Query Test</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <style>
      body {
        background-color: grey;
      }
      @media screen and (min-width: 320px) {
        body {
          background-color: green;
        }
      }
      @media screen and (min-width: 550px) {
        body {
          background-color: yellow;
        }
      }
      @media screen and (min-width: 768px) {
        body {
          background-color: orange;
        }
      }
      @media screen and (min-width: 960px) {
        body {
          background-color: red;
        }
      }
    </style>
  </head>
  <body></body>
</html>

Copy and save that into a new file, or, if you have the downloaded code for the book, you can find it in example_03-01.

Now, open the file in a browser and resize the window. The background color of the page will vary depending upon the current viewport size.

A default color is defined first, outside of a media query; when any of the media queries are true, the styles inside the media query overwrite the default.

The basic syntax of a media query is simple when you get used to it. You use the @media at-rule to communicate a media query and then write the media test in parentheses. The test must pass in order for the styles within the curly braces to be applied.

You can write media queries in links in HTML—to load particular style sheets if the media query passes. You can write media queries on CSS @import at-rules to determine which style sheets should be imported. You can also write media queries directly into a CSS file to determine which rules should be applied on the basis of which media queries resolve to true.

Let's look at each in turn.

Media queries in link tags

Here's what a media query looks like on a link you'd find in the <head> section of markup:

<link rel="stylesheet" media="screen and (orientation: portrait)" href="portrait-screen.css" />

This media query is asking "Are you a screen and is your orientation portrait?".

Media query on an @import at-rule

Here's the same rule on an @import statement:

@import url("portrait-screen.css") screen and (orientation: portrait);

You can see all the same component parts there—the file to be loaded, and the test that has to be passed. Different syntax, same outcome.

Using the @import at-rule in CSS makes the browser request the relevant file from the network and this can add to the number of HTTP requests. This can sometimes adversely affect site load speed.

Media queries in a CSS file

Finally, here's the same media query written inside a CSS file, or, within a style tag inside the HTML:

@media screen and (orientation: portrait) {
    /* styles here */
}

Inverting media query logic

It's possible to reverse the logic of any media query expression by adding not to the beginning of the media query. For example, the following code would negate the result in our prior example, loading the file for anything that wasn't a screen with a portrait orientation:

<link rel="stylesheet" media="not screen and (orientation: portrait)" href="portrait-screen.css" />

Although using the not keyword is occasionally useful, I find it is far simpler to just think about applying styles when you do want them. This way, you can stick to writing the tersest and simplest forms of media queries.

Combining media queries

It's also possible to string multiple expressions together. For example, let's extend one of our prior examples and also limit the file to devices that have a viewport greater than 800 pixels:

<link rel="stylesheet" media="screen and (orientation: portrait) and (min-width: 800px)" href="800wide-portrait-screen.css" />

A number of different media queries

Further still, we could have a list of media queries. If any of the listed queries are true, the file will be loaded. If none are true, it won't. Here is an example:

<link rel="stylesheet" media="screen and (orientation: portrait) and (min-width: 800px), print" href="800wide-portrait-screen.css" />

There are two points to note here. Firstly, a comma separates each media query, effectively acting like an or command. Secondly, you'll notice that after print, there is no trailing and or feature/value combination in parentheses. That's because in the absence of these values, the media query is applied to all media types. In our example, the styles will apply to all print scenarios.

You should be aware that you can use any CSS length unit to specify media queries. Pixels (px) are the most commonly used but ems (em) and rems (rem) are equally valid and applicable.

Everyday media queries

At this point it's probably prudent of me to repeat that in most situations, you don't actually need to specify screen. Here's the key point in the specification:

A shorthand syntax is offered for media queries that apply to all media types; the keyword 'all' can be left out (along with the trailing 'and'). I.e. if the media type is not explicitly given it is 'all'.

Therefore, unless you want to target styles to particular media types, just leave the screen and part out. That's the way we will be writing media queries in the example files from this point on. For example:

@media (min-width: 750px) {
    /* styles */
}

What can media queries test for?

When building responsive designs, the media queries that get used most usually relate to a device's viewport width (width). In my own experience, I have found little need, with the occasional exception of resolution and viewport height, to employ the other capabilities. However, just in case the need arises, here is a list of all capabilities that Media Queries Level 3 can test for. Hopefully, some will pique your interest:

  • width: The viewport width.
  • height: The viewport height.
  • device-width: The rendering surface's width (for our purposes, this is typically the screen width of a device).
  • device-height: The rendering surface's height (for our purposes, this is typically the screen height of a device).
  • orientation: This capability checks whether a device is portrait or landscape in orientation.
  • aspect-ratio: The ratio of width to height based upon the viewport width and height. A 16:9 widescreen display can be written as aspect-ratio: 16/9.
  • device-aspect-ratio: This capability is similar to aspect-ratio but is based upon the width and height of the device rendering surface, rather than viewport.
  • color: The number of bits per color component. For example, min-color: 16 will check that the device has 16-bit color.
  • color-index: The number of entries in the color lookup table (the table is how a device changes one set of colors to another) of the device. Values must be numbers and cannot be negative.
  • monochrome: This capability tests how many bits per pixel are in a monochrome frame buffer. The value would be a number (integer), for example, monochrome: 2, and cannot be negative.
  • resolution: This capability can be used to test screen or print resolution; for example, min-resolution: 300dpi. It can also accept measurements in dots per centimeter; for example, min-resolution: 118dpcm.
  • scan: This can be either progressive or interlace features largely particular to TVs. For example, a 720p HDTV (the p part of 720p indicates "progressive") could be targeted with scan: progressive, while a 1080i HDTV (the i part of 1080i indicates "interlaced") could be targeted with scan: interlace.
  • grid: This capability indicates whether or not the device is grid- or bitmap-based.

All the preceding features, with the exception of scan and grid, can be prefixed with min or max to create ranges. For example, consider the following code snippet:

@import url("tiny.css") screen and (min-width:200px) and (max-width:360px);

Here, a minimum (min) and maximum (max) have been applied to width to set a range. The tiny.css file will only be imported for screen devices with a minimum viewport width of 200 pixels and a maximum viewport width of 360 pixels.

Features deprecated in CSS Media Queries Level 4

It's worth being aware that the draft specification for Media Queries Level 4 deprecates the use of a few features (http://dev.w3.org/csswg/mediaqueries-4/#mf-deprecated), most notably device-height, device-width, and device-aspect-ratio. Support for those queries will remain in browsers but it's recommended you refrain from writing any new style sheets that use them.

Using media queries to alter a design

If you've read and at least partially understood what we have been through so far in this chapter, you should be ready to start using media queries in earnest.

I'd suggest opening the index.html file and the associated styles.css file from the start folder of this chapter's code. Then add some media queries to alter some areas of the page at certain viewport widths. Let's make a couple of changes together and then you can practice some of your own.

Let's look at the header section of what we have currently (viewport around 1200px wide):

Figure 3.3: At wider screens what we have in the browser doesn't match the designs

And here is the same section of the design we are building from:

Figure 3.4: The design calls for a different layout at wider viewports

We need to keep the design as it is for smaller viewports but amend it for larger ones. Let's start by adding a media query that makes the navigation links and the logo sit either side at 1200px and above:

@media (min-width: 1200px) {
    .rwd-MastHead {
        flex-direction: row;
        justify-content: space-between;
        max-width: 1000px;
        margin: 0 auto;
    }
}

If any of those styles don't make sense now, don't worry. We will be covering Flexbox layout in Chapter 4, Fluid Layout, Flexbox, and Responsive Images. What is important to understand is the media query itself. What we are saying is, "apply this rule, but only at a minimum width of 1200px."

And here is the effect of that rule in the browser:

Figure 3.5: Our first media query gets our navigation links over to the right

Now, the keen-eyed among you may realize that despite this new rule, which spreads out our logo and navigation links, we have some styles applied that we no longer need at this size. The following grab shows the no-longer-needed margin above and padding within the main navigation links:

Figure 3.6: There are styles being applied we want to reset at this viewport

Let's write another media query to fix that. We'll make this change at a slightly smaller screen width:

@media (min-width: 1000px) {
    .rwd-Nav {
        margin: 0;
        padding: 0;
    }
}

In this instance, we are saying, "above 1000px, make the margin and padding zero for the .rwd-Nav element." Notice that each time, in our media query, we only amend the specific properties we need to change?

By writing our "base" styles as we have, outside of any media query, our actual media queries only need to encapsulate the differences needed.

It might seem a little reductive but the preceding process is essentially all there is to working with media queries. Write the basic styles without media queries and then work wider and wider, adding media queries and changes wherever needed to affect the design as required.

If you have the time, I implore you to try writing some media queries for yourself, whether it's by using the test page here or something of your own you want to work with. Pick something you want to change, pick a viewport width, and add a media query to make the change happen.

Testing responsive designs on emulators and simulators

Although there is no substitute for testing your development work on real devices, there are emulators for Android and a simulator for iOS (for the pedantic, a simulator merely simulates the relevant device whereas an emulator actually attempts to interpret the original device's code). The Android emulator for Windows, Linux, and Mac is available for free by installing Android Studio from https://developer.android.com/studio. The iOS simulator is only available to macOS users and comes as part of the Xcode package (free from the Mac App Store).

Browsers themselves are also including ever-improving tools for emulating mobile devices in their development tools. Both Firefox and Chrome currently have specific settings to emulate different mobile devices/viewports.

Advanced media query considerations

The following section deals with concerns for when you are highly proficient in writing media queries. Think of these topics as micro-optimizations. If you are just starting with media queries, you certainly shouldn't be worrying about any of these topics yet. Jump on to the Media Queries Level 4 section instead!

OK, media query uber-geekery, here we go...

Organizing media queries

Ordinarily, for a browser, CSS is considered to be a render-blocking asset. The browser needs to fetch and parse a linked CSS file before the rendering of the page can complete. This stands to reason as the browser needs to know what styles to apply for laying out and painting the page.

However, modern browsers are smart enough to discern which style sheets, (linked with media queries in the head) need to be analyzed immediately and which can be deferred until after the initial page rendering. The upshot of this is that for these browsers, CSS files that are linked with media queries that don't apply to the current environmental situation can be "deferred" until after the initial page load, providing some performance advantage. There's more on this topic over on Google's developer pages: https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-blocking-css.

However, I would like to draw your attention to this part in particular:

...note that "render blocking" only refers to whether the browser will have to hold the initial rendering of the page on that resource. In either case, the CSS asset is still downloaded by the browser, albeit with a lower priority for non-blocking resources.

To reiterate, all the linked files will still be downloaded; they just may not necessarily require the browser to hold the rendering of the page.

Therefore, a modern browser loading a responsive web page with four different style sheets linked with different media queries (to apply different styles for different viewport ranges) will download all four CSS files but probably only parse the applicable one initially before rendering the page. Take a look at example_03-03 in the chapter's example code, which you may find more convenient to view at https://benfrain.com/playground/mq-downloads/. If you view that page with a slim viewport and you are proficient enough with your browser's developer tools, you can look in the network area and check that all files are downloaded, regardless of whether the media queries are actually being applied.

The practicalities of separating media queries

Apart from preference and/or compartmentalization of code, there is rarely a great tangible advantage in separating different media query styles into separate files. After all, using separate files increases the number of HTTP requests needed to render a page, which in turn can make pages slower in certain other situations. Nothing is ever easy on the Web! It's therefore really a question of evaluating the entire performance of your site and testing each scenario on different devices.

As a default approach, unless the project has considerable time available for performance optimizations, this is one of the last places I would look to make performance gains.

More practically, only once I am certain all images are compressed, all scripts are concatenated and minified, all assets are being served gzipped, all static content is being cached via CDNs, and all surplus CSS rules have been removed would I start looking to split up media queries into separate files for potential performance gains.

Nesting media queries "inline"

In all but exceptional circumstances, I recommend adding media queries within an existing style sheet alongside the "normal" rules. If you are happy to do the same, that leads to one further consideration: should media queries be declared underneath the associated selector? Or split off into a separate block of code at the end for all alike media queries? Glad you asked.

Combine media queries or write them where it suits?

I'm a fan of writing media queries underneath the original "normal" rule. For example, let's say I want to change the width of a couple of different elements, which are written at different places in the style sheet, depending upon the viewport width. I would typically do this:

.thing {
    width: 50%;
}
@media (min-width: 30rem) {
    .thing {
        width: 75%;
    }
}
/* A few more styles would go between them */
.thing2 {
    width: 65%;
}
@media (min-width: 30rem) {
    .thing2 {
        width: 75%;
    }
}

Can you see in this example, we have two separate media queries written testing for the same thing: @media (min-width: 30rem)? Surely duplicating media at-rules like this is overly verbose and wasteful? Shouldn't I be advocating grouping all the like media queries into a single block like this:

.thing {
    width: 50%;
}
.thing2 {
    width: 65%;
}
@media (min-width: 30rem) {
    .thing {
        width: 75%;
    }
    .thing2 {
        width: 75%;
    }
}
/* A few more styles go after */

That is certainly one way to do it. However, from a maintenance point of view I find this more difficult. There is no "right" way to do this, but my preference is to define a rule for an individual selector once and have any variations of that rule (such as changes within media queries) defined immediately after. That way I don't have to search for separate blocks of code to find the declaration that is relevant to a particular selector.

With CSS preprocessors, associating all alike rules can be even more convenient as the media query "variant" of a rule can be nested directly within the initial ruleset. But that's a technique for a different book. Curious? Take a look here: https://ecss.io/chapter8.html#h-H2_1.

It would seem fair to argue against the former technique on the grounds of verbosity. Surely file size alone should be enough reason not to write media queries in this manner? After all, no one wants a big bloated CSS file to serve their users. However, the simple fact is that gzip compression, which should be compressing all possible assets on your server, reduces the difference to a completely inconsequential amount.

I've done various tests on this in the past, so if it's something you would like to read more about, head over to http://benfrain.com/inline-or-combined-media-queries-in-sass-fight/. The bottom line is, I don't believe you should concern yourself with file size if you would rather write media queries directly after the "standard" styles.

As a final note on this, if you want to author your media queries directly after the original rule but have all alike media queries definitions merged into one, there are a number of build tools (at the time of writing Grunt and Gulp both have relevant plugins) that facilitate this.

That should give you everything you need to start wielding media queries like a pro. However, before we move on, there are a number of media query features in Media Queries Level 4 that we can actually start using today. Let's take a sneak peek!

Media Queries Level 4

Specifications at the W3C go through a ratification process, from Working Draft (WD), to Candidate Recommendation (CR), to Proposed Recommendation (PR), before finally arriving, many years later, at W3C Recommendation (REC). So modules at a greater maturity level than others are generally safer to use. For example, CSS Spatial Navigation Level 1 is in progress as I write this (http://www.w3.org/TR/css-nav-1/) at WD status with no support in browsers. Meanwhile the topic of this chapter, Media Queries Level 3, is implemented in every modern browser.

If you have a spare day, you can knock yourself out reading all about the official explanation of the standards ratification process at http://www.w3.org/2005/10/Process-20051014/tr.

At the time of writing, while CSS Media Queries Level 4 enjoys a draft specification: http://dev.w3.org/csswg/mediaqueries-4/, not all the features it documents enjoy browser implementations. So in this section, we will concentrate on Media Queries Level 4 features that we can make use of—features already implemented in browsers.

Interaction media features

Interaction media queries are concerned with pointing devices and hover capability. Let's see what each of these can do for us.

The pointer media feature

Here is the W3C introduction to the pointer media feature:

The pointer media feature is used to query about the presence and accuracy of a pointing device such as a mouse. If a device has multiple input mechanisms, the pointer media feature must reflect the characteristics of the "primary" input mechanism, as determined by the user agent.

There are three possible states for the pointer features: none, coarse, and fine.

A coarse pointer device might be a finger on a touch screen device. However, it could equally be a cursor from a games console that doesn't have the fine-grained control of something like a mouse:

@media (pointer: coarse) {
    /* styles for when coarse pointer is present */
}

A fine pointer device might be a mouse but could also be a stylus pen or any future fine-grained pointer mechanism:

@media (pointer: fine) {
    /* styles for when fine pointer is present */
}

Browsers report whether the value of pointer is fine, coarse, or none, based on the "primary" pointing device. Therefore, consider that just because a device has the capability of a fine pointer, it doesn't mean that will be the primary pointing device. Think of tablets where the primary pointer is a finger (coarse), but that has an attached stylus—a fine pointing device.

The safest bet is always to assume users are using touch-based input and to size user interface elements accordingly. That way, even if they are using a mouse they will have no difficulty using the interface with ease. If however you assume mouse input and don't provide affordance for coarse pointers, it might make for a difficult user experience.

Read the draft of this feature here: https://www.w3.org/TR/mediaqueries-4/#pointer.

The hover media feature

As you might imagine, the hover media feature tests a device's ability to hover over elements on the screen. If the user has multiple inputs at their disposal (touch and mouse, for example), characteristics of the primary input are used. Here are the possible values and example code.

For users that have no ability to hover, we can target styles at them with a value of none:

@media (hover: none) {
    /* styles for when the user cannot hover */
}

Or, as before, we might choose to make the non-hover scenario the default and then only add hover styles for devices that take advantage of them:

@media (hover) {
    /* styles for when user can hover */
}

Be aware that there are also any-pointer or any-hover media features. They are like the preceding hover and pointer but test the capabilities of any of the possible input devices.

That way, if you want to apply styles if any input device is capable of hover, regardless of whether that input device is the primary one:

@media (any-hover: hover) {
    /* styles if any input device is capable of hover*/
}

If you wanted to style an element a certain way based upon whether any attached pointer device was coarse, you could use any-pointer like this:

@media (any-pointer: coarse) {
    /* styles to be applied if any attached pointer is coarse */
}

The prefers-color-scheme media feature

In the last couple of years, popular operating systems for both desktop and mobile computers have given users the option of a "dark mode." To supplement this, operating systems expose this user preference to the browser by way of the prefers-color-scheme media feature. This media query is actually in Level 5 of the specification, not Level 4. However, it is in the odd situation of being implemented in most common browsers already.

At present there are three possible preferences: light, dark, and no-preference. To demonstrate this feature's use, we might amend the default colors for a page like this:

body {
    background-color: #e4e4e4;
    color: #545454;
}
@media (prefers-color-scheme: dark) {
    body {
        background-color: #333;
        color: #ddd;
    }
}

In the same vein as I'm recommending you to write your default "mobile" styles in the root of your style sheets, I would recommend writing the default colors in the root too and add one of these queries to cater for an alternative interface if needed or desired.

You can read the draft specification for the prefers-color-scheme media feature here: https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme.

Summary

In this chapter, we've learned what media queries are, why we need them, and how to include them in our CSS files. We've also learned how to use the viewport meta tag to make browsers render pages in the manner we'd like.

Don't worry about trying to memorize the syntax of media queries. Just get an understanding of the underlying principles and you can look up the syntax anytime; after all, that's what all developers do! As long as you understand what you can accomplish with media queries, our work here is largely done.

Back in Chapter 1, The Essentials of Responsive Web Design we noted that the three tenets of responsive web design are media queries, flexible layouts, and flexible media. We're three chapters in and we've only covered media queries! We're going to put that right in the next chapter.

In Chapter 4, Fluid Layout, Flexbox, and Responsive Images, we are going to take a deep dive into fluid layouts and images. We will cover how to convert a fixed-width design into a fluid proportional layout before laying out page elements with Flexbox, as well as covering flexible media in detail along with responsive images.

It's going to be another packed chapter, so get yourself comfy and I'll see you there!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.74.227