Chapter 20. Media-Dependent Styles

A great deal of our CSS work goes into putting content onto screens of various kinds, whether they sit on office desks or rest in the palms of our hands. There is more to the web than screens, though, and even in the part that is screen-centric, there are many different kinds of screens, each with its own constraints. Recognizing this reality, CSS provides a number of tools with which to apply styles in specific media, or in media with specific features.

Defining Media-Dependent Styles

Thanks to the mechanisms defined in HTML and CSS called media queries, you can restrict any kind of style sheet to a specific medium, such as screen or print, and set of media conditions. These mechanisms allows you to define a combination of media types and parameters such as display size or color depth, to pick two examples. We’ll cover the basic form of these queries before exploring the more complex forms.

Basic Media Queries

For HTML-based style sheets, you can impose medium restrictions through the media attribute. This works the same for both the link and style elements:

<link rel="stylesheet" type="text/css" media="print"
    href="article-print.css">
<style type="text/css" media="speech">
    body {font-family: sans-serif;}
</style>

The media attribute can accept a single medium value or a comma-separated list of values. Thus, to link in a style sheet that should be used in only the screen and speech media, you would write:

<link rel="stylesheet" type="text/css" media="screen, speech"
    href="visual.css">

In a style sheet itself, you can also impose medium restrictions on @import rules:

@import url(visual.css) screen;
@import url(outloud.css) speech;
@import url(article-print.css) print;

Remember that if you don’t add medium information to a style sheet, it will be applied in all media. Therefore, if you want one set of styles to apply only on screen, and another to apply only in print, then you need to add medium information to both style sheets. For example:

<link rel="stylesheet" type="text/css" media="screen"
    href="article-screen.css">
<link rel="stylesheet" type="text/css" media="print"
    href="article-print.css">

If you were to remove the media attribute from the first link element in the preceding example, the rules found in the style sheet article-screen.css would be applied in all media.

CSS also defines syntax for @media blocks. This allows you define styles for multiple media within the same style sheet. Consider this basic example:

<style type="text/css">
body {background: white; color: black;}
@media screen {
    body {font-family: sans-serif;}
    h1 {margin-top: 1em;}
}
@media print {
    body {font-family: serif;}
    h1 {margin-top: 2em; border-bottom: 1px solid silver;}
}
</style>

Here we see that in all media, the body element is given a white background and a black foreground by the first rule. This happens because its style sheet, the one defined by the style attribute, has no media attribute and thus defaults to all. Next, a block of rules is provided for the screen medium alone, followed by another block of rules that applies only in the print medium.

@media blocks can be any size, containing any number of rules. In situations where authors have control over a single style sheet, such as a shared hosting environment or a content management system (CMS) that restricts what users can edit, @media blocks may be the only way to define medium-specific styles. This is also the case in situations where CSS is used to style a document using an XML language that does not contain a media attribute or its equivalent.

These are the four most widely recognized media types:

all

Use in all presentational media.

print

Use when printing the document for sighted users, and also when displaying a print preview of the document.

screen

Use when presenting the document in a screen medium like a desktop computer monitor or a handheld device. All web browsers running on such systems are screen-medium user agents.

speech

Use in speech synthesizers, screen readers, and other audio renderings of the document.

HTML4 defined a list of media types that CSS originally recognized, but most of them have been deprecated and should be avoided. These are aural, braille, embossed, handheld, projection, tty, and tv. If you have old style sheets that use these media types, they should be converted to one of the four recognized media types, if possible.

Note

It’s entirely possible that new media types will be added over time, so remember that this limited list may not always be so limited. It’s fairly easy to imagine augmented-reality as a media type, for example, since text in AR displays would likely need to be of higher contrast in order to stand out against the background reality.

It’s possible in some circumstances to combine media types into comma-separated lists, though the rationale for doing so isn’t terribly compelling, given the small number of media types currently available. For example, styles could be restricted to only screen and print media in the following ways:

<link rel="stylesheet" type="text/css" media="screen, print"
    href="article.css">
@import url(article.css) print, screen;

@media screen,print {
    /* styles go here */
}

Complex Media Queries

In the previous section, we saw how multiple media types could be chained together with a comma. We might call that a compound media query, because it allows us to address multiple media at once. There is a great deal more to media queries, though: it’s possible to apply styles based not just media types, but also features of those media, such as display size or color depth.

This is a great deal of power, and it’s not enough to rely on commas to make it all happen. Thus, CSS introduced the logical operator and to pair media types with features of those media.

Let’s see how this plays out in practice. Here are two essentially equivalent ways of applying an external style sheet when rendering the document on a color printer:

<link href="print-color.css" type="text/css"
    media="print and (color)" rel="stylesheet">
@import url(print-color.css) print and (color);

Anywhere a media type can be given, a media query can be constructed. This means that, following on the examples of the previous section, it is possible to list more than one query in a comma-separated list:

<link href="print-color.css" type="text/css"
   media="print and (color), screen and (color)" rel="stylesheet">
@import url(print-color.css) print and (color), screen and (color);

In a situation where even one of the media queries evaluates to true, the associated style sheet is applied. Thus, given the previous @import, print-color.css will be applied if rendering to a color printer or to a color screen environment. If printing on a black-and-white printer, both queries will evaluate to false and print-color.css will not be applied to the document. The same holds true in a grayscale screen environment, any speech media environment, and so forth.

Each media descriptor is composed of a media type and one or more listed media features, with each media feature descriptor is enclosed in parentheses. If no media type is provided, then it is assumed to be all, which makes the following two examples equivalent:

@media all and (min-resolution: 96dpi) {}
@media (min-resolution: 96dpi) {}

Generally speaking, a media feature descriptor is formatted like a property-value pair in CSS, only enclosed by parentheses. There are a few differences, most notably that some features can be specified without an accompanying value. For example, any color-based medium will be matched using (color), whereas any color medium using a 16-bit color depth is matched using (color: 16). In effect, the use of a descriptor without a value is a true/false test for that descriptor: (color) means “is this medium in color?”

Multiple feature descriptors can be linked with the and logical keyword. In fact, there are two logical keywords in media queries:

and

Links together two or more media features in such a way that all of them must be true for the query to be true. For example, (color) and (orientation: landscape) and (min-device-width: 800px) means that all three conditions must be satisfied: if the media environment has color, is in landscape orientation, and the device’s display is at least 800 pixels wide, then the style sheet is used.

not

Negates the entire query so that if all of the conditions are true, then the style sheet is not applied. For example, not (color) and (orientation: landscape) and (min-device-width: 800px) means that if the three conditions are satisfied, the statement is negated. Thus, if the media environment has color, is in landscape orientation, and the device’s display is at least 800 pixels wide, then the style sheet is not used. In all other cases, it will be used.

Note that the not keyword can only be used at the beginning of a media query. It is not presently legal to write something like (color) and not (min-device-width: 800px). In such cases, the query will be ignored. Note also that browsers too old to understand media queries will always skip a style sheet whose media descriptor starts with not.

An example of how all this plays out is shown in Figure 20-1, which is the result of the following styles:

@media screen and (min-resolution: 72dpi) {
	.cl01 {font-style: italic;}
}
@media screen and (min-resolution: 32767dpi) {
	.cl02 {font-style: italic;}
}
@media not print {
	.cl03 {font-style: italic;}
}
@media not print and (grayscale) {
	.cl04 {font-style: italic;}
}
css4 2001
Figure 20-1. Logical operators in media queries

First, bear in mind that, even though you may be reading this on printed paper, the actual image in Figure 20-1 was generated with a screen-medium browser (Firefox Nightly, as it happens) displaying an HTML document with the previous CSS applied to it. So everything you see there was operating under a screen medium.

The first line is italicized because the screen on which the file was displayed had a resolution equal to or greater than than 72 dots per inch. Its resolution was not, however, 32767dpi or higher, so the second media block is skipped and thus the second line stays un-italicized. The third line is italicized because, being a screen display, it was not print. The last line is italicized because it was either not print or not grayscale—in this case, not grayscale.

There is no OR keyword for use in media queries. Instead, the commas that separate a list of queries serve the function of an OR—screen, print means “apply if the media is screen or print.” Therefore, instead of screen and (max-color: 2) or (monochrome), which is invalid and thus ignored, you need to write screen and (max-color: 2), screen and (monochrome).

There is one more keyword, only, which is designed to create deliberate backward incompatibility. Yes, really.

only

Used to hide a style sheet from browsers too old to understand media queries. For example, to apply a style sheet in all media, but only in those browsers that understand media queries, you write something like @import url(new.css) only all. In browsers that do understand media queries, the only keyword is ignored and the style sheet is applied. In browsers that do not understand media queries, the only keyword creates an apparent media type of only all, which is not valid. Thus, the style sheet is not applied in such browsers. Note that the only keyword can only be used at the beginning of a media query.

Media feature descriptors

So far we’ve seen a number of media feature descriptors in the examples, but not a complete list of the possible descriptors and their values. Let us fix that now!

Note that none of the following values can be negative, and remember that feature descriptors are always enclosed in parentheses.

Descriptors: width, min-width, max-width
Values: <length>

Refers to the width of the display area of the user agent. In a screen-media web browser, this is the width of the viewport plus any scrollbars. In paged media, this is the width of the page box, which is the area of the page in which content is rendered. Thus, (min-width: 850px) applies when the viewport is greater than or equal to 850 pixels wide.

Descriptors: height, min-height, max-height
Values: <length>

Refers to the height of the display area of the user agent. In a screen-media web browser, this is the height of the viewport plus any scrollbars. In paged media, this is the height of the page box. Thus, (height: 567px) applies when the viewport’s height is precisely 567 pixels tall.

Descriptors: device-width, min-device-width, max-device-width
Values: <length>

Refers to the width of the complete rendering area of the output device. In screen media, this is the width of the screen; i.e., a handheld device screen’s or desktop monitor’s horizontal measurement. In paged media, this is the width of the page itself. Thus, (max-device-width: 1200px) applies when the device’s output area is less or equal to than 1,200 pixels wide.

Descriptors: device-height, min-device-height, max-device-height
Values: <length>

Refers to the height of the complete rendering area of the output device. In screen media, this is the height of the screen; i.e., a handheld device screen’s or desktop monitor’s vertical measurement. In paged media, this is the height of the page itself. Thus, (max-device-height: 400px) applies when the device’s output area is less than or equal to 400 pixels tall.

Descriptors: aspect-ratio, min-aspect-ratio, max-aspect-ratio
Values: <ratio>

Refers to the ratio that results from comparing the width media feature to the height media feature (see the definition of <ratio> in the next section). Thus, (min-aspect-ratio: 2/1) applies to any viewport whose width-to-height ratio is at least 2:1.

Descriptors: device-aspect-ratio, min-device-aspect-ratio, max-device-aspect-ratio
Values: <ratio>

Refers to the ratio that results from comparing the device-width media feature to the device-height media feature (see the definition of <ratio> in the next section). Thus, (device-aspect-ratio: 16/9) applies to any output device whose display area width-to-height is exactly 16:9.

Descriptors: color, min-color, max-color
Values: <integer>

Refers to the presence of color-display capability in the output device, with an optional number value representing the number of bits used in each color components. Thus, (color) applies to any device with any color depth at all, whereas (min-color: 4) means there must be at least four bits used per color component. Any device that does not support color will return 0.

Descriptors: color-index, min-color-index, max-color-index
Values: <integer>

Refers to the total number of colors available in the output device’s color lookup table. Any device that does not use a color lookup table will return 0. Thus, (min-color-index: 256) applies to any device with a minimum of 256 colors available.

Descriptors: monochrome, min-monochrome, max-monochrome
Values: <integer>

Refers to the presence of a monochrome display, with an optional number of bits-per-pixel in the output device’s frame buffer. Any device that is not monochrome will return 0. Thus, (monochrome) applies to any monochrome output device, whereas (min-monochrome: 2) means any monochrome output device with a minimum of 2 bits per pixel in the frame buffer.

Descriptors: resolution, min-resolution, max-resolution
Values: <resolution>

Refers to the resolution of the output device in terms of pixel density, measured in either dots per inch (dpi) or dots per centimeter (dpcm); see the definition of <resolution> in the next section for details. If an output device has pixels that are not square, then the least dense axis is used; for example, if a device is 100 dpcm along one axis and 120 dpcm along the other, then 100 is the value returned. Additionally, in such non-square cases, a bare resolution feature query—that is, one without a value—can never match (though min-resolution and max-resolution can). Note that resolution values must not only be non-negative, but also nonzero.

Descriptors: orientation
Values: portrait | landscape

Refers to the orientation of the user agent’s display area, where portrait is returned if the media feature height is equal to or greater than the media feature width. Otherwise, the result is landscape.

Descriptor: scan
Values: progressive | interlace

Refers to the scanning process used in an output device. interlace is the type generally used in CRT and some plasma displays. progressive is more common, being the type of scanning used in most modern displays.

Descriptor: grid
Values: 0 | 1

Refers to the presence (or absence) of a grid-based output device, such as a TTY terminal. A grid-based device will return 1; otherwise, 0 is returned. This feature descriptor can be used in place of the old tty media descriptor.

New value types

There are two new value types introduced by media queries, and which (as of early 2017) are not used in any other context. These types are used in conjunction with specific media features, which are explained in the previous sections:

<ratio>

A ratio value is two positive <integer> values separated by a solidus (/) and optional whitespace. The first value refers to the width, and the second to the height. Thus, to express a height-to-width ratio of 16:9, you can write 16/9 or 16 / 9. As of this writing, there is no facility to express a ratio as a single real number, nor to use a colon separator instead of a solidus.

<resolution>

A resolution value is a positive <integer> followed by either of the unit identifiers dpi or dpcm. In CSS terms, a “dot” is any display unit, the most familiar of which is the pixel. As usual, whitespace is not permitted between the <integer> and the identifier. Therefore, a display whose display has exactly 150 pixels (dots) per inch is matched with 150dpi.

Responsive styling

Media queries are, at least as of early 2017, the foundation on which the practice of responsive web design is built. By applying different sets of rules depending on the display environment, it’s possible to marry mobile-friendly and desktop-friendly styles into a single style sheet.

Those terms were put in quote because, as you may have seen in your own life, the lines between what’s mobile and what’s desktop are blurred. A laptop with a touch-sensitive screen that folds all the way back can act as both a tablet and a laptop, for example. CSS doesn’t (yet) have a way of detecting whether or not a hinge is open past a certain point, nor whether the device is held in hand or sitting on a flat surface. Instead, inferences are drawn from aspects of the media environment, like display size or display orientation.

A fairly common pattern in responsive design is to define breakpoints for each @media block. This often takes the form of certain pixel widths, like this:

/* …common styles here… */
@media (max-width: 400px) {
    /* …small-screen styles here… */
}
@media (min-width: 401px) and (max-width: 1000px) {
    /* …medium-screen styles here… */
}
@media (min-width: 1001px) {
    /* …big-screen styles here… */
}

This is often sufficient. It does make certain assumptions about what a device can display and how it will report that, however. For example, the iPhone 6 Plus had a resolution of 1,242 × 2,208, which it downsampled to 1,080 × 1,920. Even at the downsampled resolution, that’s enough pixels across to qualify for big-screen styles in the previous example.

But wait! The iPhone 6 Plus also maintained an internal coordinate system of points which measured 414 × 736. If it decided to use those as its definition of pixels, which would be entirely valid, then it would only get the small-screen styles.

The point here isn’t to single out the iPhone 6 Plus as uniquely bad, which it wasn’t, but to illustrate the uncertainties of relying on pixel-based media queries. Browser makers have gone to some effort to make their browsers behave with some semblance of sanity, but never quite as much as we’d like, and you never know when a new device’s assumptions will clash with your own.

There are other methods available, though they come with their own uncertainties. Instead of pixels, you might try em-based measures, something like this:

/* …common styles here… */
@media (max-width: 20em) {
    /* …small-screen styles here… */
}
@media (min-width: 20.01em) and (max-width: 50em) {
    /* …medium-screen styles here… */
}
@media (min-width: 50.01em) {
    /* …big-screen styles here… */
}

This ties the breakpoints to text display size rather than pixels, which is somewhat more robust. This isn’t perfect either, though: it relies on a sensible approach to determining the em width of, say, a smartphone. It also directly relies on the actual font family and size used by the device, which varies from one device to another.

Here’s another seemingly simple query set with potentially surprising results:

/* …common styles here… */
@media (orientation: landscape) {
    /* …wider-than-taller styles here… */
}
@media (orientation: portrait) {
    /* …taller-than-wider styles here… */
}

This feels like a good way to tell if a smartphone is in use: after all, most of them are taller than they are wide, and most people don’t turn them sideways to read. The wrinkle is that the orientation feature refers to the height and width descriptors; that is, orientation is portrait is height is equal to or larger than width. Not device-height and device-width, but height and width, which refer to the display area of the user agent.

That means a desktop browser window whose display area (the part inside the browser Chrome) is taller than it is wide, or even perfectly square, will get the portrait styles. So if you assume “portrait equals smartphone,” some of your desktop users could get a surprise.

The basic point here is: responsive styling is powerful, and like any powerful tool, it requires a fair amount of thought and care in its use. Carefully considering the implications of each combination of feature queries is the minimum requirement for successful responsiveness.

Paged Media

In CSS terms, a paged medium is any medium where a document’s presentation is handled as a series of discrete “pages.” This is different than the screen, which is a continuous medium: documents are presented as a single, scrollable “page.” An analog example of a continuous medium is a papyrus scroll. Printed material, such as books, magazines, and laser printouts, are all paged media. So too are slideshows, where a series of slides are shown one at a time. Each slide is a “page” in CSS terms.

Summary

Thanks to the combination of media queries and media-specific style features, it is possible to provide a wide range of design experiences from within a single set of styles. Whether reorganizing a page to account for varying display sizes or reworking the color scheme to support grayscale printing, authors have the ability to do a great deal to make their work the best in can be, no matter what the output channel.

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

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