Safe media queries

By Opera Software

14th December 2011: This article is obsolete

This article is obsolete/out of date, so should no longer be treated as a current or reliable source of information. Media queries are now supported much more reliably across browsers. Please consult the following for more up-to-date information:

Introduction

Certain page authors reject media queries off-hand as a viable solution, claiming that the rules within them are not ignored by browsers with broken parsers (ie, ones that do not ignore unrecognized constructs like they are supposed to,) which in turn implies the pages they are applied to do not display as intended across browsers. This article provides analysis of the problem at hand, and offers a simple solution that does not resort to hacks, which should hopefully make such page authors consider giving media queries another look.

Example usage of media queries

Consider the following stylesheet:

/* example 1 */
object {
	margin: 0 0 10px 10px;
	float: right;
}
@media all and (max-width: 500px) {
	object {
		margin: 10px auto;
		float: none;
		display: block;
	}
}

This is a typical usage of media queries. For wide enough viewports, the object image is floated right, with text surrounding it from the left and below. The moderate margin ensures that the text does not flow too close to the image. For smaller viewports, the container of both the image and the text becomes too narrow to hold both the image and the text on the same line, since there is room for just a few words to the left of the image. The applied media query enables the page author to renounce the float for small enough viewports, in this case smaller than 500px in width. The object is no longer floated; it is now assigned a block display and centered within the containing block, with a new set of vertical margins comfortably separating it from the preceding and following text, presumably contained within paragraphs, although not necessarily.

Is this media query safe to use? Let's see. Are there any graphical user agents that will apply the rules inside the media query regardless of viewport width? The answer is yes: Netfront 3.2-, ICEbrowser, Escape, WebTV/MSNTV, and Openwave. Do you care? Should you care? Personally we do not like providing crutches to help any browser, but ultimately, the decision is yours - a bit of testing is in order to make sure it looks ok cross browser. The most important question that arises in this context is: "will IE misapply the media queries?" The answer is no: IE5 and later will simply ignore a simple media query as a whole, and whatever set of rules is contained therein, which is safe. As we shall see next, the problem arises when using mixed media queries.

Problematic usage of media queries

The keyword here is 'simple'. Before we proceed further, let's simplify the rules subject to a media query in terms of ambient lights:

/* example 2 */
div {
	background: lime;
}
@media all and (min-width: 300px) {
	div {
		background: blue;
	}
}

In this simplistic example, most user agents will color the box green; only the smart user agents that support media queries apply the query and color the box blue. As of this writing, there are only two browsers that should do the latter: Opera 7+ and Safari 3.0. If you see blue in any other browser, that browser has a broken parser.

The aforequoted example is safe, because all major browsers that do not understand media queries drop the entire rule, and so you will see green. This is because the media rule is simple, and contains only a media query. Consider however the following alteration:

/* example 3 */
div {
	background: lime;
}
@media screen, all and (min-width: 300px) {
	div {
		background: blue;
	}
}

Now it is no longer the case that IE does not apply the contents of the query. It now doesn't understand the second part (all and,) so it ignores that, and happily applies the contents of the query, since to IE, the query looks as follows:

@media screen, pantyhose {
	div {
		background: blue;
	}
}

Pantyhose is not a known media to IE, hence it drops the media, and ultimately, sees the following:

@media screen {
	div {
		background: blue;
	}
}

This is equivalent to not using the media query at all. Consider the next example:

/* example 4 */
div {
	background: lime;
}
@media handheld, screen and (max-width: 300px) {
	div {
		background: blue;
	}
}

Again, the query will be applied by Opera 7+ and Safari 3.0. Browsers that do not support media queries but correctly handle unknown constructs (such as Firefox and Safari 1 and 2) will ignore the query. IE however drops only what it does not understand, and sees this:

div {
	background: lime;
}
@media handheld, pantyhose {
	div {
		background: blue;
	}
}

Since it does not support handheld media, it ultimately sees this:

div {
	background: lime;
}
@media wonderbra, pantyhose {
	div {
		background: blue;
	}
}

it does not know what to do with any of those media types, so it drops the entire block, and the background comes out lime.

In summary, the only opportunity to get into trouble is to mix unconditional media rules with media queries, as shown in example 3 above:

/* example 3 */
div {
	background: lime;
}
@media screen, all and (min-width: 300px) {
	div {
		background: blue;
	}
}

But then, what exactly is this doing? It is overriding itself, since within the screen media, the latter condition is a subset of the former. It may look as a convenient way of handling "normal browsers and any user agents that are wide enough", but in fact, it isn't.

Solution

The solution is simple:

  1. If you want to conditionally apply styles depending on viewport dimensions, use media queries rather than handheld/tv media
  2. If you do not want IE to misapply your styles, do not mix media queries with unconditional media rules within the same block
  3. A corollary of point 2: use media queries only for overrides on an as-needed basis
  4. Use the all keyword in queries, if possible

If you observe these guidelines, all but the most broken browsers will parse your stylesheet as intended, with no side-effects, including IE. The following example illustrates the safe usage of media queries:

/* example 5 */
div {/*rule 1*/}
@media projection {
	div {/*rule 2*/}
}
@media all and (max-width: 800px) {
	div {/*rule 3*/}
}
@media all and (max-width: 500px) {
	div {/*rule 4*/}
}
@media all and (max-width: 350px) {
	div {/*rule 5*/}
}
@media projection and (min-width: 1281px) and (max-width: 1600px) {
	div {/*rule 6*/}
}
@media projection and (min-width: 1601px) {
	div {/*rule 7*/}
}

IE, Safari 2-, Konqueror and Gecko browsers will apply only the first rule. Opera is capable of applying everything, since it understands projection media. Safari 3.0 is capable of applying rules 1,3,4,5 since it does not understand projection media, and ignores what it does not understand. We're saying capable, because what is ultimately applied depends on viewport width.

User agents with FUBAR parsers

Some user agents are only partially CSS-capable, which due to parser errors, apply rules inside media queries regardless of how the latter are constructed. As mentioned above, Netfront 3.2-, ICEbrowser, Escape, Openwave, and WebTV/MSNTV will apply rules in media queries in all circumstances. If for some reason you must bend over and cater to those particular user agents (note that Netfront 3.3 and later contains a bugfix for this issue), then you will probably have to resort to so-called CSS-hackery. Good luck.

Staying safe

As already mentioned, as long as you do not mix regular unconditional media rules with media queries in the same block, IE, Gecko-based browsers, KHTML-based browsers, older versions of Safari, iCab, Clue, Omniweb, and older Netscape browsers will ignore the media query in its entirety, as they should. Opera and Safari 3+ will apply the query, as they should. Any browsers with future support for media queries will ultimately pick up the queries as they add support for this technology.

This article is licensed under a Creative Commons Attribution, Non Commercial - Share Alike 2.5 license.

Comments

The forum archive of this article is still available on My Opera.

No new comments accepted.