- June 17, 2021
- Posted by: team SOUTECH
- Category: Responsive Web Design
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.
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.
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.
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!