- Dynamically Changing Images’ Screen Area
- Creating Flexible Collections of Images
Creating Flexible Collections of Images
You now know several ways to make individual images flexible to either their parent’s dimensions or text size, but what about when you need a whole group of images to be flexible as a whole? Let’s go over how to make two of the most common types of image collections—teaser thumbnail lists and image galleries—flexible too.
Teaser Thumbnail Lists
A teaser thumbnail list is my own personal name for the design convention of a list where each item is made up of a title, short description, and thumbnail image. Figure 2.22 is one example of a teaser thumbnail list, as is the list of featured pets on the home page of our fictional Beechwood Animal Shelter site (Figure 2.43). These types of lists can be built in many different ways, but many techniques result in lists that are not flexible or not as accessible to the end user as they could be.
Figure 9.12 shows the teaser thumbnail list I’ll be using as an example throughout this section. I’ve chosen the following HTML as the most semantic way of marking up each of the elements of this design component:
<h1>Seafood of the Month Club 2008</h1> <ul> <li> <h2>January</h2> <img src=”january.jpg” alt=”” width=”100” height=”100”> <p>Seared sea scallops, served with mushy peas.</p> </li> <li> <h2>February</h2> <img src=”february.jpg” alt=”” width=”100” height=”100”> <p>Soy-glazed salmon, served with coconut and bell pepper broccoli slaw.</p> </li> <li> <h2>March</h2> <img src=”march.jpg” alt=”” width=”100” height=”100”> <p>Tuna steak with ginger-shitake cream sauce, served with sesame broccoli and brown rice.</p> </li> </ul>
Figure 9.12 Each teaser thumbnail list item is made up of a title, short description, and thumbnail image.
You’ll note that the img elements follow the h2 heading elements, even though Figure 9.12 shows the images appearing on the same line as the headings. You’ll need to find a way to get the images to move up to sit beside the headings, even though they come later in the source. Luckily, you’re already an expert at doing just that—you have several negative margin layouts you can use to achieve such an effect. A teaser thumbnail list is essentially nothing more than a two-column layout. This particular one has a fixed-width left “sidebar” and a liquid right “main content area,” so any negative margin technique that works for two-column, hybrid liquid-fixed layouts will work here.
To turn this into a negative margin “layout,” the basic steps are:
- Create an empty space on the left side of the list.
- Use negative margins to pull each image into that space.
- Float all the elements within each list item so they can sit side by side.
We’ll create the empty space on the left side of the list using a left margin on the ul element that is equal to the width of the images (100 pixels) plus the width of the gap we want between each image and its accompanying text (15 pixels):
ul { margin: 0 0 0 115px; padding: 0; list-style: none; }
This rule also gets rid of some of the default list styling, including the bullets. The rest of the default list styling that needs to be overridden is on the list items:
li { margin: 0 0 20px 0; padding: 0; }
This removes the default left margin and padding that some browsers add to li elements, as well as adds 20 pixels of space below each list item to space them out from each other.
Figure 9.13 A large empty space on the left side of the list stands ready to receive the thumbnails.
You can now pull the image into the empty space on the left:
img { float: left; margin-left: -115px; }
This positions the images correctly horizontally, but not vertically (Figure 9.14). To get them to move up and sit beside the headings, the headings have to be floated, as do the paragraphs:
h2 { float: right; width: 100%; margin: 0; } p { float: right; width: 100%; margin: 0; }
Figure 9.14 Negative left margins pull the images to the left, but don’t pull them up to sit beside the headings.
The width: 100%; declarations ensure that each piece of text fills up the entire width to the right of the images, instead of each element shrinkwrapping to its content, as floats without declared widths do naturally.
The images have now moved up to sit beside the headings, but they overlap each other (Figure 9.15). This is because the list items contain only floated content now, which is out of the flow, and have thus collapsed down to zero height.
Figure 9.15 Floating the text elements to the right allows the images to sit beside the headings, but the list items will not expand to hold the full height of the thumbnails when everything inside the list items is floated.
To address this, we need to use a float containment method to get each list item to encompass all of the floated elements within it. Floating the li elements themselves is one easy way to do this:
li { float: left; width: 100%; margin: 0 0 20px 0; padding: 0; }
The list items are now properly spaced out from each other, whether the text within them is shorter or longer than the thumbnail images (Figure 9.16).
The only problem is that floating the list items made the images disappear in IE 6 and earlier. To fix this, add position: relative; to both the li and img rules:
li { float: left; width: 100%; margin: 0 0 20px 0; padding: 0; position: relative; } img { float: left; margin-left: -115px; position: relative; }
Figure 9.16 No matter which is longer—thumbnail or accompanying text—the list items remain spaced out from each other.
Thumbnail Image Galleries
Although images are usually fixed in width, you can line them up side by side and still create a block of image thumbnails that can change in total width. You saw an example of this in Figure 2.41, where the thumbnails wrapped onto a variable number of lines to accommodate the liquid width of the content area. Another way to create a flexible image gallery is to make all of the thumbnails scale, using one of the scalable image techniques you learned at the start of the chapter. Let’s go over both options.
Wrapping the Thumbnails
The two behaviors you want thumbnails in a flexible image gallery to achieve—sitting side by side and wrapping onto more lines as needed—are both native behaviors of floats. So, the only thing you need to do to make thumbnails wrap is to float each one in the same direction.
You could just place the images straight into the (X)HTML with no container, and float each of the img elements. But a more semantic way to mark up a group of images is to use an unordered list, which offers you more styling possibilities as well. Put each img into an li element:
<ul> <li><img src=”january.jpg” alt=”January” width=”100” height=”100”> </li> <li><img src=”february.jpg” alt=”February” width=”100” height=”100”> </li> <li><img src=”march.jpg” alt=”March” width=”100” height=”100”> </li> <li><img src=”april.jpg” alt=”April” width=”100” height=”100”> </li> <li><img src=”may.jpg” alt=”May” width=”100” height=”100”> </li> <li><img src=”june.jpg” alt=”June” width=”100” height=”100”> </li> <li><img src=”july.jpg” alt=”July” width=”100” height=”100”> </li> </ul>
Next, remove the default list styling:
ul { margin: 0; padding: 0; list-style: none; } li { margin: 0; padding: 0; }
Now, simply float the li elements all to the left, and give them some margin on their right and bottom sides to space them out from each other:
li { float: left; margin: 0 10px 10px 0; padding: 0; }
That’s all you need to do to create a basic, wrapping thumbnail image gallery (Figure 9.17). The perfect number of thumbnails always sits on each line, no matter the viewport width, so you don’t get a horizontal scrollbar or a really large gap on the right. If you didn’t want the gallery to take up the entire width of its parent, simply assign a width to the ul element; as long as the width is a percentage or em value, the list will still be flexible and the thumbnails will still wrap.
Figure 9.17 The number of thumbnails on each line adjusts to the space available in the viewport.
You may have noticed that all of the thumbnails in this example share the same dimensions. Variable widths on thumbnails are not a problem, but variable heights make this wrapping thumbnail technique fail. Figure 9.18 shows the same page with the height of some of the thumbnails increased. When the thumbnails wrap, they move as far over to the left as they can go. But when one of the thumbnails in the previous row hangs down farther than the rest, it impedes the new row of thumbnails from moving any further to the left, and big gaps can be left in the rows.
Figure 9.18 The extra height on the second thumbnail blocks the fifth thumbnail from moving all the way to the left, leaving a gap in the second row. The same problem happens in the third row.
There are a couple ways you can modify the basic technique to work with variable height thumbnails. The simplest is to assign a fixed height to the li elements that matches the height of the tallest thumbnail. This makes all the li elements match in height, instead of depending on the size of the images inside them to dictate their heights, so there are no taller list items sticking down any more that might block the wrapping thumbnails.
If you can’t assign a fixed height to the li elements, though, perhaps because your thumbnails are pulled into the page dynamically and you don’t know what the largest height will be, there’s still hope. You’ll need to use something other than floats to get the thumbnails sitting side by side—and that something is display: inline-block.
An inline block mixes the attributes of block and inline elements. It’s placed on the same line as adjacent content, like inline elements are, but you can assign it width, height, margin, and padding, just like a block element.
Since inline block elements sit side by side by default, when you apply a display value of inline-block to the li elements, you can get rid of the float declaration:
li { display: inline-block; margin: 0 10px 10px 0; padding: 0; }
In browsers that support inline-block, that’s all you need to do to keep the thumbnails from hanging up on each other when they wrap (Figure 9.19). If you want the thumbnails aligned along their top edges, as they were when we used floats, simply add vertical-align: top; to the li rule.
Figure 9.19 When the thumbnails are turned into inline blocks, instead of floats, they no longer hang up on one another.
In browsers that don’t support inline-block, the thumbnails will just display straight down, each on its own line. These browsers include versions of IE earlier than 8 and versions of Firefox earlier than 3. Let’s take care of the IE problem first.
IE 7 and 6 support inline-block only on elements that are inline by default, so you can trick these browsers into making inline-block work by setting the list items to display: inline. Hide this rule inside a conditional comment that only IE 7 and earlier can read:
<!--[if lte IE 7]> <style type=”text/css”> li { display: inline; } </style> <![endif]-->
This fixes the problem in IE; now onto Firefox.
Versions of Firefox prior to 3 lacked support for inline-block but had their own proprietary values, -moz-inline-box and -moz-inline-stack, for the display property that worked almost identically. Add either of these values to the li rule:
li { display: -moz-inline-box; display: inline-block; margin: 0 10px 10px 0; padding: 0; vertical-align: top; }
This fixes the problem in Firefox 2 without hurting any other browsers, including Firefox 3—they all just ignore the -moz-inline-box value. If you have links wrapped around the images, however, you’ll have just a bit more work to do. Firefox 2 will position the images incorrectly and not make the entire image clickable when you nest a elements inside the li elements. To fix this, turn the a elements into blocks:
li a { display: block; }
Again, this doesn’t hurt other browsers.
Scaling the Thumbnails
If you want the thumbnails in your image gallery to scale instead of—or in addition to—wrapping, you need to add the scalable foreground image technique (that we went over earlier in the chapter) to the basic wrapping thumbnail gallery CSS.
The first step in making scalable foreground images, you may remember, is to remove the width and height dimensions from the img elements in the (X)HTML:
<ul> <li><img src=”january.jpg” alt=”January”></li> <li><img src=”february.jpg” alt=”February”></li> <li><img src=”march.jpg” alt=”March”></li> <li><img src=”april.jpg” alt=”April”></li> <li><img src=”may.jpg” alt=”May”></li> <li><img src=”june.jpg” alt=”June”></li> <li><img src=”july.jpg” alt=”July”></li> </ul>
Next, add a percentage or em width onto the li elements:
li { float: left; width: 18%; margin: 0 10px 10px 0; padding: 0; }
Finally, add a rule for the img elements that sets their widths to 100 percent so they always fill up the variable size of their parent list items:
img { width: 100%; }
The thumbnails now scale with the browser window (Figure 9.20).
Figure 9.20 The thumbnails still wrap to a small degree, but now their primary method of adjusting to the viewport is to scale with it.
If you want to avoid the blurriness or pixelation that happens when browsers scale images past their native dimensions, you can add a maximum width onto the images that matches their pixel widths:
img { width: 100%; max-width: 100px; }
When the thumbnails reach this max-width value, they will stop scaling. The list items, however, will not, so the images will appear to move farther apart from each other, still filling up the available space (Figure 9.21).
Figure 9.21 Once the thumbnails reach their maximum widths, they will stop scaling, but will still adjust to the viewport size by moving farther apart to fill the space.