Chapter 3. Adding Responsive Media

A picture paints a thousand words...

A key element of any website is a visual content; after all, text will become very repetitive and dull, without adding some form of color!

Adding media not only gives color to a site, but can serve as a vital tool to show potential customers what a product looks like or how we should use it. In fact, sales can go up based purely on being able to see a product being demonstrated. With the advent of mobile devices, it is more important that we not only add media, but also ensure it works well on a range of different devices.

Throughout the course of this chapter, we will explore different ways of adding media to our pages, and see how easy it is to make it respond to any changes in available screen size. In this chapter, we will cover the following topics:

  • Understanding the basics of adding images using <picture>
  • Exploring alternatives to adding images
  • Making video and audio content responsive
  • Adjusting text to fit automatically on the screen

Curious? Let's get cracking!

Making media responsive

Our journey through the basics of adding responsive capabilities to a site has so far touched on how we make our layouts respond automatically to changes; it's time for us to do the same to media!

If your first thought is that we need lots of additional functionality to make media responsive, then I am sorry to disappoint; it's much easier, and requires zero additional software to do it! Yes, all we need is just a text editor and a browser; I'll be using my favorite editor, Sublime Text, but you can use whatever works for you.

Over the course of this chapter, we will take a look in turn at images, videos, audio, and text, and we'll see how with some simple changes, we can make each of them responsive. Let's kick off our journey, first with a look at making image content responsive.

Creating fluid images

It is often said that images speak a thousand words. We can express a lot more with media than we can using words. This is particularly true for websites selling products; a clear, crisp image clearly paints a better picture than a poor quality one!

When constructing responsive sites, we need our images to adjust in size automatically. To see why this is important, go ahead and extract coffee.html from a copy of the code download that accompanies this book and run it in a browser. Try resizing the window. We should see something akin to this:

Creating fluid images

It doesn't look great, does it? Leaving aside my predilection for nature's finest bean drink, we can't have images that don't resize properly, so let's take a look at what is involved to make this happen:

  1. Go ahead and extract a copy of coffee.html and save it to our project area.
  2. We also need our image—this is in the img folder; save a copy to the img folder in our project area.
  3. In a new text file, add the following code, saving it as coffee.css:
            img {
               max-width: 100%;
               height: auto;
            }
  4. Revert to coffee.html. You will see line 6 is currently commented out; remove the comment tags.
  5. Save the file, then preview it in a browser. If all is well, we will still see the same image as before, but this time try resizing it.

This time around, our image grows or shrinks automatically, depending on the size of our browser window:

Creating fluid images

Although our image does indeed fit better, there are a couple of points we should be aware of when using this method:

  • Sometimes you might see !important set as a property against the height attribute when working with responsive images; this isn't necessary, unless you're setting sizes in a site where image sizes may be overridden at a later date
  • We've set max-width to 100% as a minimum; you may need to set a width value too, to be sure that your images do not become too big and break your layout

This is an easy technique to use, although there is a downside that can trip us up—spot what it is? If we use a high-quality image, its file size will be hefty—we can't expect users of mobile devices to download it, can we?

Don't worry though - there is a great alternative that has quickly gained popularity among browsers; we can use the <picture> element to control what is displayed, depending on the size of the available window. Let's dive in and take a look.

Implementing the <picture> element

In a nutshell, responsive images are images that are displayed their optimal form on a page, depending on the device your website is being viewed from. This can mean several things:

  • You want to show a separate image asset based on the user's physical screen size. This might be a 13.5-inch laptop or a 5-inch mobile phone screen.
  • You want to show a separate image based on the resolution of the device or using the device-pixel ratio (which is the ratio of device pixels to CSS pixels).
  • You want to show an image in a specified image format (WebP, for example) if the browser supports it.

Traditionally, we might have used simple scripting to achieve this, but it is at the risk of potentially downloading multiple images or none at all, if the script loads after images have loaded, or if we don't specify any image in our HTML and want the script to take care of loading images.

We clearly need a better way to manage responsive images! A relatively new tag for HTML5 is perfect for this job: <picture>. We can use this in one of three different ways, depending on whether we want to resize an existing image, display a larger one, or show a high-resolution version of the image. The recommended way to approach this is:

  1. srcset attribute
  2. sizes attribute
  3. picture element

We'll explore all three in detail; let's start with implementing the srcset attribute in a standard <img> tag, before moving on to using the <picture> element.

Using the srcset attribute

A key benefit of using the <picture> element is using the srcset attribute to select any one of several images, based on whether we want to display higher resolution versions or different sizes of the same image in different viewports.

Support for this in browsers is very good, with only Opera Mini and up to IE11 not wanting to join the party:

To make use of this srcset attribute, we need to avail ourselves of sufficient different images, then specify what should be displayed at the appropriate trigger point, as shown in this example, based on defining the device-pixel ratio:

<img src="small-image.png" srcset="small-img.png 1x, med-img.png 2x, lrg-img.png 3x"> 

Here, the src attribute acts as fallback image for those browsers that do not support srcset (although support is now very good!). The srcset attribute allows us to specify different images to use, either based on the device-pixel ratio or the available viewport:

<img src="default.png" srcset="small.png 256w, med.jpg 511w, large.jpg 640w"> 

In this case, our fallback is default.png; however, if the browser being used supports srcset, then it will display small.png at 256w or med.png at 511w. If, however, we wanted to change the size and use different images based on the available viewport, then we would have to add an extra attribute—sizes. It's easy enough to configure, so let's pause for a moment to see what this means in practice.

Exploring the sizes attribute

When adding pictures as part of the content on a responsive site, the images may each take up 100% of the element width, but the content itself doesn't always take 100% of the width of the window! For example, we might set each image element to 100% width (so they fill their parent containers), but that the overall content on screen only fills 50% of the available screen width.

To overcome this, we need to know the URLs for the various images to use, along with the width of each image resource; we can't get this from standard markup in the page layout, as images start downloading before CSS is applied.

Instead, we can simply set suitable widths within our HTML code using the srcset attribute and suitable width descriptors. This is a little controversial for some, as it starts to blur the divide between HTML markup and the CSS presentation layer. This aside, let's take a look at an example of how we can set up the code:

<img src="img/orchid.jpg" sizes="50vw" srcset="img/orchid.jpg 200w, img/orchid-2x.jpg 400w, img/orchid-hd.jpg 600w"> 

In this excerpt, we set a default of 50% or half of the viewport width; the browser can then select the appropriate image to display, depending on the available width.

Manipulating the HTML5 <picture> element

We've covered two key parts of making images responsive, but to bring it all together, we can use the HTML5 <picture> element, which has garnered good support in most browsers:

The <picture> element uses this syntax:

<picture>
   <source media="(min-width: 60rem)" sizes="(max-width: 500px) 50vw, 10vw"
   src="high-res-image-2x.png 145w ">
   <source media="(min-width: 35rem)" src="med-res-image.png">
   <source src="low-res-image.png">
   <img src="fallback-image.png" alt="Non-supported browser.">
   <p>Text to display</p>
</picture>

In this extract, we've tied together all of the various attributes we can use with the <picture> element; in this case, we've specified media queries (one of 60rem and another of 35rem), and that if our viewport is only 50% or less (indicated by the 50vw value in the code), we display the normal images; if it is higher, then we display the high-definition images (as specified by using the 100vw value).

Note

We will explore how this works in more detail, in Exploring what happened, later in this chapter.

Putting it all together

Now that we've seen all three elements in use, let's pull them together and create a simple demo that automatically adjusts which image to use, based on the available viewport. For simplicity, we will concentrate just on the image, but there is nothing stopping us from developing this further into a full-sized page!

Let's make a start. For this demo, I would strongly recommend using Google Chrome if you have it installed; its device mode is perfect for this task!

  1. From a copy of the code download that accompanies this book, go ahead and extract copies of the four landscape images, and save them to the img folder at the root of our project area.
  2. Next, fire up your text editor, and add the following code:
            <!DOCTYPE html> 
            <html> 
            <head> 
            <title>Adding responsive images with the <picture> element</title> 
            </head> 
            <body> 
              <picture> 
                <source media="(min-width: 800px)" sizes="(max-width: 1000px) 
                100vw" srcset="img/high-res-image.png 738w"> 
                <source media="(max-width: 799px)" sizes="(max-width: 600px) 
                100vw" srcset="img/med-res-image.png 738w"> 
                <img src="img/fallback-image.png" alt="Human"> 
              </picture> 
            </body> 
            </html> 
    
  3. Save this as pictureelement.html at the root of our project folder.
  4. Go ahead and preview the results of the file in Google Chrome (or another browser if preferred). Make sure you switch on that browser's device/responsive mode.

If all is well, we should see the image flip between two similar versions; to identify which is which, I've added the words High Resolution Image on one, and Medium Resolution Image on the other image used:

Putting it all together

This is the same image, but this time using the medium resolution version:

Putting it all together

Although this demo may look simple at face value, it is deceptive. We have the power to construct some complex statements, which can automatically select an image based on a number of criteria! It's important to understand how this demo works, as a basis for using it for complex examples. Let's take a moment to explore it in more detail.

Exploring what happened

If we take a look through our picture element demo, the code used may initially look complex, but is simpler than it looks! The key to it is understanding each part the <source> statements and how they interact with each other. Let's tackle the first one:

  <picture> 
    <source media="(min-width: 800px)" sizes="(max-width: 1000px) 100vw" 
    srcset="img/high-res-image.png 738w"> 
    ... 
  </picture> 

In this one, we're specifying high-res-image.png as our source image; this will only be displayed when our browser window is showing a minimum width of 800px. The size of the image will either go to a maximum of 1000px or 100vw—the latter equivalent to 100% width of the available viewport space. The 738w against the image is just the width of the image specified in the code (1w unit is equal to 1px, so our image is 738px wide).

Moving onto the second source statement, we find it shows a similar set up, but this time the media query is limited to a maximum width of 799px, and that the size of the image will go to 600px or the full width of the viewport, depending on its current size:

<picture> 
  ... 
    <source media="(max-width: 799px)" sizes="(max-width: 600px) 100vw" 
    srcset="img/med-res-image.png 738w"> 
    <img src="img/fallback-image.png" alt="Human"> 
  </picture> 

To finish off the <picture> element, we specify fallback-image.png as our fallback for those browsers that have yet to support this element in HTML5.

Note

We've only scratched the surface of what is possible with the <picture> element; for more details, take a look at the site maintained by the Responsive Images Community Group, hosted at https://responsiveimages.org/.

Creating a real-world example

We've explored the theory behind making images responsive with a couple of useful techniques; it's time we got practical! The basis for our next demo is going to look at making a responsive map using Google Maps.

Responsive maps, I hear you ask? Surely this should come automatically, right? Well no, it doesn't, which makes its use a little awkward on mobile devices. Fortunately, we can easily fix this; the great thing about it is that it only requires a little additional CSS:

  1. Let's make a start by browsing to http://maps.google.com, then entering the zip code of our chosen location; in this instance, I will use Packt's UK office, which is B3 2PB.
  2. Click on the cog, then select Share and embed map, as shown in this screenshot:

    Creating a real-world example

  3. In the dialog box that appears, switch to the Embed map tab, then copy the contents of the text field starting with <iframe src=....
  4. In a copy of the code download that accompanies this book, extract a copy of googlemaps.html in your favorite text editor, and add the <iframe> code in between the google-maps div tags.
  5. Next, add the following CSS styling to a new file, saving it as googlemaps.css:
        #container { margin: 0 auto; padding: 5px; max-width: 40rem; } 
        .google-maps { position: relative; padding-bottom: 60%;overflow: 
        hidden; } 
        .google-maps iframe { position: absolute; top: 0; left: 0; width:
        100% !important; height: 100% !important; }    

If all is well, we will see a Google Maps image of Birmingham, with Packt's office marked accordingly:

Creating a real-world example

At this point, try resizing the browser window. You will see that the map resizes automatically; the CSS styling that we've added has overridden the standard styles used within Google Maps to make our map responsive and accessible from any device we care to use.

Taking things further

Throughout the course of this chapter, we've followed the principle of using just a browser and text editor to construct our code. This, of course, included not downloading anything that was core to creating our examples (save for media and content).

There will be times though when this approach is not sufficient, we may find we need to avail ourselves of additional support to get a job done. Our overriding question should always be to check that we really need it, and that we're not just being lazy! If when answering that question, we do find that need additional help is needed, then there are a number of sources you can try out, to help take things further:

  • It goes without saying, but there will come a time when we need to resort to using jQuery (http://www.jquery.com) to help within our development. The state of responsive design is such that we should only need jQuery to make it easier to reference elements in the DOM, and not to make images or content responsive!
  • The Responsive Images site hosted at https://responsiveimages.org/. We covered it briefly at the end of the <picture> demo, but it's worth pointing it out again. It's a useful compendium of material to help understand and use the <picture> element.
  • The developer Scott Jehl created a polyfill for <picture>, to extend support to those browsers that do not support it natively; you can download it from https://scottjehl.github.io/picturefill/.
  • Are you in need of a responsive carousel? There are plenty available online, but one which I've found to work well, is ResponsiveSlides, available from http://responsiveslides.com/. Granted, the project is a few years old, but this particular plugin keeps things nice and simple, which is very much in keeping with the theme for this book!
  • A good example of where responsive capabilities are already present is in using the SVG image format. These are effectively vector-based images that we can manipulate using CSS; the key benefit though is that SVG images can automatically grow or shrink, with no loss of quality. Browser support for the format is excellent, although IE (and Edge) both have a couple of quirks that require attention when using these browsers (for more details, see http://caniuse.com/#feat=svg).
  • Another idea to try is with responsive icons. A good example that is worth a look is the FontAwesome library, available from http://fontawesome.io/. These will resize equally as well. In this instance, they would be perfect for smaller images, such as credit card icons or shopping baskets on e-commerce sites.
  • Taking things even further afield, how about support for the WebP image format? Yes, this is one that hasn't gained huge support yet, with it being limited to Chrome and Opera at the time of writing. However, when used with the <picture> element, it shows off a nice trick:
        <picture> 
            <source type="image/webp" srcset="retina-image.webp 2x, 
            image.webp 1x" /> 
            <img srcset="retina-image.jpg 2x" src="image.jpg" 
            alt="an image" /> 
        </picture> 
  • In our example, the browser will check for WebP support, if it can support it, it will display the appropriate image in WebP format, depending on what device-pixel-ratio is supported on the device being used. If WebP isn't supported, then it will fall back to using JPEG (although this could equally have been a different format such as PNG).

There are certainly things we can do, once we've become accustomed to working with responsive images, and want to graduate away from just using HTML5 and CSS3. It is important to note though, that there are a number of projects operating online that aren't listed here.

The main reason for this is age—support for responsive images was patchy for a while, which meant a number of projects appeared to help provide support for responsive images. Support for the <picture> and associated elements is getting better all of the time, which reduces some of the attraction of these older projects; it is worth considering whether it is sensible to use them, or if the impact of not using them can be mitigated by changes to the user experience.

Okay, let's move on; time to get a little animated, I think! Alright, that was a terrible lead in to our next topic, given that we're going to explore making videos responsive. Over the next few pages, we'll see that although some of the same principles apply here, there are some bumps along the way, which might impact our journey.

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

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