CSS3 Media Queries - HTML5 Multimedia - HTML5, JavaScript and jQuery (Programmer to Programmer) - 2015

HTML5, JavaScript and jQuery (Programmer to Programmer) - 2015

Part III HTML5 Multimedia

Lesson 28 CSS3 Media Queries

You will end this section by taking a first look at CSS3 media queries. This is a subject you will return to when you look at developing web applications for mobile phones, but this lesson will introduce the fundamentals for developing web applications that render differently on different devices, and in different contexts.

It is now very common for a web application to be used on many different devices. For example:

· In a web browser, on a desktop or laptop

· Output to a printer

· On a small screen device, such as a smart phone

· On an alternative device, such as a TV

Although the basic functionality of the web application may be the same in each case, it may be necessary to reposition, hide, or augment the display of specific elements for each device.

There are several ways to solve this problem. Historically, the most common approach has been for the web server to detect the browser (or user agent) accessing the web page, and directing the user to a page created specifically for this device.

Any time a browser requests a web page, it provides a variety of information in HTTP headers. These can be can be used by the web server to reliably detect the browser and operating system. For example, Figure 28.1 shows the headers that were passed to the web server when performing a simple HTTP GET request, including the User Agent header.

image

Figure 28.1

There are two main problems with this approach. The first is that it does not necessarily provide the entire context of the user's web browser. For instance, if the user is using a tablet, it will not contain information on whether he or she is using landscape or portrait mode. Likewise, it cannot be used to augment the web page for printing because printing a page does not trigger a request for a new web page from the server.

The second problem is that it can become difficult to maintain content in this manner. There will often be large amounts of duplication across the different versions of the web pages. When a change is required to the web application, it may therefore be necessary to make the same change in many different files.

CSS3 now offers an alternative mechanism for solving this problem in the form of media queries. These queries allow a stylesheet to tell the browser how to behave in various contexts, and therefore allow the same page to render differently without changing any markup.

With media queries, it is up to the browser itself to determine whether specific stylesheets, or portions of stylesheets, are relevant for them based on a set of rules, and to render the web page appropriately.

Media queries allow a stylesheet to provide custom rules based on:

· The device type—for instance, screen, printer, or TV

· The width or height of the browser or screen

· Whether the orientation is landscape or portrait

· Whether the device is color or monochrome

This lesson will focus on the first of these bullet points and return to examine the other bullet points when you develop mobile web applications in future lessons.

Adding Media Queries

Imagine that you wish to add print capabilities to the CRM web application. When clicked, this will only print the contacts in the table; it will never print the editable section of the screen, even if it is present, and it will not print the header or the footer.

One way to achieve this may be to add a new class called noprint to every element you do not wish to print. For example:

<header class="noprint">Contacts</header>

Then, add the following rule to contacts.css:

@media print {

.noprint {

display: none;

}

}

Notice that the rule begins with the @media tag. This indicates that the rule will only apply in specific contexts. The @media tag is followed by a query that allows the browser to determine whether the rule is applicable in specific contexts. In this case, the query isprint, which indicates that the rule only applies if the web page is being printed.

The other common values for media queries are:

· all: Matches all device types.

· screen: Matches any screen-based device, which therefore excludes printers.

· tv: Matches when the page is viewed on a television.

· handheld: This is intended to match browsers on small screen devices such as smart phones. I don't recommend that you use this option, however, because it is not reliably supported. You will look at a more reliable alternative to this later in the book.

Next, add a print button to the screen, and also ensure that the “Add a new contact” button does not print:

<div class="controls noprint">

<a href="#" id="addContact">Add a new contact</a>

<a onClick="window.print()" href="#">Print</a>

</div>

I also updated the table so that the Actions column has the noprint class (both the th and td elements). If you now elect to print the web application, it should generate a preview, as shown in Figure 28.2.

image

Figure 28.2

You will notice that only the appropriate elements are included in the print preview. You may notice, however, that the table header does not print as expected. In the web application, the header has a blue background and a white font. When browsers print web pages, they typically suppress background colors to save ink. As a result, they compensate by changing white fonts to have color.

In this case, the overall effect is not what you may want because the font is quite difficult to read. You also may choose to remove the border and white space from around the table. You can therefore add the following rules to your media query:

@media print {

.noprint {

display: none !important;

}

th {

color:black;

background:white;

}

#contactList {

border: none;

margin: none;

padding:none;

}

}

This will then generate the preview shown in Figure 28.3.

image

Figure 28.3

External Stylesheets

The approach outlined in the previous text involves adding device-specific rules to stylesheets. Often it is more convenient to create a base stylesheet that matches all device types, and then create device-specific stylesheets that override relevant styles.

This can be achieved by using the media attribute on the link element. For example:

<link rel="stylesheet" media="all" type="text/css" href="contacts.css">

After the base stylesheet is imported, the device-specific stylesheets can be imported. It is important that these are listed after the base stylesheet because they are likely to have rules that supersede those in the base stylesheet. For example:

<link rel="stylesheet" media="print" type="text/css" href="contacts_print.css">

Naturally, when stylesheets are imported in this manner, the stylesheets themselves do not need to contain media queries, although they still can if necessary.

It is important to realize that matches based on media queries do not have higher specificity than they would otherwise so it can also be necessary to use the !important modifier to ensure that media-specific styles are used.

Try It

In this Try It, you will introduce a print-specific stylesheet for printing. If you have not followed the example so far in this lesson, you may want to go back and implement the print functionality outlined before starting this Try It.

Lesson Requirements

You will need a text editor to write the code and the Chrome browser to run the code.

Step-by-Step

1. Start by creating a new stylesheet called contacts_print.css in the same folder as contacts.css.

2. Add the print-specific functionality to this stylesheet and remove any media queries.

3. Import the print stylesheet after the contacts.css stylesheet, and indicate that it is applicable for printing.

4. Add a media type to the contacts.css import, and indicate that it is applicable to all device types.

5. Add a new header specifically for printing; this should state “Printed from CRM.”

6. Add a class called print_only to this element, and then add rules to both the base and print stylesheets. The base stylesheet should set the display to none. The print stylesheet should set the display to initial, which means to restore it to its default value.

7. Change the header style in the print stylesheet to use a black, 16-pixel font.

Reference

Please go to the book's website at www.wrox.com/go/html5jsjquery24hr to view the video for Lesson 28, as well as download the code and resources for this lesson.