Hands-on Responsive Web Design 2: Responsive Images and Sliders
-
Introduction -
Hello and welcome to another hands-on project from Paul Cheney. This is the second in a series of four in-depth courses on responsive web design. In this course we will focus on responsive images and image sliders. In this module we will review what you can learn from this course to make sure you're in the right place. We will look at the archeology template you will use for this course. Then we will review the smart and dumb browser list, set a target for page speed, and have an in-depth discussion about CSS pixels and dots of light. If you know how to build an image that responds to the browser width, but you want to learn how to use multiple images instead of single one, then you're in the right place. If you've heard about pixel density, but don't quite understand it, then you've found the right course. If you're interested in delivering an image that is appropriate to the pixel density of the end user's device, then I have some valuable information for you. To be successful in this course you should have some web development experience with HTML and CSS. It may also be helpful to have access to and know your way around Photoshop. If you don't have Photoshop, that's okay; I will provide all of the images that you're going to need. It will also be very important to have mobile devices to test your work. Here's the fully responsive template we will be using for this course. It is built on SASS so we will be using a CSS preprocessor as we update the CSS. In each module we will do something a little different in the content area. As we move through this course, I will be testing my work on lots of different browsers and devices. I have some older technology, which I will refer to as dumb and newer technology which I will refer to as smart. Our goal will be to get our site look as good as possible on all of these. As we implement new technologies, we will be sure to provide a fallback position for old browsers. Unfortunately, the average page size keeps rising every year. Right now it's up over 2000k; however, we are going to responsible developers and try and keep our designs under 500k. This will make our smartphone users very happy. To understand the why of responsive images and using source set to display different images, we need to understand several important concepts. Let's look into those next.
-
Pixel Density
First let's talk about an LCD. A liquid crystal display is a tiny source of light. On your smartphone they come in groups of three. One is red, one is green, and one is blue. Sound familiar? Hex codes are numbers that control the brightness of each color. The individual red, green, and blue lights on your phone are so tiny that we cannot see them individually. Therefore when these colors are mixed, we see a combination color, which in this case is pink. Here we see a grouping of six sets of red, green, and blue LCDs. I will refer to each of these six groups as a single dot of light, which can be controlled by a Hex value in your CSS or an image on your website. The screen on your phone is made up of thousands of dots of light in a grid of rows and columns. Now we need to talk about CSS pixels and device pixels. CSS pixels is the number reported by the device that tells how wide the browser window is. This number has nothing to do with the actual width of the screen or the actual number of dots of light that are between the left and right edges of the device. For example, my old iPhone 4 reports that the screen width in portrait mode is 320 pixels wide, as long as I include a meta tag that instructs the browser now to lie about its width. Many people find the term device pixels to be confusing so I'm going to use a term dots of light instead. For example, my old iPhone 4 has 640 dots of light between the left and right side of the screen. Now let's talk about pixel ratio. In my possession I have an iPad 2 and an iPad 4. The older iPad reports a CSS pixel width of 768. The newer iPad also reports a CSS pixel width of 768. There are 768 dots of light between the left and right edges on the older iPad 2 while there are 1536 tiny dots of lights between the left and right edges of the newer iPad 4. If you do the math on that, you can see that the newer iPad has twice as many dots of light as reported CSS pixels so we refer to the newer iPad as 2x or we say it has a pixel ratio of 2. The older iPad is a 1x device or we say it has a pixel ratio of 1. Now the math is not always that clean. For example, my iPhone 6 Plus reports a CSS pixel width of 414 pixels, while the actual number of dots of light between the two edges is 1080. So if you divide 1080 dots of lights by 414 pixels you get 2.608. Since this is closer to 3 than 2, the iPhone 6 Plus will report its pixel ratio as 3 even though it's not completely true. So what about your device? If you'll grab your phone, tablet, or even favorite browser and open up mydevice.io, it will you everything you want to know. In my desktop monitor I have a CSS pixel width of 1920 and a pixel ratio of 1. Well on my iPhone 6 I have a CSS pixel width of 375 and a pixel ratio of 2. If you scroll down to the bottom of this page, there is a link there to show other devices. This page shows even more details about lots of different devices you may not own. Here you can see the CSS pixel width and here we have a column for physical width, but it's really reporting the dots of light between the left and right sides of the screen. Over here we have the reported pixel ratio. Notice that there are some really nice 4x devices by LG and Samsung. Now I apologize in advance for showing all Apple devices in this course, but I only have so much money and I can't buy everything. To test the browsers that do not understand responsive images, I have an iPad 1, an iPhone 4, and Internet Explorer. To test browsers that do understand responsive images and have a resolution of 1x, I have my desktop computer. To test 2x images I have my iPod Touch and iPhone 6. To test 3x images I will use an iPhone 6 Plus. I don't own a device that has a pixel ratio of 4x, but the principles are the same. So why are we making such a fuss about pixel density? Well, it's because we want to deliver the perfect image with just enough resolution to look good without being any larger than absolutely necessary. We can also deliver landscape or portrait image and finally we can deliver a wider image, depending on the width of the browser window. In this module we discussed who would benefit from this course. We showed the template and listed some of the devices I would be using. We set a target of 500k for page size and discussed CSS pixels. In the next module we will build the archeology site and show you a foolproof method for a basic responsive image.
-
Background and Scaling Images -
Hello and welcome back. In this module we will add a background and a scaling image that work on all smart and dumb browsers. We will review the sizes for the header background image and then build four graphics in Photoshop; we'll then add them to our sample page. Then we'll build an image for the content and then add it to the main part of the page. Finally we will test our work on smart and dumb browsers to see how well it works. In the header of the archeology site we are going to use a CSS background image to display the appropriately sized image for the small, medium, and large screens. In the demos for this unit there is a sunset.jpg file that I will be using. Before we can build our header graphic we need to know the size for each image. As you can see from the styles.scss file, the breakpoint between the small and medium screen is 35em or 560 pixels when you multiply by 16. The breakpoint between the medium and large screens is 64em or 1024 pixels. Using these numbers, we will create three different images. The first image will be 560 wide by 110 tall and show on all screens less than 35em in width. The second image will be 1024 wide by 130 tall and show on all screens between 35 and 64em. Notice that I want the header to be taller on the tablets than the phones because I have a little bit more screen real estate. The third image will be 1600 pixels wide by 130 tall and show on all screens greater than 64em in width. We will blur this image on the right side and create a repeatable image that if someone has a screen wider than 1600 pixels it will still look nice. I want to use this setting sun as a point of focus in the header and eventually place a logo on top of it. So as I build these graphics in Photoshop, I'm going to allow 150 pixels of space at the left and place the sun in that general area. Now let's jump over to Photoshop and build these four graphics.
-
Building the Background Header Images in Photoshop -
Inside the demos for this module you have a copy of the sunset.jpg file, which I'm going to open in Photoshop. The header image for our small screens is going to be 560 pixels wide by 110 pixels tall. So I'll create a generic image and then I'll view new guide and 150 pixels from the left side. I'm going to be positioning the sun right here in this area. Return to sunset, select it all, paste it, and we can barely see that upper left corner. Let's zoom out and make sure we have the move tool selected, and there's the sun. Click and zoom back in, and I'm going to position the sun and the landscape something like that. So it sort of fades off here to the right and there's the sunshine over there. I'll save it as header0560 pixels. Stick it out here on the desktop. We'll leave the quality at 12 because I'm going to use a different program to actually compress my images for the web. And there we can see our first image ready to go. That one's done. Let's create a new file. This time the width is 1024. The height I'm going to increase to 130 pixels because I have more screen real estate on a tablet. Once again I'll insert a guide at 150 pixels over and my sunshine will appear over here. I'll select everything, copy it, drop it in place. Now this time I'm going to move the sun over here to the right just for artistic purposes, drag it up just a little bit. If you look really closely at the right, you can see this image is pixilated. I'm going to run a filter, blur, Gaussian blur on it. And I'll change my radius to 0.3 so it's very, very subtle. That'll help with the compression as well as blending out that sky so it's not quite so pixilated and now I'm ready to save as. Header, and then I'll use the width, switch it to a JPEG, use lots of quality, and that image is now ready. We'll close that one down. We'll do another new image. This is going to be for the widest possible screens so we'll make it 1600 pixels wide and we'll keep the header at 130 pixels tall. We'll add a new guide at 150 pixels and once again position our sun over there, select it all, copy it, and drop it in place. Drag it up and put the sun somewhere over there and close my layers palette and you can see I have a gap over here on the right. So we're going to use a little bit of Photoshop trickery so that the right side of this image looks very similar to the middle of the image where it fades to complete sky and doesn't have any mountains showing, and we can see that right here in the middle between this point and this point it's all sky. So let's just randomly choose a spot in here and let's measure how far it is from there to the right side and we can see it's around 850 pixels. Half of 850 is 425 so let's go over 425-ish and we'll drop in another guide. So let's copy this section here in the middle where it fades from no mountains to a little bit of mountains and we'll copy that. We've now got that second layer. I'm now going to move that directly to the right and we'll line it up so that it snaps into position right here around this guide. Now we're going to take the newly created layer 2 and we'll do edit, transform, flip it horizontally, and now the blend area between this side and this side is completely indistinguishable; you can't tell, and we now have an image which ends at the right by fading completely out. So now we have a nice header that's going to have a blendable right edge. Now as we did before, let's flatten these two together and then let's run a blur, Gaussian blur, and we'll use the 0.3 that we did before, and now I want to make the right side of this even more blurred than it is currently. So I'm going to copy a section here of the right side and just paste it exactly above itself and then I'm going to do filter, blur, Gaussian blur and this time I'll put a nice big value like 2. You can see how much softer that is over here at the right side. We've now introduced a problem in that over here we have a regular image and it instantly fades to this fuzzy stuff, which I don't want. So now I'm going to layer, layer mask, and I'm going to hide all of that image and then I'm going to run a gradient from black to white and I'll start at the left edge, hold the Shift key down, drag straight to the left, and now you can see that that is a transition between no blur and 100% blur here at the right side. If we now file save as, header, 1600, make sure it's a JPEG file, and put it out there on the desktop with the other two. Let's go ahead and flatten that image and then we'll do an image canvas size. What we're going to do is keep a very thin sliver here from the right side to repeat over and over and over, if the browser happens to be wider than 1600. So let's take say 2 pixels from the right side and keep it and now we have a 2 pixel repeatable image for the header. Let's save that as header, repeat. And once again we'll make sure it's a JPEG image. So here on the desktop we have our small screen header, our medium screen header, and our large screen, which is combined with this image if the browser window happens to be wider than 1600. Now I have a program called JPEGmini Lite. You can get a free version which will do a few compressions every day. I use it a lot so I've actually paid the few dollars to purchase it and it is available for Mac and Windows. You simply take your images, you drag them over, and it replaces them with newly optimized images and you can see here I've reduced the size by 2.3 times. Let's now open our start file and in the images folder we'll drag all four of those.
-
Adding the Header Background Image in the CSS -
Now let's drop in the CSS to make this work. Remember we are using a CSS preprocessor so I've opened up my Koala app and I'm going to take my start folder, which I've got on the desktop, drag it into the left-hand pane and make sure that I set the output to the CSS folder and replace the styles.css that's already there. So now that that's running, I can open my editor, drag my start folder to the left-hand pane to make sure it's the currently loaded project and then open index in a browser. In this small default, the first thing I'm going to do inside the header is set my height. So in this case I'm actually going to set it to 110 pixels so that it always matches the height of the source graphic that's going in here. I'm also going to load the background image. It will be loaded from a URL and I have to go dot, dot, slash to get the correct folder up and the first one will be the 0560 for the small screen. Notice that it's repeating as we make our screen wider. It really doesn't matter because as soon as we change our browser width beyond 560, I'm going to change this graphic out. Now the only other problem is our h1 and h2 are not in the proper position. So let's slide them over by setting our margin-left to 150 pixels, which is what we designed when we went into Photoshop and that kicks them over there and in the next unit I'm actually going to stick a logo right in here. Now I don't want them up that high so I need to bring them down from the top. So down here on my h1 I will set the padding-top to 35 pixels and reload it and there it is. Now the small screen is taken care of, let's jump over and fix the medium. Here in the header we'll set the height at 130 pixels. We'll also load the second background image which is the second one we've created, header 1024. Let's save it and hit refresh. We can see it got a little bit taller. We'll change the h1 padding on the top to 50 pixels and there it slid down. Remember, we are using nesting here. So the h1 is nested inside of the header, which means when it writes it out, it will put header space h1 in the padding top. Let's now make our screen wider. Here you can see that we've now crossed the boundary between medium and large. Here in our large SCSS file. We'll set up our header. In this case we're going to do a double background image and we'll do that by separating them with a comma. We can see that the top image is repeating once we shrink down small enough that we can see the 1600 breakpoint. So in addition to loading both images, we also have to tell the first one to not repeat and the second one to repeat and we'll do that by setting background-repeat no-repeat, comma and then repeat only on the x axis. Save it and refresh it again. Now you can see that that repeated image is being replaced by a banding of the color of our sunset starting from the end of the 1600 image and moving to the right. So now no matter how wide someone makes the site, the header image is going to look great.
-
Building and Adding the Scaling Body Image -
Now that the header graphic is done, let's place a scathing image in the content part of our page. In small screens the image will be full width. In the medium and large screens the image will be one-half the width of the page. So how large does this image really need to be? Well, that depends on the widest possible desktop screen. Currently we do not limit the overall page width, but we probably should. For the purpose of this lessun we will limit the overall page width to 1600 pixels. Since the breakpoint for the small CSS ends at 35em or 560 pixels, the maximum needed for the phone is 560 pixels. The breakpoint for medium screens is 64em or 1024 pixels, and since the image is half the screen, then the maximum needed there is 512. Since we have limited the overall page width to 1600 pixels and the image is going to be half the screen, the maximum size needed for the large monitors is 800 pixels. Since we are using one image for all three displays, we will build our image at 800 pixels wide. This way the image is never pixilated. In the demos for this module you have an image named templemount.jpg which I will use. Let's jump into Photoshop and then into Brackets for the HTML and CSS. Here in the desktop I've copied by templemount.jpg and I'm going to open that up in Photoshop. If we click on image and image size we can see that the current width is way over 3000. All we need is 800 pixels in width so let's click OK and save the image. I'll put it in my start folder inside the images folder along with the other four and I like to keep my case at lowercase. Currently I'm going to leave the quality at 12. We'll check the size and then reduce it from there. Since we no longer need the master file, I'll dump it in the trash. As you can see, this current image is 432kb which is not bad, but remember our target for the entire page is 500 and so that image alone is almost taking up all of our 500k. So I'm going to open up a program called JPEGmini Lite which you can get on Mac and Windows, it is free. Drag the image in. It will automatically reduce it while maintaining optimal quality. Now we can see that it's dropped all the way down to 207kb, which is less than half of what it was. Now we're ready for the HTML and CSS. I've loaded the start file which is here on my desktop into the left- hand pane of Brackets. I have also loaded the index file into my browser. Let's start by opening the index.html. So down here on line 43 we're going to start by adding a figure tag. You could use a picture tag, but the figure tag has better support. Inside the figure tag let's add an image and we could even add a figcaption. Refresh it and there it is. Notice that the image is its native size of 800; it does not scale to fit the page and if I shrink the image, it is chopped off on the right side. I do have my CSS preprocessor running so I can open up my SASS file and open up the small and down here in the content area I'll go ahead and add a figure and I'll set its width to 96%. I'll then add a margin left of 2%, but if you remember, in our variables, we have a gutter variable already set up, which has a value of 2%. So in my small I will simply do margin-left and go ahead and use that variable and that will be 2%. Now if the left margin is 2% and the image is 96%, the total is 98% which should leave a right side margin of 2%. Now this is not complete and let's see what we get when we refresh. We have the left margin like we're supposed to, but it does nothing to scale the image. Well, why is it not working? To identify why it is or isn't working, let's set a border. We'll make it red, we'll make it 2 pixels, and we'll make it a dashed line which is really totally ugly, but you can see the dash and it comes right down here and as we make it wider, you can see that there is a 2% margin right there and a 2% margin right there. So the figure is actually doing exactly what it's supposed to, but the image is not scaling to fit the figure. So that requires the second piece of code. Figure, image, width, 100%. So the image will always be 100% of its containing element and we'll save that and we'll refresh it. You can see that the image expanded to fill that space and as we shrink our screen, the image shrinks accordingly. Now if the image was supposed to be 100% wide on all screens, we would now be done, but it's not. It needs to be half the width on medium and large. So let's come back to our medium now and down here in main we'll set the figure and we'll give it a width of 50%. Save it and now we can see that as soon as we cross that boundary between small and large, the image shrinks to half and it maintains its half width all the way up. Now remember we were going to limit the overall page width to 1600 so that even if someone was using a massive monitor, this image wouldn't grow and grow and grow and eventually become pixilated. So down here in main, we'll set the max-width to 1600 pixels or we could pull up our calculated, take 1600 and divide that by our base font of 16, which would give us 100em. Now we can't really see that so let me make some more CSS changes. Let's take our main and let's put a border around it and now we can see the orange border around the main and we can see that the image shrinks and as soon as we pass that 1600 mark, it no longer enlarges our image. Now typically what we do is we put an image and we wrap text around it so let me grab some filler text here. Back to our index and we'll wrap each of these in paragraph tags and now when we refresh it, we have text on the top and the image below, but since I want the image to wrap around the text, I'm going to have to move the figure up above the paragraphs. So it should be the photo first followed by the paragraph text. And to make the styling look decent, we're going to come in here to the paragraph and we'll set a margin of 0 top and bottom and then we'll use the gutter variable for the left and right sides. That should now push the paragraphs in to exactly match the picture. So let's start with our small screen. This is how we want it to look minus the red border. So let me get rid of this, save it, and there it is. As we now cross into medium we want the image to float to the right. So let's go to our medium and down here in the figure where we set the width to 50%, we'll now float to the right. And now it's popped over there and you can see it's touching that 2% border on the main and as we widen it, it becomes very clear that our 2% margin on the left looks great. Our 2% margin on the right is being violated by the image because it's now floated to the right. So in addition to floating it to the right, we need to do margin-right and of course we'll use the gutter variable. And now we can see a nice 2% margin there to match the 2% margin on the left and as we continue to widen our page, it now slides over so that we have a bigger margin on the right than on the left. So in the main where we limit the maximum width we can also set the margin to 0 top and bottom and then auto, which really means center. And when we hit refresh, the margin on the left and the margin on the right are now identical.
-
Testing the Page -
In order to test this on all my different devices and browsers, I need to upload my start file to a sandbox which I have on one of my websites. I'm going to use a program called Cyberduck; it's free for Mac and Windows and I've opened my sandbox folder and I simply drag the start file over there and after a couple seconds, it uploads. Let's take a look at how the background image and the scaling image are doing on smart and dumb technology. In this case I will only show the older dumb technology because if it works there, it will also work on the newer stuff. Here are the results of our work on an old iPhone 4. Notice how the image scales to fit the smaller screen. Here are the results of our work on an old iPad 1. Here are the results of our work on Internet Explorer 7. Yes, it works all the way back to 7. Of course it works on all other modern browsers like Opera, Firefox, Safari and Chrome. On our page speed test we're getting an 88%, which is not bad. We're also getting a page size of 285kb which is well below our target of 500. And finally, we pass the mobile friendly test. In this module we reviewed the sizes for the header background image and then built four graphics in Photoshop. We then added them to our sample page, then we built an image for the content and added it to the main part of the page. Finally we tested our work on smart and dumb browsers. Now that we're done with scaling an image, let's build a logo that loads based on device pixel density or dots of lights, as we discussed in the very first module.
-
Pixel Density Logo -
In this module we will create a logo that displays appropriately based on the pixel density of the end user's screen. First we will identify the logo sizes needed for a 1x, 2x, and 3x screens. Next we will build three graphics using Photoshop and then we will add that image to our archeology page header. Finally we will test our page on smart and dumb browsers. In the demos for this unit you have a tree logo.tif file which I will use to create our logo as well as a copy of the start folder containing the HTML, SCSS, and images used for this module. In the header of our site we will place a logo so that it has a left- hand margin of 2% and is 100 CSS pixels in width and height. Yes, it will be square. On a 1x screen, an image with a CSS width of 100 pixels is displayed with 100 dots of light or device pixels. Therefore we will need a logo that is 100 Photoshop pixels wide and 100 Photoshop pixels tall. On a 2x screen, an image with a CSS width of 100 pixels is displayed with 200 dots of light or device pixels, therefore we will need a logo that is 200 Photoshop pixels wide and tall. On a 3x screen, an image with CSS width of 100 pixels is now displayed with 300 dots of light or device pixels, therefore we will need a logo that is 300 Photoshop pixels wide and tall. I sure hope this is making sense because now we're going to open Photoshop and create these three logos.
-
Building the Different Sized Logos -
First we will open this logo in Photoshop. Notice it is black on a white background. To remove the background we will use the magic wand. Set the tolerance to 32 and make sure there is not a check next to contiguous; click the black tree trunk to select an anti-aliased version of the tree. Copy and then paste. Now let's check our logo against a colored background by filling the bottom layer with red. As you can see, we have a nice tree with no ghosting. Save this as a Photoshop file on your desktop. Now choose file, generate, and make sure there is a checkmark next to image assets. With that turned on, let's change the name of the layer to 100x100, space, logo1x.png. The first value is the output size in pixels and the second value is the name of the file and the file type. If we look at the desktop, we now have a new folder called treelogo-assets. Inside that is a png file that is exactly 100 pixels square. We now have a logo for 1x screens. Now let's modify the layer name to include the other two images we need. We next add a comma and then 200x200, space, logo2x.png followed by a comma and then 300x300, space, logo3x.png. Now when we look in the assets folder we have three logos, each at the appropriate size. Let's now move these into the images folder.
-
Adding the Logos to the Web Page Header Using SRCSET -
Let's take a look at the HTML for the logo. I'm going to place the logo inside a figure tag with the class name of logo. This is not necessary, but I like to be consistent by placing all images either in a figure or a picture tag. Next we'll add the standard image tag with sources equals logo.png, which does not exist yet. For the purpose of this tutorial we will include a different default image so you can see the change on smart and dumb browsers. Normally you use one of the SourceSet images. Now let's add the SourceSet code. Between the quotes we specify an image and its associated pixel ratio. Each image and pixel ratio is separated by a comma. If our browser understands SourceSet then one of these images will be shown in place of the default image based on the device pixel ratio. Now let's jump over to our code editor and add the logo. Before we jump into Brackets, let's duplicate the 1xlogo.png and rename it logo.png. This logo will be shown on all dumb browsers. Now let's open Brackets and make sure we are working on the start file from module 3. Inside the header tag let's add a figure tag. Inside the figure tag, add the image tag with a path to the default logo for dumb browsers. Now we can add the SourceSet code for 1x, 2x, and 3x devices. In the CSS for the small screens we need to position the logo to the left so the company name appears to the right. We'll do this with position absolute and bottom and left. Now I can see you're having some doubts about whether this is really working or not so let's tag each of these graphics so we can see the difference. Let's open all four of these logos in Photoshop. We'll change the color of the default logo to red so it's easy to identify the dumb browsers. Let's add a small 1x to the small version. We'll now save and close this image. Let's add a 2x to the medium version and we'll now save and close this image. And let's add a 3x to the largest version. We'll now save and close this image. Finally I will upload this entire folder to my sandbox for testing purposes.
-
Testing out Site on Multiple Browsers and Devices -
I will begin testing SourceSet with an iPhone 4. The result is a complete failure as we see the red logo. This browser does not understand SourceSet at all. The iPad 1 is a similar disappointment. Here are the results of our work on Internet Explorer 10. Yes, we are having a browser meltdown and a total failure here as well. Now let's move to the other modern browses like Firefox, Chrome, Safari and Opera. As you can see, we are displaying the 1x logo properly. Now let's try an iPhone 6. This device has a pixel ratio of 2 and the 2x version of the logo is being shown. Now let's try an iPad 4. This device has a pixel ratio of 2 and the 2x version of the logo is being shown. Now let's look at my laptop which has a retina display. The device has a pixel ratio of 2 and the 2x version of the logo is being shown. Now let's try an iPhone 6 Plus. This device has a pixel ratio of 3 and the 3x version of the logo is being shown. Now let's try a Galaxy 6 I borrowed from my daughter. This device has a pixel ratio of 4, but the 3x version of the logo is being shown. Remember that this is because we did not actually create a 4x version of the logo. The typical viewing distance for a smartphone is about 12 inches from your eyes. Can people really see the difference between a 1x and a 2x logo or between a 2x and a 3x logo? At what point do we say enough is enough when it comes to making different logos for different screen densities. To answer this question let's do a cost/benefit analysis. What are the benefits of creating multiple logos for different pixel ratios? If they ever project their phone onto a large screen then an appropriate logo would look much better. An logo is important and seen on every page so it really should get special attention. Logos are typically small in size so there's very little impact on bandwidth. The largest 3x used in this tutorial is only 25k. What are the costs of creating logos appropriate for the screen density of the device? If you have Photoshop then it takes about 5 seconds to type a comma and the size of the new logo and the name. Photoshop takes care of everything else. The HTML code is also easy. You add a SourceSet line to an existing image tag and you're done. This may take another 10 seconds of your time. So my recommendation is to do it, at least up to a 3x. Any more than that may be overkill. So let's wrap up this unit on responsive logos by reviewing what we have learned. First we identified the sizes we would need based on our design. Then we looked at using Photoshop to easily create the graphic logos. Next we added the code to our HTML and finally we tested our logo on multiple browsers and devices. We decided that it was so easy to build multiple logos that we should definitely do it. Now that we're done creating multiple logos, let's look at responsive images in the content part of our site.
-
Similar Sized Responsive Images -
In this module we will build a responsive image for the content part of the page. First, we will determine the maximum size image needed for all three displays; small, medium, and large. Then we will use Photoshop to automatically build these images for us. Next we'll add the image to our HTML page and finally we'll test our work on multiple browsers and devices to see how well it works. In the demos for this module you have a copy of this image or you could use one of your own. We will be creating multiple versions of this image using Photoshop. My image is 2500 pixels wide, which should be large enough for all the different versions we will create. If you're using one of your own, make sure it's at least 2000 pixels wide. Here we have a linear representation of the breakpoints for our CSS. Let's convert these to Photoshop pixels. In the small screen our image will be 100% of the screen width, which means it will display starting at 320 pixels and never grow larger than 560 pixels. In the medium screens it will display at 50% of the page width, which means it will display starting at half of 560 which is 280 pixels and then grow to half of 1024, which is 512 pixels. In the largest screen it will be displayed at 33% or one-third of the page width, which means it will display starting at one-third of 1024, which is 242 pixels, and then grow to one-third of 1600 which is 534 pixels. Using this approach, the image display for all three screens is basically the same size. It ranges between 242 pixels to 560 pixels. As you can see, the largest image we will need is 560 Photoshop pixels wide. So here I have the 1x version at 560 pixels wide. Then we'll build a second version for 2x screens at 1120 pixels wide, and the third image for 3x screens at 1680 pixels wide. We are not going to build a 4x version as that size will be too large for mobile phone users and they may get upset about us burning all their phone data and leave our site. Deciding where to stop is of course your decision. Now personally I never go over a 3x screen. Now let's open Photoshop and build these images.
-
Creating Images in Photoshop -
Let's open Photoshop and build these three different images. The first thing we need to do is make sure our image is at least as big as the largest image we will create. Our maximum image needed is 680 pixels wide and this image is 2500 so we're in good shape. Now let's create the three different versions. First we have 560x336, named shean1x.jpg. Go to comma, then we have 1120x672 named shean2x.jpg followed by another comma. Then finally we have 1680x1008 named shean3x.jpg. Turn on generate assets and save this file on your desktop. Now we can see on the desktop a new folder with the three different images needed. Let's move these images into the images folder of the start file for this module. The start file is located in the demos. Normally this would be the end of our image creation work, but for the purpose of this tutorial, I'm going to add labels to each image. In addition, I will duplicate the smallest one and name it shean.jpg. Then I'll open it in Photoshop, convert it to black and white. This way we can easily identify dumb browsers that don't recognize SourceSet. Let's now optimize all of our images using JPEGmini Lite. Now we're ready to jump into our text editor and build the HTML.
-
Building Newspaper Columns -
Now we're ready for the HTML. I have my start folder loaded inside of Brackets; I have also loaded in my CSS preprocessor so that as I make changes it automatically updates and I have it loaded in my browser. Let's start by going to our index page and adding a section inside of the main tag and we'll actually divide that into three newspaper columns. We'll begin by adding an article and we'll give it a class for multi column and inside of that we'll put three paragraphs. Inside each paragraph I will put some filler text. Here's what it looks like so far, and on our smallest screen it stacks 100% width as it's supposed to. When we move to medium screen we want to divide this block of text into two different columns. So we'll jump to our CSS for that. Inside our medium SCSS file we'll start with an article.multiCol. First we'll set the column count to 2. Next we'll set the column rule, which is the dividing line between the columns to 1px solid and then we'll jump to our variables SCSS file, grab the variable's secondary color and use that for the color. The third thing we'll do is put a gap between our columns and once again we'll go to the variables SCSS file, grab the variable gutter, and use it for the column gap. We open up our browser and there's our two columns from our medium SCSS. Column count, column rule, and column gap are still fairly new. So we need to use browser prefixes to work for older versions of Chrome, Safari, and Opera. For column count, we're going to preface it with webkit and we're going to preface it with Mozilla. For column rule we'll do the same. We'll preface it with webkit and Mozilla. For column gap we also use webkit and Mozilla. Let's save that. Of course, it's not going to make any difference because every browser I'm using is already working and recognizes column count, but if you had an older version of any of these browsers it will still work. I'm going to copy all the work we've done here in our medium CSS. We'll now jump to our large SCSS file and we'll add a main section because we haven't done anything in the main yet and then I'm going to paste that, change the column count to 3 for all three of these. There are no changes to column rule and there are no changes to column gap so we can simply eliminate that redundant code. Let's save it, refresh it, widen our screen, and sure enough we now have three columns on the large screens.
-
Using SRCSET for a Content Image -
Now that we have our newspaper columns working, let's go ahead and drop in the image using the default grayscale image. Here in my index, between the first and second paragraphs is where I'm going to put this. I'll open with the standard figure tag. I'm going to give it a class of photo-pd and inside of that I'll put an image with a source. Let's check our work and the image appears, but notice as I scale it, the right side of the image is actually going beyond the column width. So now we need to make some changes to our CSS. Inside the small default I'll add an article and set it to a margin of .5rem top and bottom and use the gutter variable for the left and right sides. As we refresh it we can see the margin is now kicked over to the more in line with the word excavation. While I'm here in the small default, I'm going to add a figure with a class of photo-pd and set it to a width of 100%. I also need to set the image which lives inside the figure to a width of 100%. So I'm going to combine both of those rules together using a comma. Let's refresh our page and we can see that we have a nice 2% margin there and we have a gap here between the edge of the image and the column. As we reduce our page down we still have our gap until we get all the way down to the smallest, which still has a nice 2% margin on both sides of our grayscale image. Now we're ready to add the SourceSet. Inside the index.html, inside the image tag which currently has a source and an alt, we'll add a third parameter called srcset. Inside the source set we'll put a path to shean1.jpg and set it as the 1x version. We'll then enter a comma and now we're ready for the 2x version so let me copy this, paste it, simply change the path name to a 2 and the display density to a 2. Don't forget the comma separating them and now let's do the 3x version by using a 3 in the image name and a 3 for the pixel density. Let's save that. Hit refresh. Our grayscale image is now replaced by a colorized version which tells us the pixel density of my display is 1x, which is correct. Now that the page is built, we will upload our start file to my sandbox so that we can test it on multiple browsers and devices.
-
Testing Page and Recommendations
I will begin testing SourceSet with an iPhone 4. The result is a complete failure because we see the grayscale image being displayed. The iPad 1 using a Chrome browser is a similar disappointment. Here are the results of our work on Internet Explorer 10 and it does not work. Now let's move on to the other modern browsers like Firefox, Chrome, Safari and Opera. As you can see, we are displaying the color version of the 1x logo properly. Now let's try an iPhone 6. This device has a pixel ratio of 2 and the 2x version of the photo is being shown. Now let's try an iPad 4. This device has a pixel ratio of 2 and the 2x version is being shown. Now let's look at my laptop which has a retina display. This device has a pixel ratio of 2 and the 2x version of the photo is being shown. Here's an iPhone 6 Plus. This device has a pixel ratio of 3 and the 3x version of the logo is showing. Now let's try a Galaxy 6. This device has a pixel ratio of 4, but the 3x version of the photo is being shown. This is because we did not create a 4x version and you'll see why in just a minute. Let's run a speed test on our finished page. We can see that the total page size is 181k. If we scroll down a little bit we can see that the test being run is using the logo 1x with a size of 21k and the shean1x.jpg photograph with a size of 65k. In order to calculate the size of the 2x and 3x versions of our page, we need to get the size of the logo and photograph. Let's enter the path here for only the 2x logo and we can see the size is 56k. Now let's change this to a 3x version and we can see the size is 93k. Next we switch to the 2x photograph and it comes in at 201k. Finally we change to the 3x photograph and that image is 357k. Now let's do some math. If we take the total page size and remove the logo and photo, we have all the other stuff on the page. This comes in at 95k. For the 2x screen we add back the 2x logo and the 2x photo and our page size is now 352k. This is well under our target of 500k; however, when we add the 3x logo and the 3x photo, our total page size is now 545k, which is not under our target of 500k. So should we build multiple versions of a photograph when the image being displayed is basically the same size for all three screens? The main benefit is that it will look better on displays than have more dots of light. The amount of work needed to make all three images is minimal when using Photoshop, the code is simple; you just add a SourceSet attribute to the image tag. As we saw earlier, the 3x version of our page is barely above our target of 500k. Remember, the average page size in 2016 was over 2000 and we are well below that. So in the end you need to ask yourself if providing an image that's a little larger for people who have 3x and 4x devices is really worth it. Now that we've seen the results of our work on different browsers, let's review a real world deployment of an image using SourceSet. First you don't need the default image. In this case it's the grayscale photograph. Its only purpose was to help us learn which browsers do not support SourceSet. What you should really do is use one of your pretty images instead. I typically use the 1x version as the default. The other SourceSet images in your code should remain unchanged. So that wraps up this unit on responsive images. Let's review what we've covered. First we identified the sizes we need based on our design. Then we looked at using Photoshop to easily create those images. Next we added the code to our HTML and finally we tested our image on multiple browsers and devices. In the next module we will explore different sized images using width instead of pixel density.
-
Different Sized Responsive Images
Overview
In this module we will add two different images to the content area of the archeology template using SourceSet and sizes. First, we will use Photoshop to create two different sets of images. Then we'll jump into our text editor and build a responsive image using width and a constant size of 50%. Next we'll add an image using width and media queries to change the display width. Finally, we will test our work and discuss the best use of these techniques. In the demos for this module you have a copy of these images or you can use your own. We will be creating multiple version of these using Photoshop. The first responsive image we create will be 50% of the view width for small screens, medium screens, and large screens. For this we will use SourceSet and the width descriptor. Remember that one of the new CSS units of measurement is vw, which stands for view width. 100vw is the full width of the browser window. For the first project we will create a series of images starting at 200 Photoshop pixels wide and going up to 1200 Photoshop pixels wide. In this example I have increased the width 200 pixels for each new image. This will give me very precise control over which image is being shown. I will also create a grayscale image as a default for browsers that don't understand SourceSet. For the second image we will mix it up a bit. We will display a photo at 100% of the view width on small screens, 75% of the view width on medium screens, and finally 50% of the view width on large screens. This gives us a chance to explore sizes that contain media queries. For this example I will create a series of images starting at 400 Photoshop pixels wide and going up to 1300 Photoshop pixels wide. In this example I have increased the width 300 pixels for each new image. Once again, I'll create a grayscale image as the default for dumb browsers. You remember in the last module we used pixel density and 1x, 2x, and 3x for our images. In this module we'll be using the width descriptor instead. Please use one or the other. Don't try and use them together. Now let's look at the math used to select an image. Some of the information is already known by the browser and the rest we have to supply. First we take the width of the browser window and we multiply it by the pixel density, which gives us the number of dots of light between the left and right sides. Next we multiply by how wide the image is relative to the window and that gives us the minimum image width needed for the display. Let's try this with an iPhone 5 and an image that is 50% of the screen width. The CSS width of the iPhone 5 is 320 pixels. It has a pixel density of 2, which gives us 640 dots of light between the two edges of the browser. We multiply that by .5, which is 50% of the view width. Now we had to provide that information here and now we know that we need an image that is at least 320 Photoshop pixels wide. So we look at our list of images and the first image is less than 320 so we skip it. The next one is 400 wide, which is larger than 320 so that's the one we're going to use. The browser then loads church400.jpg into the display. Now let's jump into Photoshop and get some work done.
-
Image at 50 Percent Page Width
In Photoshop we will open the church.psd image from the demos folder for this module. Once it is open we can figure out the ratios for our different images. If I open the image size and change the width to 200, I can see that the correct height of this image is 120 pixels so I write that down. I can do that for all the other widths as well. Once you know all of your image sizes, height and width, enter them into the layer name. In this example I'm going to create a new image every 200 pixels up to 1200 wide. Remember to separate each different image with a comma and use a space between the size and the image name. Turn on generate image assets and save your file. You should now have a set of images ready to go. Let's duplicate the smallest one and make it grayscale so we can easily identify dumb browsers. Remember to compress all of these images. Once that is done we'll move them over to the images folder. Now let's jump over to our text editor. I will open the start folder in brackets. In the main section of index.html I will add a figure with the class of photoA. Then just for fun I will also add a caption to the photo using figure caption. Inside that I'll add an image tag with a source and an alt. For testing purposes we're going to use the grayscale image as the default value for source. Next we add the sizes attribute set to 50% for all screen sizes. Finally, I will add the srcset attribute with a series of images and their widths, each separated by a comma. Remember, the reason we add width is to tell the browser how wide the image is because it doesn't know. The browser needs to know the image width to perform the calculation to display the correct image. Now let's add a couple of paragraphs of filler text below the image. In the small default CSS, we'll tell the image to display at 100% of the containing element, which is the figure. Then we tell the figure to display at 50% of the browser width. We set the margin to 0 and the variable for 2%. Finally we float it to the right. Now let's style the caption below the photo by centering the text, changing the font weight, and the color of the text. That should do it. Make sure you have your CSS preprocessor running to update your CSS file and test your work in a browser. Now you can see the images have been modified to display the image width. I've provided this set of altered images and the demos for this module if you would like to use those instead of your own.
-
Image at Multiple Page Widths
In Photoshop we will open the Jaffa.psd image from the demos folder for this module. Once it's open we can figure out the ratios for our different images. If I open the image size and change the width to 400, I can see that the correct height is 200 pixels. I do that for all the other widths as well. Once you know all your image sizes, enter them into the layer name. In this example, I'm going to create a new image every 300 pixels up to 1300 wide. Remember to separate each different image with a comma and use a space between the size and image name. Turn on generate image assets and save your file. You should now have a set of images ready to go. Let's duplicate the smallest one and make it grayscale so we can easily identify dumb browsers. Remember to compress all of the images. Once that's done we can move them all over to the images folder. Before we jump into Brackets, let's take a look at how to use multiple entries for sizes. In this example, you can see three different conditions each separated by a comma. The first two contain media query conditions. The last one does not need a condition because it is the default option. All three contain a display width so the browser knows how to calculate the correct image. The browser is going to go over each media query entry starting at the left until it finds a match. Then it will use that information to calculate the correct image size. For this reason they are listed in reverse order. Now we're ready to open up our text editor and go to work. I will open the start folder in brackets and add a heading for Jaffa Boat Dock. Then I will add a figure with a class of photoB. I will also add a caption to the photo using figcaption. Inside the figure I'll add an image tag with a source and an alt. For testing purposes we're using a grayscale image as the default. Next we add three sizes attributes, each separated by a comma. The first is for large screen, which in my case starts at 64em. For that one I will display the image at 50 view width or 50%. The second one is for medium screens which kicks in at 35em and displays at 75vw or 75%. Finally, we have the default small screen option which displays full width. Next I will add srcset attribute with a series of images and their widths, each separated by a comma. These inform the browser how wide the image in Photoshop pixels. Finally, we'll add a couple of paragraphs of filler text below the image. In the small default SCSS we will add photoB to photoA for both the image and the caption. Then we'll tell the figure for photoB to display at 96% of the browser width. We'll set the margin to 0 and the gutter to 2%. Now we'll move to the medium SCSS, set the width to 75% and float the image to the right. Finally we'll go to the large SCSS and change the width to 50%. Make sure you have your CSS preprocessor running and test your work in a browser. Now you can see the images have been modified to show the image width. I have provided this set of altered images in the demos if you would like to use those instead of your own.
-
Testing Page on Multiple Browsers
Let's begin our testing with the iPhone 4. Again, we have the grayscale images showing and the iPad 1 doesn't work either. Once again, Windows 10 displays the default image. Now let's move on to other modern browsers. We're going to look at several different browser widths to see how the calculations are working out. For both images, we have a window width of 500 pixels on a 1x display, which is 500 dots of light between the left and right edges of the browser window. The church image is displayed at 50 view width so one-half of 500 is 250, therefore the 400 wide image is selected. The Jaffa image is displayed at 100% of 500, which is 500, big surprise there; the 400 image is too small so the 700 wide image is selected. Now let's widen our browser window. We have a window width of 900 on a 1x display, which is 900 dots of light. The church image is displayed at 50 view width so one-half of 900 is 450, therefore the 600 wide image is selected. The Jaffa image is displayed at 75% of 900, which is 675. The 400 image is too small so the 700 image is selected. Now let's try my laptop with a retina display. We have a window width of 900 pixels, but now it's a 2x display which is 1800 dots of light between both sides. The church image is displayed at 50 view width so one-half of 1800 is 900, therefore the 1000 wide image is selected. The Jaffa image is displayed at 75% of 1800, which is 1350. Since there is no image larger than 1300, that's the one that's selected. Now let's move on to our mobile devices. On my iPhone 6 we have 750 dots of light. Since half of 750 is greater than 200, the 400 image is chosen. If we scroll down, we see the 1000 version of the Jaffa image because the 700 version is not wide enough. Now let's try an iPad 4. This device has a pixel ratio of 2 and the 800 and 1300 images are showing. See if you can do the math on this one yourself. My laptop with its retina display is showing the image in both cases. On the iPhone 6 Plus we are seeing the 600 version of the church and the widest version of the Jaffa image. On the 4x Galaxy we're bumping up to the 800 wide version of the church. This is because the dots of light is 1440 and half of that is 720 so the 800 image is picked. We still see the 1300 version of the Jaffa image because there's not a larger one available. Let's run a speed test on our finished file. We can see that the total page size is 424k. If we scroll down, we can see the test is being run using the church 800 at 203k and the Jaffa 700 at 104k. As in the previous module, I entered the path to every image in the web speed test page. Here are the results. The numbers in red will end up being too big if we are to stay under our 500k page size limit we set for ourselves. Now let's do some math. If we take the total page size and remove the photos we have all the other stuff on the page. If we stop at Jaffa 1000 wide and stop at church 800 wide and then add them all together, we get a total of 518 maximum, which is barely over our target of 500. Now let's say that we did provide the largest images in red. If I launch the page with all of these assets in place then the retina display laptop or a large tablet would be downloading a whopping 939k page. Now it would be beautiful, but would your customer wait around for it? So what are the benefits and opportunity costs? The benefit is still a better viewing experience for large screens with higher pixel ratios, the amount of work needed to make all these images still minimal when using Photoshop. The code is getting a little bit more complex as we start including media queries in the sizes attribute. Now that you've seen the results of our work on different browsers, let's review a real world deployment. First you don't need the default grayscale image; it's only purpose was to help us learn which browsers don't support SourceSet. You should use one of your color images instead. I typically use the smallest version which in this case would be the 400 image. The other SourceSet images in your codes should remain unchanged. How many images should you create and at what intervals? In the two examples used in this module we could get by with two images, a 600 wide and a 1000 wide. If you go much larger, then your total page size will be over our target goal of 500k. This would work because the photo was full width on the smaller screens and partial width on larger screens. Later we'll talk about full width hero images on all screen sizes. So to wrap up this unit, let's review what we have learned. First, we created two different images sets using Photoshop. Then we built a page with an image that was always 50% of the screen width. Next we built an image that had a media query that was full width, 75% and finally 50%. Then we tested our page on multiple browsers and devices. In the next module we will explore deploying a full width hero image that includes art direction.
-
Art Direction
Overview
In this module we will explore using art direction when creating full width hero images. First we will build a horizontal hero image using Photoshop and add that image to our HTML page. Second, we'll build a hero image that contains both landscape and portrait cropping and add that to our page. Finally, we'll test our work and discuss the best use of these techniques. In the demos for this module you have a copy of these images or you can use your own. I will be creating three versions of each using Photoshop. What is our direction and how does it apply to web images? Well, basically, it's cropping and displaying an image differently, depending on the screen size. For this module we are going to create three evenly spaced images for the full width hero image. The first breakpoint is 35em or 560px. So our first image will be used for screens up to 560 in width. The largest image we'll ever need is 1600 wide because I will add a max size to my main tag of 100em. If we take 1600 and subtract 560, the different is 1040. Then we divide by 2 and get 520. If we then add 520 to 560 we get 1080 for the maximum size of the second image. We will now use these three numbers for the target width when we calculate the image size in Photoshop. This is what your images may look like when you're done. Remember that in this module we are using art direction so what you choose to show may be different than what I chose. As before, we will include a grayscale test image. Now let's jump into Photoshop.
-
Portriat Hero Image Using Art Direction
From the demos for this unit, get a copy of synagogue.psd and open it in Photoshop. Duplicate the background layer. Choose the rectangle marquee tool and change the style to fixed ratio. Set the width to 2 and the height to 1. Drag a rectangle marquee around the part of the image that you want to keep for large screens. Choose select, inverse, and press the delete key. Choose select, deselect. Change the layer name to 1600 x 800, space, synagogue1600.jpg. Since we are using a 2 to 1 ratio, I know that the height in this case is half of the width. Duplicate the background layer again. Drag a rectangle marquee around the part of the image you want to keep for medium screens. Choose select inverse. Press the delete key and choose select/deselect. Change the layer name to 1080 x 540, space synagogue1080.jpg. Duplicate the background layer a third time. Drag a rectangle marquee around the part of the image you want to keep for small screens. Choose select inverse, press the delete key. Choose select, deselect. Change the layer name to 560 x 280, space, synagogue560.jpg. Turn on file, generate, image assets, and then save your file. Here in the desktop you should now have three images. Duplicate the smallest one and rename it synagogue.jpg. Open it in Photoshop and change it to grayscale and save it. Remember to compress these images and then drag them into the images folder of your start file. Now we can open the start folder in Brackets. Let's add a heading too for Synagogue at Capernaum. Add a figure tag with a fake caption of Synagogue at Capernaum and a class of hero. Add an image tag with the source pointing to the grayscale image, add an alt tag, add a sizes attribute. Since this is a hero image and full width on all screens, set the sizes to 100vw. Now we're ready for the SourceSet. The smallest image is synagogue560.jpg with 560 as the width. The second image is synagogue1080.jpg with 1080 as the width and finally synagogue1600.jpg with 1600 as the width. In the small SCSS file, add a figure.hero with the width set to 96% and a left margin set to 2%, which is the value of our gutter variable. Remember to set the image to 100% of the figure. Now in the large SCSS we'll limit the width of the main element to 100em and set the margin to 0 and auto on the sides. Make sure you have your CSS preprocessor running and launch your page in a browser. As we move from small to large, we can see the three different croppings of our image. In Chrome when you move from large to small, you do not see the changes. This is because Chrome and Opera do not load a smaller image once a large one has already been loaded. This can cause problems when testing your work. Use Firefox instead. Firefox shows your changes from small to large and from large back to small.
-
Portriat and Landscape Hero Image Using Art Direction
Now let's return to Photoshop for our second example. Open the temple mount in Photoshop. Duplicate the background layer. Select the marquee tool and change the style to normal. Draw a rectangle marquee around the part of the image that you want for the large screen display. Now choose window, info, and write down the width and the height of the selection. Choose select, inverse, and press the delete key. Choose select, deselect. Select the layer tab. Using the cross multiply box, enter the width and height of the selection. Enter 1600 for the target width. Now multiply the selection height by the target width and divide by the selection width to get the target height. Enter the width and height followed by temple1600.jpg in the layer name. Now we're ready for the second one. Duplicate the background layer again. Drag a rectangle marquee around the part of the image you want for medium screens. Choose window info and write down the width and height of the selection. Choose select inverse and press the Del key. Choose select, deselect. Using the cross multiply box, enter the width and height of the selection, enter 1080 for the target width. Now multiply the selection height by the target width and divide by the selection width to get the target height. Enter the width and height followed by temple1080.jpg in the layer name. Now we'll duplicate the background layer for the third and last time. Drag a rectangle marquee around the part of the image you want for a small screen. Remember that this time you want a taller image for small phone screens. Choose window info and write down the width and height of the selection. Choose select inverse and press the Del key. Choose select and deselect. Using the cross multiply box, enter the width and height of the selection. Enter 560 for the target width. Now multiply the selection height by the target width, divided by the selection width and you get the target height. Enter the width and height followed by temple560 in the layer name. Turn on file, generate image assets, and save your file. Create a black and white version for dumb browsers and name it temple.jpg. Optimize these images and move them to the start folder. The code is almost identical to the synagogue image so we'll start by duplicating what we have and make some changes. Copy from heading 2 down to the end of the figure tag. Paste it below, change the h2, the alt tag, and the figure tag all to Temple Mount. Now change all references of synagogue to temple. Save your page. Let's open it in a browser and see what we have.
-
Introducing the Picture Tag
So here's what we have in our browser with the first and the second image. The second image is displaying as it should. Remember when we reduce the screen size in Chrome it doesn't automatically load the next image so what we're going to do is bring up our inspect tools. We're going to resize the image using the center bar and then we're going to empty cache and do a hard reload. So with our browser at full width we can see the largest image showing in both cases. We'll now reduce it down to around a medium size, empty the cache, and we can see the second image cropping appearing. Let's now reduce it to a smaller size and once again, empty the cache. Here we can correctly see the smallest crop here and the tall image showing under Temple Mount just as we intended. Now there are also some additional inspect tools right here in the device toolbar. If we start with an iPhone 5, which is the smallest one and then we do an empty cache and reload, you can see that it's loading the smallest version of both images as you might expect, but beware because it's not correct. Since we can't quite trust the Google emulator to show us properly 1x, 2x, and 3x devices, we're going to upload the start file to my sandbox. Once it's done, I can now open my phone and test it on a real device. Over here at the left I have my Chrome desktop browser and you can see the Temple Mount image with the single arch. Over to the right I have opened up my iPod Touch. Now I use this one for testing screens that are 320 CSS pixels wide. When we scroll up to the Temple Mount image, we can see that it is not showing the single arch, but instead the three arches. That's because the iPod Touch has a 2x display and so when the width is calculated, the appropriate image is the second image, not the first one. Now when I display my iPhone 6 Plus, which has a 3x resolution, you can see that I'm getting the five arch version of the Temple Mount image. So this is not working at all the way I intended. I wanted all phones to display the single arch, all medium screens such as tablets to display the three arch, and then all desktops or really wide screens to display the five arch version. So let's go back into our code and try using a picture tag instead of an image tag. So down here below this Temple Mount we'll do another h2 and we'll use a picture tag. First of all you have a source and you immediately have a media query. Media equals quote, left parentheses, min-width, and we're going to convert 1080 pixels into em, so that's going to be 67-1/2 and then the srcset which you're familiar with, is going to equal images, forward slash, temple1600, which is you remember is the largest. So what we're saying is once the minimum width crosses the boundary of 1080, then start using the largest possible image and we will end that particular source. Just like we did in earlier modules, we start the media queries with the largest and we go down to the smallest or default. So now let's do the medium one. The medium one starts working at 35em and it uses the 1080 image. The last one doesn't need a media query because it is the default and it uses the smallest image, which is the 560 wide image. And then of course there's a default image tag and that's the grayscale one for browsers that don't understand what we're trying to do. Save that and we'll see what we've got. There's our new image and of course the CSS is not working. So let's jump back to our small SCSS file. We already have the setup for the figure tag. We'll simply change this to picture and picture. Now you might be wondering why I don't just put a comma here and add the picture. Well, the picture doesn't react the same way as a figure so we're going to have to make some changes here. First of all, when I do width of 96%, it seems to ignore that for some reason so that's worthless gone. Instead you actually assign the image the width that you want it to be. So in our case 96%. So with those changes in place and our CSS preprocessor running, let's open our browser and test it again. When I empty my cache and reload, I can see that the Temple Mount redone is not working so I'll go back here. I'll switch to index and make sure I've spelled class correctly and I have not so let's save that. Let's empty the cache and reload one more time and it's working as it should. In order to perform a real test, I'm going to re-upload the start folder to my sandbox and test it on real phones and devices. I now have my two devices connected using Airplay and you can see on the smallest iPod Touch with the 320 CSS width screen that the new redone Temple Mount is loading the correct image of the single arch just like I wanted. If we now pull up the iPhone 6 Plus, which has a 3x display, we can see that it is also loading the correct image. Now my original design, which was to have a single arch displayed on narrow screens is working because we're now using the picture tag. Using the picture element with the source, you can not only have media queries, but your srcset can include images for 1x, 2x, 3x displays. In Photoshop I have created a second version of the smallest image only and I've done with a comma and I've doubled the size. I've named it 560B.jpg. I then went into Photoshop and I added a 1x and a 2x to it. So here in the default, which is the smallest portrait image, we'll go ahead and sign this first image as a 1x. Put a comma and then we'll copy this entire path, paste it, simply change this to a 2x display and put a large B there. So here on my desktop browser I see a 1x image, which I would expect because it's a 1x display. Here on my 2x iPod Touch I see the 2x image, which is twice the width and twice the height, twice as pretty. On my 3x iPhone 6 Plus I still see the 2x image because I didn't create a 3x. That would just be way too large. Now I could've created a 2x version for the temple1080 and a 2x version for the temple1600, but these images are already pretty hefty so quadrupling the size of each and uploading it probably wouldn't be a good idea.
-
Testing and Page Size Review
Let's begin our testing of the picture element with the iPhone 4, the iPad 1, and Internet Explorer 10. We can see they are not working. On a 1x display at 400, 800, and 1200 on a modern browser, I have an exact match between the second and third images where I'm displaying a single arch, triple arches, and five arches. Remember that the third image is using the picture tag; however, when I move to a retina display on my laptop, there is not match between the second and third image. It is only with the third image, when I used the picture tag and media queries that it works properly. Note the 2x image being shown on the smaller screen. In the iPhone 6 we see the medium version of the synagogue image and the proper display of the single arch a 2x using the picture tag. As with the retina display laptop, the second image is not working as I intended. In the next slide, I'm going to use a Chrome extension called YSlow. It allows me to resize my window to any width and then check the page speed for the displayed images. I will use it for the smallest window width test. The page with only the synagogue image comes in at 561k for the largest browser width. It comes in at 103k for the small screen. This is a significant savings of over 500% in data usage because we used responsive images. The page with five arches comes in at 466k for the largest browser width and at 138k for a small screen. This time it's over a 300% savings in data. From the previous slide we can see that this image was larger than our target of 500k. One way we could fix this would be to lower our max width from 1600 down to say 1200. Another way would be to take the image back into Photoshop and lower the quality a little bit until it fits. We could crop some off the top or bottom to make it work or we could change our target of 500k to something larger. Remember that in 2016 the average web page size was 2300k. So what are the benefits and opportunity costs? With the synagogue image the benefits are still looking really, really nice. With the temple image we can use art direction for different screen widths. The third benefit to responsive image is the lower data demands on smaller screens. Building the image in Photoshop is still really easy but it requires a little more math. The code for the picture tag is easy to understand, especially if you've been working with the image tag already. In the real world you don't need a default grayscale image. I would use the triple arch because it's landscape. The other code should remain unchanged. So to wrap up this unit, let's review what we've learned. First we created three different croppings and coded a hero image using the image tag. Then we built three different croppings of the temple image and made the smallest one portrait for phones. We had to use the picture tag to make this work correctly. Finally we tested our work. In the next module we will explore lazy loading images below the fold.
-
Lazy Load Images
Overview of Lazy Loading
In this module we will build a photo gallery page that incorporates image lazy loading. First, we will review the start folder for this module and the problem of page size for image galleries. Next we'll implement lazy loading using the large 11 images, using a plain JavaScript, not jQuery. Second, we will combine lazy loading with responsive images so our smaller mobile screens are even faster. Finally, we will review how these pages load on different devices and browsers. In the demos for this unit you have the following 11 images in different sizes. The small image is 560 pixels wide and the large version is 1200 wide. I'm going to assume by now that you've had enough Photoshop experience to build these on your own. As always, you're welcome to use the ones in the demos for this module. Please get a copy of the start folder for this lesson. Here is the full page with all 11 images showing. Each image is wrapped in a figure tag. The CSS tells the figure and the image to both be 100% of the available width. When this page loads, it's a whopping 3.4 MB, which is over six times our target size of 500k. Now that's the problem we're going to try and solve. So what is lazy loading? Well, it speeds up your web page by loading images only as they enter the view port or visible area of the screen. Anything below the fold is not loaded until the user specifically requests them by scrolling down to see more images. In our case, only the first two images are loaded and the remaining nine are not loaded up front. If you scroll down really fast, you can actually see the remaining images being loaded on the fly. Andre is the author of the Lazyload script we're going to use for this module. His JavaScript code is six times faster than using the jQuery lazy load. You can download the latest version of his script from his GitHub account or you can use a content delivery network or CDN and add the link. I have included a copy of his minified script in the demos for this module and we will be using it locally. So let's get started on our first demo.
-
Lazy Loading with JavaScript
First we will go to Andre's website where he provides the basic JavaScript to initialize async script plus auto initialization. We will copy these and paste them just before the closing body tag. Later we will add options, but for now let's change the path to point to our local version of the minified lazyload script. Now we're going to remove the prior reference to figures and images. Inside the article with a class of llgallery, add a figure tag with an empty image tag. Within the image tag we will add data-original= and reference our very first image. Next we add sizes=100vw and alt=photo. Now let's test our page to make sure everything is working. If we inspect the image, we can see that the lazyload script has added a source with a path to our image. Now it's simply a matter of copying and pasting 10 more images and changing the path for data-original. Now let's explore another useful tool inside Chrome. The network tab shows us all the resources that are being loaded, how big they are, as well as the page size. I have noticed that when loading a page locally, the size is not reported correctly. If we load our page now we can see that even though we have lazyload script in place, all of the images are showing up in the network tab of developer tools. This is because currently the images have a height of 0. So the script thinks all images are above the fold. Now we're ready for the CSS, which is again provided by Andre's website. Our image wrapper is the figure tag inside the article. First we will add width at 100%, height of 0, and now if we divide our image height of 750 pixels by the width of 1200 pixels, it gives us a bottom padding of 62.5%. This allows the browser to pre-calculate how high each image is and therefore how many of the images will be above the fold. We also set the width of the image, which is inside the figure to 100%. Now let's test our work again. This time when we look at the network tab we can see that not all of the 11 images were loaded. Let me adjust my window height so exactly one image is showing and reload the page. Why am I still seeing two images here? It's because by default the lazyload script looks down 300 pixels below the window and loads whatever is there. If we return to our HTML page and add threshold: 0, then it will not look below the fold. Let's run our test again and we can see that only one image is being loaded. When we scroll down we can see additional images being loaded dynamically. Now let's upload this to our sandbox and run some more tests. When we run YSlow, which only works on live sites, not locally, we can see that the page total is now 330k because we're lazy loading only one image. If we click components and images we can see that we are loading the logo and one gallery image. If we use the iPhone emulator, it shows two images above the fold. It loads two gallery images plus the logo for a total weight of just over 600k. Remember that earlier when we loaded this page on any browser or any device, it was over 3400k in size. Now we're down to over just 600k on the phone. That's a great improvement, but it's still over our target of 500.
-
Lazy Loading with Responsive Images
Now let's take this to the next level and add responsive images to our lazy loading gallery. We will be using 11 images that are 560 Photoshop pixels wide for small screens and the 11 images we used before at 1200 wide. Notice that the smaller images are tagged with the black dot so we can easily tell the difference. Now we could use the width approach as shown here. The problem is that a vast majority of mobile devices have a 2x or higher screen so they will never see the 560 image. For example, an iPhone 6 with a CSS width of 375 pixels times a 2x pixel density will have 750 dots of light at the 100 view width so the larger image will be chosen. Using this method, the only place the smaller image would ever be seen is on a 1x desktop computer with a narrow browser. The place we need to save bandwidth is on mobile devices that have a monthly data plan so let's try something else. We will use the picture tag instead to make sure that the wider screen gets the larger image and the smaller screens see the smaller default image. So let's go back to Brackets and make some minor modifications. First, in the HTML page let's delete all the figures in the article. Let's add back a figure tag and inside that a picture tag. Now we can add a source with a media query for screens wider than 35rem. We will add an image using data-original-set and point to the large 1200 wide jpg image. Finally, we will add an image tag with an alt. And using data-original we will point to the smaller graphic that is 560 Photoshop pixels wide. Now this should work based on CSS screen width and not the dots of light. We copy and paste this 10 more times and update the image paths for each one. When we test the picture tag in Chrome, it switches from the small image with the black box to the larger image as expected, but it also switches from the larger image back to the smaller image. This makes testing much easier. Let's upload this to the server and test it on other devices. Now this is amazing. Up to this point the iPhone 4 has failed every test, but the lazyload gallery works. You can see the small black box indicating the small image has been loaded. The iPad 1 on the other hand is a total failure. Same results for Internet Explorer using this pure JavaScript approach. Andre has a section on his lazyload site about how to get Internet Explorer to work or you could switch to a jQuery version of lazyload and get all older devices to work. On a 1x display at 500 pixels wide we are seeing the small image with the black box and on the 800 wide screen we're seeing the 1200 wide image. On this retina 2x display at 500 wide we are seeing the small 560 gallery image as we hoped. The 800 wide is also displaying the larger image correctly. The iPhone 6 is displaying the smaller images correctly. The 2x display is currently showing the larger version of the photo since the screen width is greater than 560 pixels. In a desktop 1x display at 500 CSS pixels wide, we are seeing the first three smaller gallery images and the page weight on YSlow is 302k and on the Chrome network tab it's 292k. We have already demonstrated that the mobile devices are loading the same images as the desktop so we have finally brought our page weight down below 500 for the initial load time. So what are the benefits and opportunity costs? In this module we have taken the original gallery page with 11 images from 3400k down to 300k by using lazy loading and responsive images. That's a huge benefit for mobile browsers. To accomplish this we connected one lightweight JavaScript and built two version of each photo. If you need to support Internet Explorer, then you may have to use the jQuery library which weighs in at 83k for the latest minified version, but you should definitely incorporate lazy loading when you have a page with lots of images. So this has been a really fun module for me. We started out with the start folder and added lazy loading to reduce the initial page size. Then we added responsive images to lazy loading, and finally we tested our site and beat our page weight goal of 500k. In the next module we will explore image sliders.
-
Image Sliders
Overview of Sliders
In this module we will build a responsive image slider. First, we will review the start folder for this module and the images we'll be using. Then we will review the slick slider features. Next we'll build a simple slider with one set of images and then modify it using a second or responsive set of images. Finally, we will test the page speed and see how well it works on multiple browsers. Opinions about the usefulness of sliders is mixed and often polarized. This could be due in part to the purpose of a slider. Sliders can be used to simply display visually interesting photos or they can be used to display product features or tell a story. Either way, I try to keep the slider to about five images and give the user full control over accessing the slides. Our goal is to keep the page size under 500k while creating a consistent user experience across all devices. We are going to look at how to present and optimize a slider with a message. In the demos for this unit you have the following 10 images in two different sizes. The small images are 468 pixels wide and the large versions are 944 pixels wide. Notice that the smaller versions are almost square while the larger ones are very wide. I use this approach for an orthodontist that has specific messaging he wanted with the images. The design had to be changed for each slider for both the small and large screen layouts. For this module we'll be using the Slick Slider built by Ken Wheeler. You should download the latest version from his GitHub account. His slider relies on the jQuery library which I typically try to avoid, but in this case the slider is so awesome that it's totally worth it. If we examine our completed page using YSlow we can see that version 3.1.1 of jQuery is 86k and Ken's script is 42k. Like most other sliders you can configure the slick slider. This one can turn on or off dots below the slider images. It can also deactivate arrows, which I personally don't like to use. You can control the speed at which the slides move and set how long each slider is shown; however, the main reason I like this slider is the user action is identical on phones, tablets, and desktops. For example, on mobile devices, you touch the screen with your pointing finger and drag either left or right to see the next image. On desktop screens you click the screen with your pointing cursor, then drag either left or right to see the next image. The demos for this module contain the Photoshop file which I use to build all the sliders. It also contains 10 generated images in case you don't have Photoshop handy. There is also version 1.7.1 of the Slick Slider in case you want to use the same version I will use in this module. And finally I've included a start folder.
-
Build a Slider with One Set of Images
Please get a copy of the start folder on your desktop and open it in your favorite text editor and let's get started. First we need all 10 of the slider images copied to the start folder from the demos folder. We will then place them in a folder called sliders. Download a copy of the latest version of the Slick Slider from GitHub. Unzip the file and open it to see the contents. Copy the slick folder and paste it into the start folder. We will only be using some of these files. Inside the slick folder there are two CSS files we need. Open up the slider1.html and place a link in the header to the slick.css and the slick-theme.css. Next add a link to the latest minified version of jQuery from the Google CDN. We will place the link right above the closing body tag. Right below that we will add a link to the slick.bin.js script written by Ken for the Slick Slider. This file is in the local slick folder. Finally we will initialize the slider using an inline script tag. Type an opening and closing script tag. Inside that type $ left parentheses document, right parentheses, dot ready, left parentheses function, left and right parentheses and open curly. On the line below that, type another $, left parentheses, two single quotes, right parentheses, dot slick, left parentheses, another open curly. Now press return twice. Then we'll close the second function with a right curly, right parentheses, semicolon and go back and close the first function with a right curly, right parentheses, semicolon. Now you may be wondering what goes between the single quotes. Well, we need to make up a class name, which we will use above. Let's type .myslider. Now we can scroll up to the main tag and build our slider. Let's start with an open and closed division. We will assign it the class of myslider typed exactly as we did below. Remember to add a comment to the closing division to keep track of it. Now we create another open and closing division for each slider. Inside that division we'll add an image tag with a source pointing to slider01h.jpg. Let's open our HTML page in a browser and see if the image is showing up, and it looks like it is. Now let's add the four remaining sliders to the HTML code. When we test our page again we can see that all the images are there and they're sliding; however, if you change the screen width, you can see that the slider images are not responsive. Make sure you have your CSS preprocessor running and open the small-default.scss file. We will add two lines of code. The first one makes the division full width and the second one makes the image the full width of the containing division. Now when we look at the results, we can see that the image responds to the width of the browser window. Now let's add some parameters to the Slick Slider. First we'll start the slider automatically using autoplay:true. Now when we reload the page and wait we can see the first slider go. Next we add dots:true to turn on the dots below the images. Along with that we want to turn off the arrows using arrows:false. You can see the dots here below the sliders. We also have the ability to change the sliding action to ease out using cssEase. We can also control the transition speed. Let's try speed 1000, which is 1 second. We can also control the length of time the image is displayed. Let's try autoplaySpeed: 3000, which is 3 seconds. Let's look at our page. We can see that after a 3 second wait there is a 1 second transition to the next image. There is another 3 second wait and a 1 second transition. Now let's switch the values to 3 second transition and a 1 second wait. Now we have a 1 second wait and a slow 3 second transition. Let's change these to a more acceptable 2 second transition and a 10 second wait. Well, it looks like everything is working correctly. We are now loading the same large images on the small phone screen as the larger desktop screen. The total page weight is 833k, a little over our target. Let's see if we could do something about this by combing responsive images with our slider.
-
Build a Slider with Responsive Images
Let's return to our editor and change the HTML. To make sure all phones regardless of their pixel density are displaying the square images instead of the wide images, we will have to use the picture tag. Delete the five divisions with the current slider images, add an opening and closing picture tag. Inside that add a source with a srcset pointing to the large images and a media set to 29.25 rem. This is the width of a smaller image. This image will be used when the window is wider than 29.25 rem. Next add a default image with a srcset pointing to the smaller version of the slider image. You should also have an alt tag filled out for accessibility. Let's test this and see if it works. Notice as we change the width of the browser we can see the square image on the small screen and the bigger one on the wider screen. Now it's simply a matter of copying and pasting four more times and changing the image names. Let's upload this start folder to a real server so we can run some tests. Now when we load the page and inspect the network tab, the wider screen with the larger image still comes in at 883 KB. Remember our goal was 500k. When we look at the page on a small screen, we can see that the page is 439k, which is under our goal and we win. The iPhone 4 is working for the first slider; however, only the dots are showing when we try the picture tag with the responsive images. The same result for the iPad 1. Internet Explorer also has a mixed story. The first version we did uses the image and the standard source attribute is working wonderfully; however, when we changed to the picture tag and used the source with the srcset, it broke. The iPhone 6 and newer phones with a high pixel density will show the small square image. The iPad 4 shows the larger image correctly. So that wraps up this module on responsive sliders. You are now equipped to build a touch-enabled slider with a responsive set of images under 500k. So let's wrap up this module by remembering that we reviewed the start folder and the Slick Slider features. Then we built a simple slider with one set of images and a second one with a responsive set of images. Finally we tested the page size and found that we had made our goal of being under 500k. And that wraps up this course on responsive images. Now you have a better understanding of when and how to implement them in your next project.