Media Queries Level 4

Group: csswg
Shortname: mediaqueries
Level: 4
Status: ED
Work Status: Exploring
ED: http://dev.w3.org/csswg/mediaqueries4/
TR: http://www.w3.org/TR/mediaqueries-4/
Editor: Florian Rivoal, Invited Expert, florian@rivoal.net, http://florian.rivoal.net
Editor: Tab Atkins Jr., Google, http://xanthir.com/contact/
Former Editor: Håkon Wium Lie, Opera, howcome@opera.com
Former Editor: Tantek Çelik, Mozilla, tantek@cs.standard.edu
Former Editor: Daniel Glazman, Disruptive Innovations, daniel@glazman.org
Former Editor: Anne van Kesteren, Mozilla, annevk@annevk.nl
Abstract: Media Queries allow authors to test and query values or features of the user agent or display device, independent of the document being rendered.  They are used in the CSS @media rule to conditionally apply styles to a document, and in various other contexts and languages, such as HTML and Javascript.
Abstract:
Abstract: Media Queries Level 4 describes the mechanism and syntax of media queries, media types, and media features. It extends and supersedes the features defined in Media Queries Level 3.
Ignored Terms: min-resolution, max-resolution, none, view-mode, mediaText, DOMString
Link Defaults: css-break-3 (property) break-inside

Introduction

This section is not normative. HTML4 [[HTML401]] defined a mechanism to support media-dependent style sheets, tailored for different media types. For example, a document may use different style sheets for screen and for print. In HTML, this can be written as:
			<link rel="stylesheet" type="text/css" media="screen" href="style.css">
			<link rel="stylesheet" type="text/css" media="print" href="print.css">
		
CSS adapted and extended this functionality with its ''@media'' and ''@import'' rules, adding the ability to query the value of individual features:
Inside a CSS style sheet, one can declare that sections apply to certain media types:
			@media screen {
				* { font-family: sans-serif }
			}
		
Similarly, stylesheets can be conditionally imported based on media queries:
@import "print-styles.css" print;
Media queries can be used with HTML, XHTML, XML [[XMLSTYLE]] and the @import and @media rules of CSS.
Here is the same example written in HTML, XHTML, XML, @import and @media:
			<link media="screen and (color), projection and (color)"
			      rel="stylesheet" href="example.css">

			<link media="screen and (color), projection and (color)"
			      rel="stylesheet" href="example.css" />

			<?xml-stylesheet media="screen and (color), projection and (color)"
			                 rel="stylesheet" href="example.css" ?>

			@import url(example.css) screen and (color), projection and (color);

			@media screen and (color), projection and (color) { … }
		
Note: The [[XMLSTYLE]] specification has not yet been updated to use media queries in the media pseudo-attribute.

Module interactions

This module replaces and extends the Media Queries, Media Type and Media Features defined in [[!CSS21]] sections 7 and in [[!MEDIAQ]].

Values

Value types not defined in this specification, such as <>, <> or <>, are defined in [[!CSS3VAL]]. Other CSS modules may expand the definitions of these value types. This specification also introduces some new value types. The <ratio> value type is a positive (not zero or negative) <> followed by optional whitespace, followed by a solidus ('/'), followed by optional whitespace, followed by a positive <>. <>s can be ordered or compared by transforming them into the number obtained by dividing their first <> by their second <>. The <mq-boolean> value type is an <> with the value ''0'' or ''1''. Any other integer value is invalid. Note that ''-0'' is always equivalent to ''0'' in CSS, and so is also accepted as a valid <> value.

Units

The units used in media queries are the same as in other parts of CSS, as defined in [[!CSS3VAL]]. For example, the pixel unit represents CSS pixels and not physical pixels. Relative units in media queries are based on the initial value, which means that units are never based on results of declarations. For example, in HTML, the ''em'' unit is relative to the initial value of 'font-size', defined by the user agent or the user's preferences, not any styling on the page.

Media Queries

A media query is a method of testing certain aspects of the user agent or device that the document is being displayed in. Media queries are (almost) always independent of the contents of the document, its styling, or any other internal aspect; they're only dependent on “external” information unless another feature explicitly specifies that it affects the resolution of Media Queries, such as the ''@viewport'' rule. The syntax of a media query consists of an optional media query modifier, an optional media type, and zero or more media features:
	Or:
		N: media condition
		And:
			Or: 1
				T: only
				S:
				T: not
			N: media type
			Opt:
				And:
					T: and
					N: media condition
	
A media query is a logical expression that is either true or false. A media query is true if: * the media type, if specified, matches the media type of the device where the user agent is running, and * the media condition is true. Statements regarding media queries in this section assume the syntax section is followed. Media queries that do not conform to the syntax are discussed in [[#error-handling]]. I.e. the syntax takes precedence over requirements in this section.
Here is a simple example written in HTML:
<link rel="stylesheet" media="screen and (color)" href="example.css" />
This example expresses that a certain style sheet (example.css) applies to devices of a certain media type (''screen'') with certain feature (it must be a color screen). Here is the same media query written in an @import-rule in CSS:
@import url(example.css) screen and (color);
User agents must re-evaluate media queries in response to changes in the user environment that they're aware of, for example if the device is tiled from landscape to portrait orientation, and change the behavior of any constructs dependent on those media queries accordingly. Unless another feature explicitly specifies that it affects the resolution of Media Queries, it is never necessary to apply a style sheet in order to evaluate expressions. Note: CSS Device Adaptation [[CSS-DEVICE-ADAPT]]] defines how ''@viewport'' rules interact with Media Queries.

Combining Media Queries

Several media queries can be combined into a comma-separated media query list.
	Star:
		N: media query
		T: ,
	
A media query list is true if any of its component media queries are true, and false only if all of its component media queries are false.
For example, the following media query list is true if either the media type is ''screen'' and it's a color device, or the media type is ''projection'' and it's a color device:
		@media screen and (color), projection and (color) { … }
		
An empty media query list evaluates to true.
For example, these are equivalent:
		@media all { … }
		@media { … }
		

Media Query Modifiers

A media query may optionally be prefixed by a single media query modifier, which is a single keyword which alters the meaning of the following media query.

Negating a Media Query: the ''not'' keyword

An individual media query can have its result negated by prefixing it with the keyword not. If the media query would normally evaluate to true, prefixing it with ''not'' makes it evaluate to false, and vice versa.
For example, the following will apply to everything except color-capable screens. Note that the entire media query is negated, not just the media type.
<link rel="stylesheet" media="not screen and (color)" href="example.css" />

Hiding a Media Query From Legacy User Agents: the ''only'' keyword

The concept of media queries originates from HTML4 [[HTML401]]. That specification only defined media types, but had a forward-compatible syntax that accommodated the addition of future concepts like media features: it would consume the characters of a media query up to the first non-alphanumeric character, and interpret that as a media type, ignoring the rest. For example, the media query ''screen and (color)'' would be truncated to just ''screen''. Unfortunately, this means that legacy user agents using this error-handling behavior will ignore any media features in a media query, even if they're far more important than the media type in the query. This can result in styles accidentally being applied in inappropriate situations. To hide these media queries from legacy user agents, the media query can be prefixed with the keyword only. The ''only'' keyword has no effect on the media query’s result, but will cause the media query to be parsed by legacy user agents as specifying the unknown media type “only”, and thus be ignored.
In this example, the stylesheet specified by the <link> element will not be used by legacy user agents, even if they would normally match the ''screen'' media type.
<link rel="stylesheet" media="only screen and (color)" href="example.css" />
Note: Note that the ''only'' keyword can only be used before a media type. A media query consisting only of media features, or one with another media query modifier like ''not'', will be treated as false by legacy user agents automatically. Note: At the time of publishing this specification, such legacy user agents are extremely rare, and so using the ''only'' modifier is rarely, if ever, necessary.

Media Types

A media type is a broad category of user-agent devices on which a document may be displayed. The original set of media types were defined in HTML4, for the media attribute on <link> elements. Unfortunately, media types have proven insufficient as a way of discriminating between devices with different styling needs. Some categories which were originally quite distinct, such as ''screen'' and ''handheld'', have blended significantly in the years since their invention. Others, such as ''tty'' or ''tv'', expose useful differences from the norm of a full-featured computer monitor, and so are potentially useful to target with different styling, but the definition of media types as mutually exclusive makes it difficult to use them in a reasonable manner; instead, their exclusive aspects are better expressed as media features such as 'grid' or 'scan'. As such, the following media types are defined for use in media queries:
all
Matches all devices.
print
Matches printers, and devices intended to reproduce a printed display, such as a web browser showing a document in “Print Preview”.
screen
Matches all devices that aren't matched by ''print'' or ''speech''.
speech
Matches screenreaders and similar devices that “read out” a page.
In addition, the following deprecated media types are defined. Authors must not use these media types; instead, it is recommended that they select appropriate media features that better represent the aspect of the device that they are attempting to style against. User agents must recognize the following media types as valid, but must make them match nothing.
  • tty
  • tv
  • projection
  • handheld
  • braille
  • embossed
  • aural
Note: It is expected that all of the media types will also be deprecated in time, as appropriate media features are defined which capture their important differences.

Media Features

A media feature is a more fine-grained test than media types, testing a single, specific feature of the user agent or display device. Syntactically, media features resemble CSS properties: they consist of a feature name, a colon, and a value to test for. They may also be written in boolean form as just a feature name, or in range form with a comparison operator.
	T: (
	Choice:
		And:
			N: feature name
			T: :
			N: feature value
		N: feature name
		And:
			N: range form
			C: (see below)
	T: )
	
There are, however, several important differences between properties and media features:
  • Properties are used to give information about how to present a document. Media features are used to describe requirements of the output device.
  • Media features are always wrapped in parentheses and combined with the ''and'' keyword, like ''(color) and (min-width: 600px)'', rather than being separated with semicolons.
  • A media feature may be given with only its name (omitting the colon and value) to evaluate the feature in a boolean context. This is a convenient shorthand for features that have a reasonable value representing 0 or “none”. For example, ''(color)'' is true is the 'color' media feature is non-zero.
  • Media features with “range” type can be written in a range context, which uses standard mathematical comparison operators rather than a colon, or have their feature names prefixed with “min-” or “max-”.
  • Properties sometimes accept complex values, e.g., calculations that involve several other values. Media features only accept single values: one keyword, one number, etc.
If a media feature references a concept which does not exist on the device where the UA is running (for example, speech UAs do not have a concept of "width"), the media feature must always evaluate to false.
The media feature ''device-aspect-ratio'' only applies to visual devices. On an ''speech'' device, expressions involving ''device-aspect-ratio'' will therefore always be false:
			<link media="speech and (device-aspect-ratio: 16/9)"
			      rel="stylesheet" href="example.css">
		

Media Feature Types: “range” and “discrete”

Every media feature defines its “type” as either “range” or “discrete” in its definition table. “Discrete” media features, like 'light-level' or 'scripting', take their values from a set. The values may be keywords or boolean numbers (0 and 1), but the common factor is that there's no intrinsic “order” to them-- none of the values are “less than” or “greater than” each other. “Range” media features like 'width', on the other hand, take their values from a range. Any two values can be compared to see which is lesser and which is greater. The only significant difference between the two types is that “range” media features can be evaluated in a range context and accept “min-” and “max-” prefixes on their name. Doing either of these changes the meaning of the feature-- rather than the media feature being true when the feature exactly matches the given value, it matches when the feature is greater than/less than/equal to the given value.
A (width >= 600px) media feature is true when the viewport's width is ''600px'' or more. On the other hand, ''(width: 600px)'' by itself is only true when the viewport's width is exactly ''600px''. If it's less or greater than ''600px'', it'll be false.

Evaluating Media Features in a Boolean Context

While media features normally have a syntax similar to CSS properties, they can also be written more simply as just the feature name, like ''(color)''. When written like this, the media feature is evaluated in a boolean context. If the feature would be true for any value other than the number ''0'', a dimension with the value ''0'', or the keyword ''none'', the media feature evaluates to true. Otherwise, it evaluates to false.
Some media features are designed to be written like this. For example, 'scripting' is typically written as ''(scripting)'' to test if scripting is enabled, or ''not (scripting)'' to see if it's disabled. It can still be given an explicit value as well, with ''(scripting: enabled)'' equal to ''(scripting)'', and ''(scripting: none)'' equal to ''not (scripting)''.
Some numeric media features, like 'width', are rarely if ever useful to evaluate in a boolean context, as their values are almost always greater than zero. Others, like 'color', have meaningful zero values: ''(color)'' is identical to ''(color > 0)'', indicating that the device is capable of displaying color at all.
Only some of the media features that accept keywords are meaningful in a boolean context. For example, ''(pointer)'' is useful, as 'pointer' has a ''pointer/none'' value to indicate there's no pointing device at all on the device. On the other hand, ''(scan)'' is just always true or always false (depending on whether it applies at all to the device), as there's no value that means “false”.

Evaluating Media Features in a Range Context

Media features with a “range” type can be alternately written in a range context that takes advantage of the fact that their values are ordered, using ordinary mathematical comparison operators:
	T: (
	Choice:
		Seq:
			N: feature name/value
			Choice: 4
				T: =
				T: <
				T: <=
				T: >
				T: >=
			N: feature value/name
		Seq:
			N: value
			Choice:
				T: <
				T: <=
			N: feature name
			Choice:
				T: <
				T: <=
			N: value
		Seq:
			N: value
			Choice:
				T: >
				T: >=
			N: feature name
			Choice:
				T: >
				T: >=
			N: value
	T: )
	
The basic form, consisting of a feature name, a comparison operator, and a value, returns true if the relationship is true.
For example, ''(height > 600px)'' (or ''(600px < height)'') returns true if the viewport height is greater than ''600px''.
The remaining forms, with the feature name nested between two value comparisons, returns true if both comparisons are true.
For example, ''(400px < width < 1000px)'' returns true if the viewport width is between ''400px'' and ''1000px'' (but not equal to either).

Using “min-” and “max-” Prefixes On Range Features

Rather than evaluating a “range” type media feature in a range context, as described above, the feature may be written as a normal media feature, but with a “min-” or “max-” prefix on the feature name. This is equivalent to evaluating the feature in a range context, as follows:
  • Using a “min-” prefix on a feature name is equivalent to using the “>=” operator. For example, ''(min-height: 600px)'' is equivalent to (height >= 600px).
  • Using a “max-” prefix on a feature name is equivalent to using the “<=” operator. For example, ''(max-width: 40em)'' is equivalent to (width <= 40em).
“Discrete” type properties do not accept “min-” or “max-” prefixes. Adding such a prefix to a “discrete” type media feature simply results in an unknown feature name.
For example, ''(min-grid: 1)'' is invalid, because 'grid' is a “discrete” media feature, and so doesn't accept the prefixes. (Even though the 'grid' media feature appears to be numeric, as it accepts the values ''0'' and ''1''.)
Attempting to evaluate a min/max prefixed media feature in a boolean context is invalid and a syntax error. Combining Media Features {#media-conditions} -------------------------------------------- Multiple media features can be combined together into a media condition using full boolean algebra (not, and, or). Issue: TODO: Fill this in.

Syntax

Informal descriptions of the media query syntax appear in the prose and railroad diagrams in previous sections. The formal media query syntax is described in this section, with the rule/property grammar syntax defined in [[!CSS3SYN]] and [[!CSS3VAL]]. To parse a <media-query-list> production, parse a comma-separated list of component values, then parse each entry in the returned list as a <>. Its value is the list of <>s so produced. Note: This explicit definition of <> parsing is necessary to make the error-recovery behavior of media query lists well-defined. Note: This definition of <> parsing intentionally accepts an empty list.
	<media-query> = <>
	             | [ not | only ]? <> [ and <> ]?
	<media-type> = <>

	<media-condition> = <> | <> | <> | <>
	<media-condition-without-or> = <> | <> | <>
	<media-not> = not <>
	<media-and> = <> [ and <> ]+
	<media-or> = <> [ or <> ]+
	<media-in-parens> = ( <> ) | <> | <>

	<media-feature> = ( [ <> | <> | <> ] )
	<mf-plain> = <> : <>
	<mf-boolean> = <>
	<mf-range> = <> [ '<' | '>' ]? '='? <>
	           | <> [ '<' | '>' ]? '='? <>
	           | <> '<' '='? <> '<' '='? <>
	           | <> '>' '='? <> '>' '='? <>
	<mf-name> = <>
	<mf-value> = <> | <> | <> | <>

	<general-enclosed> = [ <> <> ) ] | ( <> <> )
	
The <> production does not include the keywords ''only'', ''not'', ''and'', and ''or''. A <dimension> is a dimension. An <ident> is an identifier. No whitespace is allowed between the "<" or ">" <>s and the following "=" <>, if it's present. Whitespace must be present between a ')' character and a ''not'', ''and'', or ''or'' keyword, and between a ''not'', ''and'', or ''or'' keyword and a '(' character. When parsing the <> production, the <> branch must only be chosen if the input does not match either of the preceding branches. <> exists to allow for future expansion of the grammar in a reasonably compatible way. In addition to conforming to the syntax, each media query needs to use media types and media features according to their respective specification in order to be considered conforming.
Only the first media query is conforming in the example below because the "example" media type does not exist.
		@media all { body { background:lime } }
		@media example { body { background:red } }
		
Each of the major terms of <> or <> is associated with a boolean result, as follows:
<>
<>
<>
The result is the result of the child term.
<>
The result is the negation of the <> term. The negation of unknown is unknown.
<>
The result is true if all of the <> child terms are true, false if at least one of the <> child terms are false, and unknown otherwise.
<>
The result is false if all of the <> child terms are false, true if at least one of the <> child terms are true, and unknown otherwise.
<>
The result is unknown. Authors must not use <> in their stylesheets. It exists only for future-compatibility, so that new syntax additions do not invalidate too much of a <> in older user agents.
<>
The result is the result of evaluating the specified media feature.
If the result of any of the above productions is used in any context that expects a two-valued boolean, "unknown" must be converted to "false". Note: This means that, for example, when a media query is used in a ''@media'' rule, if it resolves to "unknown" it's treated as "false" and fails to match.
Media Queries use a three-value logic where terms can be "true", "false", or "unknown". Specifically, it uses the Kleene 3-valued logic. In this logic, "unknown" means "either true or false, but we're not sure which yet". In general, an unknown value showing up in a formula will cause the formula to be unknown as well, as substituting "true" for the unknown will give the formula a different result than substituting "false". The only way to eliminate an unknown value is to use it in a formula that will give the same result whether the unknown is replaced with a true or false value. This occurs when you have "false AND unknown" (evaluates to false regardless) and "true OR unknown" (evaluates to true regardless). This logic was adopted because <> needs to be assigned a truth value. In standard boolean logic, the only reasonable value is "false", but this means that ''not unknown(function)'' is true, which can be confusing and unwanted. Kleen's 3-valued logic ensures that unknown things will prevent a media query from matching, unless their value is irrelevant to the final result.

Error Handling

A media query that does not match the grammar in the previous section must be replaced by ''not all'' during parsing. Note: Note that a grammar mismatch does not wipe out an entire media query list, just the problematic media query. The parsing behavior defined above automatically recovers at the next top-level comma.
			@media (example, all,), speech { /* only applicable to speech devices */ }
			@media &test, speech           { /* only applicable to speech devices */ }
		
Both of the above media query lists are turned into ''not all, speech'' during parsing, which has the same truth value as just ''speech''. Note that error-recovery only happens at the top-level of a media query; anything inside of an invalid parenthesized block will just get turned into ''not all'' as a group. For example:
			@media (example, speech { /* rules for speech devices */ }
		
Because the parenthesized block is unclosed, it will contain the entire rest of the stylesheet from that point (unless it happens to encounter an unmatched ")" character somewhere in the stylesheet), and turn the entire thing into a ''not all'' media query.
An unknown <> must be treated as not matching.
For example, the media query ''unknown'' is false, as ''unknown'' is an unknown media type. But ''not unknown'' is true, as the ''not'' negates the false media type.
Remember that some keywords aren't allowed as <>s and cause parsing to fail entirely: the media query ''or and (color)'' is turned into ''not all'' during parsing, rather than just treating the ''or'' as an unknown media type.
An unknown <> or <>, or disallowed <>, results in the value "unknown". A <> whose value is "unknown" must be replaced with ''not all''.
<link media="screen and (max-weight: 3kg) and (color), (color)"
		      rel="stylesheet" href="example.css" />
As ''max-weight'' is an unknown media feature, this media query list is turned into ''not all, (color)'', which is equivalent to just ''(color)''.
@media (min-orientation:portrait) { … }
The 'orientation' feature does not accept prefixes, so this is considered an unknown media feature, and turned into ''not all''.
The media query ''(color:20example)'' specifies an unknown value for the 'color' media feature and is therefore turned into ''not all''.
This media query is turned into ''not all'' because negative lengths are not allowed for the 'width' media feature:
@media (min-width: -100px) { … }
Note that media queries are also subject to the parsing rules of the host language. For example, take the following CSS snippet:
 @media test;,all { body { background:lime } }
The media query ''test;,all'' is, parsed by itself, equivalent to ''not all, all'', which is always true. However, CSS's parsing rules cause the ''@media'' rule, and thus the media query, to end at the semicolon. The remainder of the text is treated as a style rule with an invalid selector and contents.

Screen/Device Dimensions Media Features

width

	Name: width
	Value: <>
	For: @media
	Type: range
	
The '@media/width' media feature describes the width of the targeted display area of the output device. For continuous media, this is the width of the viewport (as described by CSS2, section 9.1.1 [[!CSS21]]) including the size of a rendered scroll bar (if any). For paged media, this is the width of the page box (as described by CSS2, section 13.2 [[!CSS21]]). A specified <> cannot be negative.
For example, this media query expresses that the style sheet is usable on printed output wider than 25cm:
<link rel="stylesheet" media="print and (min-width: 25cm)" href="http://…" />
This media query expresses that the style sheet is usable on devices with viewport (the part of the screen/paper where the document is rendered) widths between 400 and 700 pixels:
@media (400px <= min-width <= 700px) { … }
This media query expresses that style sheet is usable if the width of the viewport is greater than 20em.
@media (min-width: 20em) { … }
The ''em'' value is relative to the initial value of 'font-size'.

height

	Name: height
	Value: <>
	For: @media
	Type: range
	
The 'height' media feature describes the height of the targeted display area of the output device. For continuous media, this is the height of the viewport including the size of a rendered scroll bar (if any). For paged media, this is the height of the page box. A specified <> cannot be negative.

aspect-ratio

	Name: aspect-ratio
	Value: <>
	For: @media
	Type: range
	
The 'aspect-ratio' media feature is defined as the ratio of the value of the 'width' media feature to the value of the 'height' media feature.

orientation

	Name: orientation
	Value: portrait | landscape
	For: @media
	Type: discrete
	
portrait
The 'orientation' media feature is ''portrait'' when the value of the 'height' media feature is greater than or equal to the value of the 'width' media feature.
landscape
Otherwise 'orientation' is ''landscape''.
The following media query tests for “portrait” orientation, like a phone held upright.
@media (orientation:portrait) { … }

Display Quality Media Features

resolution

	Name: resolution
	Value: <>
	For: @media
	Type: range
	
The 'resolution' media feature describes the resolution of the output device, i.e. the density of the pixels, taking into account the page zoom but assuming a pinch zoom of 1.0. When querying media with non-square pixels, 'resolution' queries the density in the vertical dimension.
<> does not refer to the number of device pixels per physical length unit, but the number of device pixels per css pixels. This mapping is done by the user agent, so it is always known to the user agent. If the user agent either has no knowledge of the geometry of physical pixels, or knows about the geometry physical pixels and they are (close enough to) square, it would not map a different number of device pixels per css pixels along each axis, and the would therefore be no difference between the vertical and horizontal resolution. Otherwise, if the UA choses to map a different number along each axis, this would be to respond to physical pixels not being square either. How the UA comes to this knowledge is out of scope, but having enough information to take this decision, it can invert the mapping should the device be rotated 90 degrees.
For printers, this corresponds to the screening resolution (the resolution for printing dots of arbitrary color). Printers might have a different resolution for grayscale printing.
This media query simply detects “high-resolution” screens (those with a hardware pixel to CSS ''px'' ratio of at least 2):
@media (resolution >= 2dppx)
For example, this media query expresses that a style sheet is usable on devices with resolution greater than 300 dots per CSS ''in'':
@media print and (min-resolution: 300dpi) { … }
This media query is equivalent, but uses the CSS ''cm'' unit:
@media print and (min-resolution: 118dpcm) { … }

scan

	Name: scan
	Value: interlace | progressive
	For: @media
	Type: discrete
	
The 'scan' media feature describes the scanning process of some output devices.
interlace
CRT and some types of plasma TV screens used “interlaced” rendering, where video frames alternated between specifying only the “even” lines on the screen and only the “odd” lines, exploiting various automatic mental image-correction abilities to produce smooth motion. This allowed them to simulate a higher FPS broadcast at half the bandwidth cost. When displaying on interlaced screens, authors should avoid very fast movement across the screen to avoid “combing”, and should ensure that details on the screen are wider than ''1px'' to avoid “twitter”.
progressive
A screen using “progressive” rendering displays each screen fully, and needs no special treatment. Most modern screens, and all computer screens, use progressive rendering.
For example, the “feet” of letters in serif fonts are very small features that can provoke “twitter” on interlaced devices. The '@media/scan' media feature can be used to detect this, and use an alternative font with less chance of “twitter”:
@media (scan: interlace) { body { font-family: sans-serif; } }

grid

	Name: grid
	Value: <>
	For: @media
	Type: discrete
	
The 'grid' media feature is used to query whether the output device is grid or bitmap. If the output device is grid-based (e.g., a "tty" terminal, or a phone display with only one fixed font), the value will be 1. Otherwise, the value will be 0.
Here is an example that detects a narrow console screen:
		@media (grid) and (max-width: 15em) { … }
		

update-frequency

	Name: update-frequency
	Value: none | slow | normal
	For: @media
	Type: discrete
	
The 'update-frequency' media feature is used to query the ability of the output device to modify the apearance of content once it has been rendered. It accepts the following values:
none
Once it has been rendered, the layout can no longer be updated. Example: documents printed on paper.
slow
The layout may change dynamically according to the usual rules of CSS, but the output device is not able to render or display changes quickly enough for them to be percieved as a smooth animation. Example: E-ink screens or severely under-powered devices.
normal
The layout may change dynamically according to the usual rules of CSS, and the output device is not unusually constrained in speed, so regularly-updating things like CSS Animations can be used. Example: computer screens.
For example, if a page styles its links to only add underlines on hover, it may want to always display underlines when printed:
		a { text-decoration: none; }
		a:hover, a:focus { text-decoration: underline; }
		@media (update-frequency: none) {
			a { text-decoration: underline; }
		}
		

overflow-block

	Name: overflow-block
	Value: none | scroll | optional-paged | paged
	For: @media
	Type: discrete
	
The 'overflow-block' media feature describes the behavior of the device when content overflows the initial containing block in the block axis.
none
There is no affordance for overflow in the block axis; any overflowing content is simply not displayed. Examples: billboards
scroll
Overflowing content in the block axis is exposed by allowing users to scroll to it. Examples: computer screens
optional-paged
Overflowing content in the block axis is exposed by allowing users to scroll to it, but page breaks can be manually triggered (such as via 'break-inside'/etc) to cause the following content to display on the following page. Examples: slideshows
paged
Content is broken up into discrete pages; content that overflows one page in the block axis is displayed on the following page. Examples: printers, ebook readers

overflow-inline

	Name: overflow-inline
	Value: none | scroll
	For: @media
	Type: discrete
	
The 'overflow-inline' media feature describes the behavior of the device when content overflows the initial containing block in the inline axis.
none
There is no affordance for overflow in the inline axis; any overflowing content is simply not displayed.
scroll
Overflowing content in the inline axis is exposed by allowing users to scroll to it.
Note: There are no known implementations of paged overflow of inline-overflowing content, and the very concept doesn't seem to make much sense, so there is intentionally no ''paged'' value for '@media/overflow-inline'.

Color Media Features

color

	Name: color
	Value: <>
	For: @media
	Type: range
	
The 'color' media feature describes the number of bits per color component of the output device. If the device is not a color device, the value is zero. A specified <> cannot be negative.
For example, these two media queries express that a style sheet applies to all color devices:
		@media (color) { … }
		@media (min-color: 1) { … }
		
This media query expresses that a style sheet applies to color devices with at least 8 bits per color component:
@media (color >= 8) { … }
If different color components are represented by different number of bits, the smallest number is used.
For instance, if an 8-bit color system represents the red component with 3 bits, the green component with 3 bits, and the blue component with 2 bits, the '@media/color' media feature will have a value of 2.
In a device with indexed colors, the minimum number of bits per color component in the lookup table is used. Note: The described functionality is only able to describe color capabilities at a superficial level. If further functionality is required, RFC2531 [[RFC2531]] provides more specific media features which may be supported at a later stage.

color-index

	Name: color-index
	Value: <>
	For: @media
	Type: range
	
The 'color-index' media feature describes the number of entries in the color lookup table of the output device. If the device does not use a color lookup table, the value is zero. A specified <> cannot be negative.
For example, here are two ways to express that a style sheet applies to all color index devices:
		@media (color-index) { … }
		@media (color-index >= 1) { … }
		
This media query expresses that a style sheet applies to a color index device with 256 or more entries:
		<?xml-stylesheet media="(min-color-index: 256)"
			href="http://www.example.com/…" ?>
		

monochrome

	Name: monochrome
	Value: <>
	For: @media
	Type: range
	
The 'monochrome' media feature describes the number of bits per pixel in a monochrome frame buffer. If the device is not a monochrome device, the output device value will be 0. A specified <> cannot be negative.
For example, this is how to express that a style sheet applies to all monochrome devices:
@media (monochrome) { … }
Express that a style sheet applies to monochrome devices with more than 2 bits per pixels:
@media (monochrome >= 2) { … }
Express that there is one style sheet for color pages and another for monochrome:
		<link rel="stylesheet" media="print and (color)" href="http://…" />
		<link rel="stylesheet" media="print and (monochrome)" href="http://…" />
		

inverted-colors

	Name: inverted-colors
	Value: none | inverted
	For: @media
	Type: discrete
	
The 'inverted-colors' media feature indicates whether the content is displayed normally, or whether colors have been inverted.

This is an indication that the user agent or underlying operating system has forcibly inverted all colors, not a request to do so. This is sometimes provided as a simple accessibility feature, allowing users to switch between light-on-dark and dark-on-light text. However, this has unpleasant side effects, such as inverting pictures, or turning shadows into highlights, which reduce the readability of the content.

none
Colors are displayed normally.
inverted
All pixels within the displayed area have been inverted.
For example, a user frequently using his operating system's ability to invert the screens color may want to add the following to his user style sheet, to limit the undesirable side effects of the inversion.
@media (inverted-colors) {
			img { filter: invert(100%); }
			* { text-shadow: none; background-shadow: none; }
		}
		

Interaction Media Features

pointer

	Name: pointer
	Value: none | coarse | fine
	For: @media
	Type: discrete
	
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. (To query the capabilities of any available input mechanism, see the 'any-pointer' media feature.)
none
The primary input mechanism of the device does not include a pointing device.
coarse
The primary input mechanism of the device includes a pointing device of limited accuracy.
fine
The primary input mechanism of the device includes an accurate pointing device.
Both ''coarse'' and ''fine'' indicate the presence of a pointing device, but differ in accuracy. A pointing device with which it would be difficult or impossible to reliably pick one of several small adjacent targets at a zoom factor of 1 would qualify as ''coarse''. Changing the zoom level does not affect the value of this media feature. Note: As the UA may provide the user with the ability to zoom, or as secondary pointing devices may have a different accuracy, the user may be able to perform accurate clicks even if the value of this media feature is ''coarse''. This media feature does not indicate that the user will never be able to click accurately, only that it is inconvenient for them to do so. Authors are expected to react to a value of ''coarse'' by designing pages that do not rely on accurate clicking to be operated.
Typical examples of devices matching combinations of 'pointer' and 'hover':
pointer
coarse fine
hover none smartphones, touch screens stylus-based screens (Cintiq, Wacom, etc)
hover Nintendo Wii controller, Kinect mouse, touch pad
For accessibility reasons, even on devices whose pointing device can be described as ''fine'', the UA may give a value of ''coarse'' or ''pointer/none'' to this media query, to indicate that the user has difficulties manipulating the pointing device accurately or at all.
		/* Make radio buttons and check boxes larger if we have an inaccurate pointing device */
		@media (pointer:coarse) {
			input[type="checkbox"], input[type="radio"] {
				min-width:30px;
				min-height:40px;
				background:transparent;
			}
		}
		

hover

	Name: hover
	Value: none | on-demand | hover
	For: @media
	Type: discrete
	
The 'hover' media feature is used to query the user's ability to hover over elements on the page. If a device has multiple input mechanisms, the 'hover' media feature must reflect the characteristics of the “primary” input mechanism, as determined by the user agent. (To query the capabilities of any available input mechanism, see the 'any-hover' media feature.)
none
Indicates that the primary pointing system can't hover, or there is no pointing system.
on-demand
Indicates that the primary pointing system can hover, but it requires a significant action on the user's part. For example, some devices can't normally hover, but will activate hover on a “long press”.
hover
Indicates that the primary pointing system can easily hover over parts of the page.
For example, on a touch screen device that can also be controlled by an optional mouse, the 'hover' media feature should match ''hover/none'', as the primary interaction mode (touching the screen) can't hover. Authors should therefore be careful not to assume that the ':hover' pseudo class will never match on device where 'hover:none' is true, but they should design layouts that do not depend on hovering to be fully usable.
For accessibility reasons, even on devices that do support hovering, the UA may give a value of ''hover: none'' to this media query, to opt into layouts that work well without hovering.
		/* Only use a hover-activated drop down menu on devices that can conveniently hover. */
		@media (hover) {
			.menu > li        {display:inline-block;}
			.menu ul          {display:none; position:absolute;}
			.menu li:hover ul {display:block; list-style:none; padding:0;}
			/* ... */
		}
		

any-pointer and any-hover

	Name: any-pointer
	Value: none | coarse | fine
	For: @media
	Type: discrete
	
	Name: any-hover
	Value: none | on-demand | hover
	For: @media
	Type: discrete
	
The 'any-pointer' and 'any-hover' media features are identical to the 'pointer' and 'hover' media features, but they correspond to the union of capabilities of all the pointing devices available to the user. More than one of their values can match, if different pointing devices have different characteristics.
These two media features are best suited to provide refinements over 'hover' and 'pointer', and it is rarely appropriate to use them without having first designed the main style and interaction mode of the page to suit the primary input mechanism. Once that has been taken into account, 'any-hover' and 'any-pointer' can be used to see if some extra conveniences or non essential controls can be offered to users who have additional ways to interact. Designing a page that relies on hovering or accurate pointing only because 'any-hover' or 'any-pointer' indicate that an input mechanism with these capabilities is available, is likely to result in a poor experience.
A number of smart TVs come with a way to control an on-screen cursor, but it is often fairly basic controller which is difficult to operate accurately. A browser in such a smart TV would have ''coarse'' as the value of both 'pointer' and 'any-pointer', allowing authors to provide a layout with large and easy to reach click targets. The user may also have paired a Bluetooth mouse with the TV, and occasionally use it for extra convenience, but such the mouse is not the main way the TV is operated. 'pointer' still matches ''coarse'', while 'any-pointer' now both matches ''coarse'' and ''fine''. Switching to small click targets based on the fact that ''(any-pointer: fine)'' is now true would not be appropriate. It would not only surprise the user by providing an experience out of line with what they expect on a TV, but may also be quite inconvenient: the mouse, not being the primary way to control the TV, may be out of reach, hidden under one of the cushions on the sofa... By contrast, consider scrolling on the same TV. Scrollbars are difficult to manipulate without an accurate pointing device. Having prepared an alternative way to indicate that there is more content to be seen based on ''(pointer: coarse)'' being true, an author may want to still show the scrollbars in addition if ''(any-pointer: fine)'' is true, or to hide them altogether to reduce visual clutter if ''(any-pointer: fine)'' is false.

Environment Media Features

light-level

	Name: light-level
	Value: dim | normal | washed
	For: @media
	Type: discrete
	
The 'light-level' media feature is used to query about the ambient light-level in which the device is used, to allow the author to adjust style of the document in response. The following values are valid:
dim
The device is used in a dim environment, where excessive contrast and brightness would be distracting or uncomfortable to the reader. For example: night time, or a dimly illuminated indoor environment.
normal
The device is used in a environment with a light level in the ideal range for the screen, and which does not necessitate any particular adjustment.
washed
The device is used in an exceptionally bright environment, causing the screen to be washed out and difficult to read. For example: bright daylight.
User agents should set the thresholds between the 3 levels in a way that takes into account the characteristics of the device.
Even though it is expected that User Agents will adjust the value of this media feature based on ambient light sensors, this specification intentionally refrains from defining the 3 levels in terms of a measurement in lux, for several reasons:
  • Devices equipped with a light sensor usually adjust the brightness of the screen automatically. Depending on the level of adjustment, the thresholds for needing a low contrast or hight contrast content may vary.
  • Different screen technologies wash out at very different ambient light levels; e-ink displays remain readable in bright daylight, while liquid crystal displays do not.
  • Many embedded light sensors are inaccurately calibrated, making it difficult to establish useful thresholds valid across devices.
For accessibility purposes, user agents may offer manual controls allowing the user to switch between the 3 levels of independently of the ambient light level, as high contrast or low contrast styles may be more suitable for users with visual disabilities.

Using this media feature for accessibility purposes overlaps a lot with the high-contrast media feature proposed by Microsoft. Can we adjust this so that it covers all use cases for both, or somehow modify them to work in an orthogonal, rather than overlapping, fashion?

		@media (light-level: normal) {
			p { background: url("texture.jpg"); color: #333 }
		}
		@media (light-level: dim) {
			p { background: #222; color: #ccc }
		}
		@media (light-level: washed) {
			p { background: white; color: black; font-size: 2em; }
		}
		

Scripting Media Features

scripting

	Name: scripting
	Value: none | initial-only | enabled
	For: @media
	Type: discrete
	
The 'scripting' media feature is used to query whether scripting languages, such as JavaScript, are supported on the current document.
enabled
Indicates that the user agent supports scripting of the page and that support is active for the current document.
initial-only
Indicates that scripting is enabled during the initial page load, but is not supported afterwards. Examples are printed pages, or pre-rendering network proxies that render a page on a server and send a nearly-static version of the page to the user.
none
Indicates that the user agent will not run scripts for this document; either it doesn't support a scripting language, or the support isn't active for the current document.
Some user agents have the ability to turn off scripting support on a per script basis or per domain basis, allowing some, but not all, scripts to run in a particular document. The 'scripting' media feature does not allow fine grained detection of which script is allowed to run. In this scenario, the value of the 'scripting' media feature should be ''scripting/enabled'' if scripts originating on the same domain as the document are allowed to run, and ''scripting/none'' otherwise. Note: A future level of CSS may extend this media feature to allow fine-grained detection of which script is allowed to run.

Custom Media Queries

When designing documents that use media queries, the same media query may be used in multiple places, such as to qualify multiple ''@import'' statements. Repeating the same media query multiple times is an editing hazard; an author making a change must edit every copy in the same way, or suffer from difficult-to-find bugs in their CSS. To help ameliorate this, this specification defines a method of defining custom media queries, which are simply-named aliases for longer and more complex media queries. In this way, a media query used in multiple places can instead be assigned to a custom media query, which can be used everywhere, and editing the media query requires touching only one line of code. A custom media query is defined with the ''@custom-media'' rule:
		@custom-media = @custom-media <> [ <> | true | false ] ;
	
The <> can then be used in a media feature. It must be used in a boolean context; using them in a normal or range context is a syntax error. If a <> is given, the custom media query evaluates to true if the <> it represents evaluates to true, and false otherwise. If true or false is given, the custom media query evaluates to true or false, respectively. A ''@custom-media'' rule can refer to other custom media queries. However, loops are forbidden, and a custom media query must not be defined in terms of itself or of another custom media query that directly or indirectly refers to it. Any such attempt of defining a custom media query with a circular dependency must cause all the custom media queries in the loop to fail to be defined. Note: For error handling purposes, an undefined media feature is different from a media feature that evaluates to false. See Error Handling for details.
For example, if a responsive site uses a particular breakpoint in several places, it can alias that with a reasonable name:
			@custom-media --narrow-window (max-width: 30em);

			@media (--narrow-window) {
				/* narrow window styles */
			}
			@media (--narrow-window) and (script) {
				/* special styles for when script is allowed */
			}
			/* etc */
		

Script-based Custom Media Queries

Define a map of names to values for JS. Values can be either a MediaQueryList object or a boolean, in which case it's treated identically to the above, or can be a number or a string, in which case it's treated like a normal MQ, and can use the normal or range context syntax. Like:
			<script>
			CSS.customMedia.set('--foo', 5);
			</script>
			<style>
			@media (_foo: 5) { ... }
			@media (_foo < 10) { ... }
			</style>
		

CSSOM

The CSSRule interface is extended as follows:
	partial interface CSSRule {
		const unsigned short CUSTOM_MEDIA_RULE = 17;
	};
	
The CSSCustomMediaRule interface represents a ''@custom-media'' rule.
	interface CSSCustomMediaRule : CSSRule {
		attribute DOMString name;
		[SameObject, PutForwards=mediaText] readonly attribute MediaList media;
	};
	
name, of type DOMString
The name attribute on getting must return a DOMString object that contains the serialization of the <> defined for the associated rule. On setting the name attribute, run the following steps:
  1. Parse a component value from the value.
  2. If the returned value is an <>, replace the associated rule's name with the <>'s representation.
  3. Otherwise, do nothing.
media, of type MediaList, readonly
The media attribute must return a MediaList object for the <> specified with the associated rule.

Appendix A: Deprecated Media Features

The following media features are deprecated. They kept for backward compatibility, but are not appropriate for newly written style sheets. Authors must not use them. User agents must support them as specified.

To query for the size of the viewport (or the page box on page media), the 'width', 'height' and 'aspect-ratio' media features should be used, rather than 'device-width', 'device-height' and 'device-aspect-ratio', which refer to the physical size of the the device regardless of how much space is available for the document being laid out. The device-* media features are also sometimes used as a proxy to detect mobile devices. Instead, authors should use media features that better represent the aspect of the device that they are attempting to style against.

device-width

	Name: device-width
	Value: <>
	For: @media
	Type: range
	
The 'device-width' media feature describes the width of the rendering surface of the output device. For continuous media, this is the width of the screen. For paged media, this is the width of the page sheet size. A specified <> cannot be negative.
@media (device-width < 800px) { … }
In the example above, the style sheet will apply only to screens less than ''800px'' in length. The ''px'' unit is of the logical kind, as described in the Units section.
Note: If a device can be used in multiple orientations, such as portrait and landscape, the 'device-*' media features reflect the current orientation.

device-height

	Name: device-height
	Value: <>
	For: @media
	Type: range
	
The 'device-height' media feature describes the height of the rendering surface of the output device. For continuous media, this is the height of the screen. For paged media, this is the height of the page sheet size. A specified <length> cannot be negative.
<link rel="stylesheet" media="(device-height > 600px)" />
In the example above, the style sheet will apply only to screens taller than 600 vertical pixels. Note that the definition of the ''px'' unit is the same as in other parts of CSS.

device-aspect-ratio

	Name: device-aspect-ratio
	Value: <>
	For: @media
	Type: range
	
The 'device-aspect-ratio media feature is defined as the ratio of the value of the 'device-width' media feature to the value of the 'device-height media feature.
For example, if a screen device with square pixels has 1280 horizontal pixels and 720 vertical pixels (commonly referred to as "16:9"), the following media queries will all match the device:
		@media (device-aspect-ratio: 16/9) { … }
		@media (device-aspect-ratio: 32/18) { … }
		@media (device-aspect-ratio: 1280/720) { … }
		@media (device-aspect-ratio: 2560/1440) { … }
		

Changes

Changes Since the Media Queries Level 3

The following changes were made to this specification since the 19 June 2012 Recomendation of Media Queries Level 3:
  • Large editorial rewrite and reorgization of the document.
  • Boolean-context media features are now additionally false if they would be true for the keyword ''none''.
  • Media features with numeric values can now be written in a range context.
  • The 'scripting', 'pointer', 'hover', 'light-level', 'update-frequency', 'overflow-block', and 'overflow-inline' media features were added.
  • ''or'', ''and'', ''only'' and ''not'' are disallowed from being recognized as media types, even invalid ones. (They'll trigger a syntax error instead.)
  • White space is required around the keyword “and” as well as after “not” and “only”.
  • All media types except for ''screen'', ''print'', ''speech'', and ''all'' are deprecated.
  • Deprecated 'device-width', 'device-height', 'device-aspect-ratio'

Acknowledgments

This specification is the product of the W3C Working Group on Cascading Style Sheets. Comments from Arve Bersvendsen, Björn Höhrmann, Chris Lilley, Christoph Päper, L. David Baron, Elika J. Etemad, François Remy, Melinda Grant, Nicholas C. Zakas Philipp Hoschka, Rick Byers, Rijk van Geijtenbeek, Roger Gimson, Sigurd Lerstad, Simon Kissane, Simon Pieters, Steven Pemberton, and Susan Lesch improved this specification.