The Responsive Web (2015)
Part 3. Expanding the design with code
In part 3 we’ll dive into the code. Here you’re not just going to learn how to use HTML and CSS to build a basic web page. We’re going to talk in detail about some of the challenges that are unique to responsive web design.
In chapter 7 we’ll discuss adding graphics to a page. This includes ways to use CSS3 to optimize for performance and small screens.
Then, in chapter 8 you’ll start learning about progressive enhancement. With progressive enhancement you can create websites so that they function well in a variety of platforms, each with their own limitations and specifications.
Finally, in chapter 9, we’ll talk about testing and optimization. Here we’ll get into the nitty gritty of optimizing your website for performance on every screen.
Chapter 7. Adding graphics in the browser with CSS
This chapter covers
· Using CSS as a design tool
· Maintaining proportions in a responsive site
· Adding responsive media
· Using icon fonts in your design
· Using SVG in modern sites
It was tempting to title this chapter “Designing in the Browser” because we’re now at what might commonly be referred to as a “detail design” phase. We’ve already designed the site, and we’ve discussed the user interface, content, visual brand, and identity; everything is ready for us to start crafting a more detailed presentation layer.
In chapter 2 we used Photoshop to create a presentation layer for our site (figure 2.8). This showed designers how to take their typical workflow and apply it to mobile design. In this chapter, we’re going to execute a lot of those ideas, but with one huge variation: we’re not going to use Photoshop; we’ll use Cascading Style Sheets (CSS). With CSS3 you can add gradients, round corners, drop shadows (on text as well as on elements), color models for both RGB colors and alpha transparency, and opacity. In addition to features that enable beautiful design, CSS lets you animate between states, and because it renders natively in the browser, it also looks sharp and vibrant in high-resolution screens, such as Retina displays. This enables you to avoid the messy business of detecting high-resolution displays and serving alternative files to those browsers.
7.1. Using CSS to implement design
Let’s look back to our style tile from chapter 3 (shown in figure 7.1) as a guide in making decisions regarding color and visual appearance.
Figure 7.1. The style tile from chapter 3 will serve as a guide for our design.
Developer insight: designing in phases
For most developers, designing web pages is a boring and intimidating task. An understanding and respect of web design basics is crucial to success in front-end development, but it’s important not to get too hung up trying to perfect a web design yourself. The process described in this book is intended to be highly iterative and collaborative.
In my daily work, I find myself relying on other people for their expertise, and they rely on me for mine. This is the nature of collaboration, and it’s important to keep that in mind. Building web sites and applications is more of a team sport today than ever.
Using the style tile as a guide, we’ll start with the basics and select a color scheme and some patterns or background texture. We’ll use small images to create background patterns. With just a little CSS, we can produce the page in figure 7.2. For the CSS involved in creating this page, see the 7.1 directory in this chapter’s source code.
Figure 7.2. The beginnings of a designed page
7.1.1. CSS basics
Most of the CSS is rudimentary, but there are a few things worth pointing out. The first is on line 77:
The first property worth mentioning is background-size. This property allows you to set the size of a background image. Its syntax is
background-size: [x value] [y value];
and the values can be sizes in pixel or percentage values, as well as the following three keywords:
· auto— Automatically scales the image so its proportions are retained.
· cover— Scales the image to entirely cover the size of the related object. Some parts of the image may not be in view in the background area.
· contain— Ensures the image covers as much of the object’s area as possible, without distorting the image. All of the image will be in view, but it may not cover all of the background area.
Next there’s the box-shadow property. This gives you the ability to add a small shadow to the header, which we’ll add alongside a background color to give the header some depth:
The box shadow property syntax is
box-shadow: [x distance] [y distance] [blur] [color];
The x, y, and blur values can be set with pixel values, and color can be set with a hex or RGB value, or an RGBA value, which allows better control over shading with its ability to apply alpha transparency.
A major issue you may face is displaying an image with a consistent proportion or aspect ratio. When working in fluid measurements, it can be trying to ensure images retain the proper dimensions and scale. Let’s see how CSS can solve the problem.
7.1.2. Maintaining proportions in a fluid structure
In a scalable and responsive website, the height and width of images or media elements often need to maintain a relationship. A 3:4 image might need to be displayed at a width of 200 pixels on one device and 400 pixels on another but still maintain the same proportions. One way of doing this with images is by declaring a CSS height of auto, but what about elements that don’t have an embedded height value, such as an element with a background image?
There’s a trick in CSS to help with this. In our current example (figure 7.2), it’s used on the logo. In the mobile screen size, we want the logo to display at a width of 100 pixels, but on larger screens we want the logo to increase in height as well as width. We can use the same technique here that we discussed in section 1.3.3 for adding scalable images.
To create a consistent relationship between width and height, we’ll use an h1 tag to display the logo, as seen in figure 7.3, and use a wrapper to constrain the proportions. The logo shown in the h1 should be able to scale proportionally with the width of the parent element:
Figure 7.3. The logo should maintain a consistent relationship between width and height.
Then we’ll create CSS rules for both the wrapper and the logo header:
First, we set the parent to the desired width. In this case we want it set to 100 pixels, but we could just as easily use an em or a percentage value. We also need to set the positioning to relative. This is important because we need to set an absolute position for the child element in order to maintain the sizing.
Percentage-based height is always relative to an ancestor with an explicit height, but percentage-based padding is always consistent (top and bottom, left and right), and always relative to the parent element. Therefore, padding-bottom is relative to the width of a parent element. We can exploit this to our advantage in responsive websites.
Another place this CSS trick comes in handy is with video. Videos almost always require a set aspect ratio (see figure 7.4 and the 7.2 directory in the chapter’s source code).
Figure 7.4. A responsive video in place
An aspect ratio is easily applied to a video by wrapping the video in a container div (instead of the usual iframe HTML element) that will define the available area for the video:
Using the preceding HTML and CSS, the video will scale nicely between views. The video iframe will scale fully from right to left and maintain a proper aspect ratio, as you can see at the bottom of figure 7.5.
Figure 7.5. The aspect ratio difference between a video using just the iframe tag (top) and using the container div (bottom).
Now let’s look at some ways we can add user interface graphics to the page.
7.2. Using icon fonts in your design
With CSS3 you can load custom typefaces into your designs, as we discussed in chapter 6. This has obvious advantages for creating unique designs in the browser, but it can also be exploited to create beautiful user interfaces using icon fonts. An icon font is a custom typeface that’s based on scalable vectors (SVG). With an icon font, you can easily change the color, size, and everything else you can do with any typeface.
7.2.1. User interface sprites
Typically, user interface controls for websites are implemented by creating a CSS sprite, which is a collection of images combined in a single image (see figure 7.6), and displaying the parts of the image in that sprite as they’re needed. A single image is used as the background for an element, and the portion displayed is aligned by using the background-position CSS property.
Figure 7.6. An example of a commonly used image sprite, this one from Videojs.com
This has traditionally been an effective method, but in a responsive website it needs to be slightly more nuanced. High-resolution displays will display a fuzzier image than normal displays, and in smaller screens you might want to use smaller or larger buttons, which would require new sprites for various breakpoints.
The best way around this is to use an icon font face instead of a sprite. Because it’s a custom typeface, the icons are vector-based as opposed to the raster-based images in a typical PNG sprite, and you can manipulate each icon as you would any other font family. The font face also scales elegantly for various size requirements.
Designer insight: vector images vs. rasterized images
The difference between vector images and rasterized images is important in responsive web design due to the need to accommodate various pixel densities. One way to describe the difference is that Photoshop produces rasterized images and Illustrator produces vector images.
Rasterized images contain pixel data and create an image by assigning each pixel a color. Displaying such an image becomes challenging when pixel sizes are revised by changing requirements. An image that’s created at 100 pixels wide looks “pixelated” when it’s stretched to 200 pixels wide.
Vector images, on the other hand, are created by setting points and mathematically drawing lines and curves between them. Because there is no “pixel” data being communicated, the vector images can scale fluidly. Fonts are, by default, vector-based images, but there are other ways of creating vector art for use on the web, most notably the SVG format, which we’ll discuss in section 7.3.
7.2.2. Font-based user-interface graphics
In our example site, we’ll use an open source font for user interface icons called Font Awesome. The font of icons is free to use and is also available through a public content delivery network (CDN), such as the Google CDN we used earlier for our custom typefaces. The CDN I’m using for Font Awesome is cddjs.com.[1]
1 Font Awesome is a free and open source font: http://fontawesome.io/.
Figure 7.7 shows some of the icons available on Font Awesome.
Figure 7.7. A small example of icons available in Font Awesome
In figure 7.8 I’ve used Font Awesome to create the information icon and the four-bar navigation icon.
Figure 7.8. Our site’s UI, at the top of the page, is generated using a typeface instead of images.
To use this font, you have to add a link reference to the font file. This is similar to the process of linking a font from Google Fonts, as we did in chapter 6. The first thing you do is import the CSS library into your page:
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.3/css/font-awesome.min.css" type="text/css" charset="utf-8">
After that, you can add a few classes to the buttons:
Note
Open source development releases new versions quickly. At the time this was written, the latest version of Font Awesome was 4.0.3.
Then use the btn class to style the buttons in the same way you’d style any other type on the page:
.btn{
font-size:2.2em;
color:#2e3034;
text-align:center;
}
In just a minute or two, you’ve created a simple user interface that will scale nicely and look gorgeous on high-resolution displays, mostly thanks to the fact that font faces are rendered on the page using Scalable Vector Graphics (SVG). In the case of Font Awesome, these vector graphics come in the form of font files in order to work across different browsers. The vectors themselves are the same, but they’re implemented by hacking CSS3’s font-face properties for ease of embedding.
What if you wanted to leverage the advantages of SVG outside of generic icon fonts, such as for an image on a page? SVG can currently be used in place of traditional background image formats in most browsers and can offer the same high-quality graphics to present your custom design.
7.3. Using Scalable Vector Graphics
Scalable Vector Graphics (SVG) is an XML-based image format that has been an open standard since 1999. The file format has only recently been accessible in modern browsers, but it came in at the perfect time.
SVG gives designers the opportunity to create images that remain sharp and beautiful at any scale and in any display. They can be zoomed in on and retain their crispness, or scaled down and retain their detail. Take a look at figures 7.9 and 7.10.
Figure 7.9. This star was created with a raster-based imaging program and is zoomed in to 400% original size.
Figure 7.10. This is the same star created in a vector-based imaging program, also shown zoomed in to 400%.
An SVG file can be created in Illustrator, Photoshop, or a myriad of other programs—I use an application called Sketch (www.bohemiancoding.com/sketch/). Once you’ve created your graphics, you can save the files as SVG for use on your page.
Note
Any vectors created in Photoshop will have to be exported to Illustrator because Photoshop lacks the ability to save SVG files.
Another great feature of the SVG format is that you can edit it with any text editor. With drawing software like Illustrator you can open and edit an SVG and save it without having to export it every time, meaning that designers can make changes to graphics on a page quickly and easily without having to update any CSS.
7.3.1. Adding an SVG image to a page
An SVG image can be added to a web page in one of two ways: as an object HTML element or as a CSS background image. An object is displayed on the page itself, whereas a CSS background image is applied as the style of an HTML object tag. This is a minor, but important, distinction.
Displaying figure 7.8’s SVG star on the page is as simple as linking to the source file on the page. In the HTML file, simply add an <object> tag and a few attributes, and the image shows up in the browser (figure 7.11).
Figure 7.11. The SVG image on the page
When using an object tag to embed an SVG image, you use the data attribute to assign the SVG file. This will display the SVG within the object tag:
<object type="image/svg+xml"
width="400" height="400" style="float:right"
data="images/star.svg">
</object>
As you can see in figure 7.11, the image retains transparency much like a PNG file and is scaled up to 400 x 400 pixels, as specified in the object tag. You can see this transparency in how the page background is visible behind the image of the star. In image formats that don’t retain alpha transparency, an image is rendered with a white background. If you wanted to scale this image down, you could change the width and height values, and the image would still look beautiful (see figure 7.12). See the example code in the 7.3 directory.
Figure 7.12. The star scaled down
The SVG image can be scaled using the width and height attributes:
<object type="image/svg+xml"
width="100" height="100" style="float:right"
data="images/star.svg">
</object>
It can also be scaled with CSS:
<object type="image/svg+xml" class="star"
data="images/star.svg">
</object>
Note that the object tag now has a CSS class star that defines the same styles as the style, width, and height properties in the previous example:
.star {
float: right;
width: 100px;
height: 100px;
}
Both code samples produce the same result.
While scaling the image down is helpful, it’s not nearly as impressive as when you scale the image up, as shown in figure 7.13. Now the image is scaled to a ridiculous 4,000 x 4,000 size and still looks wonderful.
Figure 7.13. An intensely zoomed-in SVG star
Here, I’ve increased the size of the SVG using the width and height attributes:
<object type="image/svg+xml"
width="4000" height="4000" style="float:right"
data="images/star.svg">
</object>
The file hasn’t changed, so the file size is the same—the user isn’t burdened with downloading a bigger file to get the bigger image.
7.3.2. Implementing SVG with CSS
Being able to add an SVG image to a document is helpful, but using SVG images in CSS can be much more useful at times, such as when you want the image to scale with an object on the page. SVG should be the graphic format of choice when designing a user interface because of its crisp appearance and scalability. This scaling is most easily done in CSS.
As an example, let’s replace our logo with an SVG version. First, you need to create an SVG file using Sketch or some other vector-editing program and export it into the images folder. All you have to do next is replace the PNG in your CSS with an SVG file. The source code for this example is in the 7.4 directory:
What we get is shown in figure 7.14.
Figure 7.14. Our logo is now an SVG file.
You could use a small logo for this site, but in larger views you might want the full size of the logo. This can be done simply by using background-size:
#logo {
position: absolute;
overflow: hidden;
width: 131px;
height: 0px;
padding-bottom: 53%;
font-size: 0px;
background-image: url(/images/logo.svg);
background-size: 242px auto;
}
This scales the logo without compromising image quality by adjusting the size of the background image without affecting the size of the object itself. Even though the object is 131 px wide, its background image is set to 242 px wide, leaving 111 px difference, which is unseen, because it extends outside of the DOM object.
This might be how you’d want to handle a sprite with SVG. The background-size setting changes the scale at which the image is rendered without affecting the object the image is rendered within. The background-size property is not to be confused with background-position, which dictates an image’s placement within a DOM object.
7.3.3. Limitations of the SVG format
Working with new technology always has its consequences, and the SVG format is no different. Although it gives designers and developers a much higher degree of quality, it comes at a cost, and you need some foresight to overcome the limitations.
File size
The most obvious consequence is file size. The file for the star example comes in at just a handful of bytes, but the logo is 70 KB, which is pretty large considering its PNG equivalent is only 9 KB. This issue can be overcome with server-side gzip compression, but it’s still important to keep track of how many files are being loaded and how large they are.
Single-color files
Another complication is that SVG only works well with illustrations, where color boundaries remain simple. You can apply color and gradients to shapes, but complex images come at an expense in file size. This is why SVG is most useful for user interface elements or site iconography such as Font Awesome, where all the icons are rendered using a single color.
The server
You also need to make sure that your server will serve SVG files. If you’re using an Apache web server, this is as simple as adding a few lines to the server’s .htaccess file. If you’re not, it should be easy to find an equivalent configuration that will work with your web server configuration.
For Apache, just open your .htaccess file, and add the following two lines at the beginning:
AddType image/svg+xml svg
AddType image/svg+xml svgz
These lines are the MIME types that ensure your server is configured to read and serve the SVG file format.
Browser support
The other issue, and probably the most problematic, is browser support. SVG is supported by all modern browsers except Internet Explorer. This can be troublesome, but it’s easily solved by creating a PNG file as a fallback when exporting your SVG file:
Instead of simply serving the fallback through the typical browser detection, I recommend using feature detection to accomplish this. In the next chapter, we’ll discuss feature detection.
7.4. Summary
In this chapter we discussed using modern techniques such as font faces and SVG to create and implement beautiful responsive websites.
We talked about creating scalable background images and videos. Using these techniques, images and video elements can scale fluidly in a responsive environment.
We also discussed using icon-based font families to create buttons and UI elements. By using an icon font, you can scale up beautiful, vector-based graphics using CSS.
Finally, we looked at the benefits and implementation of Scalable Vector Graphics (SVG). We discussed the features of SVG images and how to display them on a page and use them in CSS. We also covered the inherent limitations that come with this progressive format.
In the next chapter, we’ll discuss ways to overcome some of the cross-browser issues that arise when using modern CSS. We’ll discuss Modernizr, a JavaScript library that resolves this issue by basing CSS on feature detection as opposed to assumptions based on browser detection.
7.5. Discussion points
· When it comes to adding graphics to a prototype, how can designers and developers collaborate to achieve a beautiful product?
· What are some of the opportunities that designing in the browser opens up for you?
· What flexibility and benefits do you see to using SVG in your designs? What limitations does it present?