Media Queries in ePUBs

  • Sumo

Liz Castro has a great post on her Pigs, Gourds, and Wikis blog titled “Multiple Indents.” The post is related to a discussion on Twitter at #ePrdctn with Natasha Fondren (@ebookartisans) on how to ensure that poetic indents will work accurately in ePUB and continue to work when the ePUB is converted to Kindle format using KindleGen. This also builds on what Liz wrote in her post “Media Queries for formatting Poetry on Kindle and EPUB.”

With the proliferation of eReader devices, tablets, and phones all being using as reading devices, I thought it would be helpful to take a look at media queries and how you can apply them to ePUBs.

What Are Media Queries?

So what is a media query? Essentially it is a way to differentiate how content is displayed based on the media that is displaying it.  W3C defines it as:

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

A good example is a Web site with content that is intended to be printed out by a user. It may have different CSS style depending on the media for which it is rendered, for example:

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

In this example, type would reference "sans-serif.css" if it was displayed on screen, but would reference "serif.css" if it is to be printed. In an ePUB, these two lines of markup would appear at the begin of each XHTML/HTML file where the link to the CSS appears. In this case, the two lines of markup with links to two separate CSS files indicate that there is more than one CSS in the ePUB. Media queries can also be used within a single CSS within an individual style element.

In HTML4 and CSS2,  the complete list of media types in HTML4 is: "aural", "braille", "handheld", "print", "projection", "screen", "tty", "tv". CSS2 defines the same list, deprecates "aural" and adds "embossed" and "speech". Also, "all" is used to indicate that the style sheet applies to all media types.

In HTML 5 and CSS3, users can create additional media types as long as they follow they proper syntax. Most eReaders will probably default to media="screen", but there are other options. In fact, the new Amazon Kindle Publishing Guidelines define two new types of media.

Support for two new media types enables content creators to use specific CSS based on the Mobi or KF8 file format: amzn-mobi and amzn-kf8.

In addition, Amazon defines what media the Kindle devices will recognize.

The @media screen and @media all styles continue to apply to both KF8 and Mobi. If the media type is not amzn-mobi, amzn-kf8, screen, or all, Kindle ignores it.

You can also use "not" before the device name for all devices that are not the device specified (media="not amzn-mobi").

So in Liz Castro’s example with poetry on ADE friendly devices, the Kindle Fire, and the regular Kindle, you are create styles specific to the Kindle or Kindle Fire, you will have one CSS that has no media query and applies to all readers, and then have additional CSSs that apply to particular devices and include media queries.

<style type="text/css">
h1 {text-align: left}
p {line-height: 1;padding:0;margin:0}
</style>

<style type="text/css" media="amzn-kf8" [or "not amzn-kindle"]>
p.firstline {margin-top:2em; margin-left:2em; text-indent: -2em;}
p.line {margin-left:2em; text-indent: -2em;}
</style>

<style type="text/css" media="amzn-mobi">
p.firstline {margin-top:20px;text-indent:-40px}
p.line {text-indent:-40px}
</style>

 

This is an example of the media query being used within a single CSS. For all media, h1 will text-align: left and p will have line-height: 1; padding: 0;margin: 0;. Where the media query comes into play is with p.firstline and p.line, which will each be displayed differently based on the device.
Just remember that when media queries are included one CSS, the device will display any styles in the “generic” first set of styles that is not superseded by a specific style specified after the media query. A device will also run through the media queries and stick to the styles of the last one that fits it.
Always start with the default or generic device styles in the CSS. If you are styling for a particular device (say the iPad), do not put the media query for it specifically before a more generic media query for which it will answer “yes.” If you do, the iPad will drop down to the last media query that it matches and display text using that last style.

Common Media Features

Devices can also be defined by their features using media features. While media features resemble CSS styles there are some differences. From the W3C Media Queries, the differences are defined as:

  • Properties are used in declarations to give information about how to present a document. Media features are used in expressions to describe requirements of the output device.
  • Most media features accept optional "min-" or "max-" prefixes to express “greater or equal to” and “smaller or equal to” constraints. This syntax is used to avoid “<” and “>” characters which may conflict with HTML and XML. Those media features that accept prefixes will most often be used with prefixes, but can also be used alone.
  • Properties always require a value to form a declaration. Media features, on the other hand, can also be used without a value. For a media feature feature(feature) will evaluate to true if (feature:x) will evaluate to true for a value x other than zero or zero followed by a unit identifier (i.e., other than 00px0em, etc.). Media features that are prefixed by min/max cannot be used without a value. When a media feature prefixed with min/max is used without a value it makes the media query malformed.
  • Properties may accept more complex values, e.g., calculations that involve several other values. Media features only accept single values: one keyword, one number, or a number with a unit identifier. (The only exceptions are the "aspect-ratio" and "device-aspect-ratio" media features.)

Media features that can be defined in a media query include

  • width (of the targeted display area of the output device)
  • height (of the targeted display area of the output device)
  • device-width (of the rendering surface of the output device)
  • device-height (of the rendering surface of the output device)
  • orientation (portrait or landscape)
  • aspect-ratio (ratio of the value of the "width" to "height" media feature)
  • device-aspect-ratio (ratio  of the value of the "device-width" to "device-height" media feature)
  • resolution (the resolution of the output device, i.e. the density of the pixels. When querying devices with non-square pixels, in "min-resolution" queries the least-dense dimension must be compared to the specified value and in “max-resolution” queries the most-dense dimensions must be compared instead. A "resolution" [without a "min-" or "max-" prefix] query never matches a device with non-square pixels.)

There are a few others that can be used (color, color-index, monochrome, scan, and grid), but these are the ones the I have generally seen in ePUBs and other eBooks. All the bulleted values above accept min-/max- values except orientation, which is just portrait or landscape. These min-/max- values are important because they allow you to not have to know exactly what the width, height, and pixel count of every device out there is. You can generalize to a four-inch smartphone screen, a six-inch eReader, a seven-inch Android Tablet, or a nine-inch Android or iOS tablet

If you were creating separate CSS files for a regular ePUB, an iPad in portrait orientation, and an iPad in landscape orientation, they might look something like this:

<link href=”css/all.css” type=”text/css” />
<link media=”all and (orientation:portrait)” href=”css/ipadportrait.css” type=”text/css” />
<link media=”all and (orientation:landscape)” href=”css/ipadlandscape.css” type=”text/css” />

Media resolution is a good example of how you can use media queries to determine on what device someone is reading your ePUB. There are examples all over the Web of setting you might want to use, but here is one from Get Skeleton for iOS devices specifically:

That being said, all of the queries were written to be optimal on Apple iOS devices. The built in media queries include:

  • Smaller than 960: Smaller than the standard base grid
  • Tablet Portrait: Between 768px and 959px
  • All Mobile Sizes: Less than 767px
  • Just Mobile Landscape: Between 480px and 767px
  • Just Mobile Portrait: Less than 479px

No Media Queries for ePUB 2.0.1

The current ePUB implementation you see on most readers and devices is for ePUB 2.0.1. The styling in ePUB 2.0.1 was based was based on a specific subset of CSS 2, and did not support @media and @import rules with media queries. As a result, most eReading apps and devices for this spec do no support media queries in the CSS. The ePUB 3.0 spec, in contrast, defines a profile of CSS based on CSS 2.1 with added modules from CSS3. It  includes @media and @import rules with media queries as defined in the Media Queries specification from the W3C.

Apple and Amazon’s Early Implementation of Media Queries

Along with Webkit elements, Apple has supported media queries in iBooks. It makes sense when you think about the two different screen sizes of iOS devices and the many things you can do to improve readability on an iPad (if you are not breaking running text/paragraphs into two columns for anyone reading in landscape view, you might want to consider.

As stated previously, Amazon supports media queries in their new publishing guidelines and KindleGen2. The media queries make a lot of sense with Amazon essentially bifurcating their offerings into plain vanilla Kindle files for the eInk devices and enhanced multi-media and fixed layout offerings in KF8.

ePUB 3.0

The new ePUB 3.0 spec includes media queries. We will need to wait to see how device makers and retailers support this part of the spec, but I think we can assume that media queries are going to become a common ingredient when building ePUBs in the very near future if they are not already so.

It is not too hard to imagine a world where all the device makers have created their own media type for their device to ensure optimum display much as Amazon has done. It is, however, hard to fathom how ePUB creators will possibly have time to create separate CSS files for every different device on the market. Let us hope that device makers have the good sense (and take pity on those creating ePUBs) and adopt the ePUB 3 spec and support it fully while agreeing to some common media types that devices will recognize or making their device specs available so they can be easily identified in big device feature buckets. We may still need to create separate CSS, or separate files, for legacy ePUB2 readers and new or updated ePUB3 readers, for six-inch eInk readers vs. color tablets at seven- or nine-inches.

Media Query Test File

Finally, if you ever want to test the media features on a device, try this file from Peter posted to his Extraordinary Commons blog (Peter posts great content on Kindle especially, so check out his blog regularly). It will give you a nice summary of your device if you open the link in your device’s browser. Also, check out his post “Media Query Values for Kindle Fire” for the results we received when we ran it on a Kindle Fire. You can also copy the source HTML to a file, load it on your device, and open it locally. Of course, I already scraped it for you.

<html lang=”en”><head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ />
<title>Media query test</title>
<style>
span {
text-decoration: line-through;
}
@media (device-width: 1024px) {
#dw1024 { text-decoration: none; }
}
@media (device-width: 600px) {
#dw600 { text-decoration: none; }
}
@media (device-height: 1024px) {
#dh1024 { text-decoration: none; }
}
@media (device-height: 600px) {
#dh600 { text-decoration: none; }
}
@media (device-aspect-ratio: 1024/600) {
#dar1024x600 { text-decoration: none; }
}
@media (device-aspect-ratio: 600/1024) {
#dar600x1024 { text-decoration: none; }
}
@media (orientation: portrait) {
#portrait { text-decoration: none; }
}
@media (orientation: landscape) {
#landscape { text-decoration: none; }
}
@media (width: 526px) {
#w526 { text-decoration: none; }
}
@media (width: 950px) {
#w950 { text-decoration: none; }
}
@media (height: 990px) {
#h990 { text-decoration: none; }
}
@media (height: 566px) {
#h566 { text-decoration: none; }
}
@media (aspect-ratio: 526/990) {
#ar526x990 { text-decoration: none; }
}
@media (aspect-ratio: 950/566) {
#ar950x566 { text-decoration: none; }
}
@media (color: 10) {
#c10 { text-decoration: none; }
}
@media (min-color-index: 0) {
#color-index { text-decoration: none; }
}
@media (monochrome: 0) {
#m0 { text-decoration: none; }
}
@media (min-resolution: 1dpi) {
#resolution { text-decoration: none; }
}
@media (grid: 0) {
#g0 { text-decoration: none; }
}
</style>
</head><body>
<div>Device width: <span id=”dw1024″>1024px</span> <span id=”dw600″>600px</span></div>
<div>Device height: <span id=”dh600″>600px</span> <span id=”dh1024″>1024px</span></div>
<div>Device aspect ratio: <span id=”dar1024x600″>1024/600</span> <span id=”dar600x1024″>600/1024</span></div>
<div>Orientation: <span id=”portrait”>portrait</span> <span id=”landscape”>landscape</span></div>
<div>Width: <span id=”w526″>526px</span> <span id=”w950″>950px</span></div>
<div>Height: <span id=”h990″>990px</span> <span id=”h566″>566px</span></div>
<div>Aspect ratio: <span id=”ar526x990″>526/990</span> <span id=”ar950x566″>950/566</span></div>
<div>Color: <span id=”c10″>10</span></div>
<div>Color index: <span id=”color-index”>supported</span></div>
<div>Monochrome: <span id=”m0″>0</span></div>
<div>Resolution: <span id=”resolution”>supported</span></div>
<div>Grid: <span id=”g0″>0</span></div>
</body></html>

Results of the Media Query Test on Kindle Fire

Are you inserting media queries into your ePUBs? Are you going to start when you create ePUB3s? What else have you done with media queries in ePUBs?

5 Responses to “Media Queries in ePUBs”

  1. Ricardo says:

    Hello,

    Very interesting article, but I have a question:

    Can you use ‘max-width’/’min-width’ in media queries for ePUBS?

    Thanks.

  2. […] our sidebars, we have some simple CSS (specifically, media queries) that do the following (for Mobi7 […]

  3. […] our sidebars, we have some simple CSS (specifically, media queries) that do the following (for Mobi7 […]

  4. […] Interested in learning more about what a media query is and does? Read our previous post on the topic here. […]

  5. Hi, I do think this is an excellent web site. I stumbledupon it 😉 I
    maay revisit yet again since i have saved as a favorite
    it. Money and freedom iis the best way to change, may you be richh and continue to
    help others.

    Feel free to suirf to my webpage; 8 what is search engine optimization and why is it important