August 13th, 2008 - by Paul OB

This article details how to produce a product category list with associated images and text. This is the sort of thing you would see if you did a search on Amazon.

I am going to start by showing the finished product as this will help you visualize what we are going to achieve along the way. Figure 1 below shows a smaller version of the task ahead.

Figure 1

We are going to make a similar display but without using tables as in my view the information presented is not tabular and does not have a logical correspondence between rows and columns. Even if you do present a good case of why this should be in a table, please don’t comment on this as we are interested in the layout techniques rather than perfect semantics (for this example). The techniques presented here can be used in other layouts that are certainly not tabular and will prove useful in many situations.

Define Your Content

The first thing we need to do is decide what elements we are going to use to style this category list. That’s your first clue – we should already be thinking about using a list to do this. However, I feel that information like this is more suited to a definition list (DL) as the product name is the data term (DT) and the description underneath is the data definition (DD). (Feel free to disagree but whatever method you choose the techniques used to construct our layout will likely be the same.)

I’m using a Definition List which will allow us to semantically describe the heading and the associated text that describes the heading.

Although definitions have default styling applied, such as margins, we can simply get rid of that using one of the many reset techniques available. I am using a global reset for purposes of the demo but I suggest you look into more thorough methods.

Lets’ start by thinking about what we want to achieve.

The image needs to be at the left of the layout and the text needs to be lined up nicely alongside the image but we don’t want the image to wrap underneath the image as that looks a little messy in a list like this.
e.g. Not like this:
Figure 2

As you can see the last line of text wraps under the image rather spoiling the effect so we will look at how to overcome this problem without complicating the issue too much.

The image can be floated to the left and we can apply a right margin to push the text away at the side. So for a start we will do just that and see what our display looks like.

HTML

  1. <dl>
  2.     <dt><img src="images/product.jpg" alt="Product image" width="93" height="62" /><a href="#">The Name of the Product Goes here</a></dt>
  3.     <dd>
  4.         <p>The description of whatever the heading is about goes here. The description of whatever the heading is about goes here.The description of whatever the heading is about goes here. The description of whatever the heading is about goes here. The description of whatever the heading is about goes here.The description of whatever the heading is about goes here.</p>
  5.     </dd>
  6. </dl>

CSS:

  1. *{margin:0;padding:0}
  2. p{margin:0 0 .5em 0}
  3. dl{
  4.     width:640px;
  5.     margin:0 auto;
  6.     border-bottom:1px dashed #ccc;
  7.     padding:10px;
  8.     overflow:hidden;
  9.     background:#f2f2f2;
  10. }
  11. dl img{
  12.     float:left;
  13.     margin:0 10px 0 0;
  14.     border:1px solid #000;
  15. }

If you run the above small code sample you will see a display almost exactly as that shown in Figure 2 above. The image is floated nicely to the left and the text wraps to the right side of the image except that the last line wraps under the image.

We will address that issue in a moment but it’s important to mention at this stage that floats are removed from the flow and if you want them to stay inside your container you must use some sort of clearing mechanism. Otherwise the float will float out of the container and poke into the container below should content be less than the height of the image.

In our example I have added overflow:hidden to the dl container which will ensure that all floats are contained within. Overflow other than visible will cause elements to contain their floated children in most modern browsers. IE6 needs “haslayout” to be true and then it will auto clear floats also. This can be achieved by setting a dimension which we already have in place so no extra hacks are required. Overflow isn’t always the most suitable clearing mechanism to use but in simple layouts it works well but you should investigate other clearing techniques also.

Additionally, note that I have placed the image inside the dt element because the product image and it’s title are really the same thing.

Stopping The Text From Wrapping

Usually authors would apply a left margin to the text content to make it steer clear of the image but this is not the best solution for three main reasons:

1) Firstly your images may be supplied dynamically and be of varying widths and therefore your left margin approach would fail unless you set a width wider than all the images.

2) The second problem would be that IE6 has a “3px jog” on static content next to a float and would make the display look slightly odd. Sometimes this is barely noticeable but it can still be annoying.

3) Lastly and more importantly, if you have floated content mixed in your content description section and you try to clear them you will end up clearing all floats and the whole description drops below the float. Figure 3 shows an example of this.

Figure 3

(Example shows what happens when a float (the red box) is cleared)

Luckily there is a simple method we can turn to that cures all these problems quite easily. (As an aside this method was also exploited earlier in one of John’s Articles.) If we once again use overflow other than visible on this content we can make it form a rectangular box to the side of the image and also honoring the image’s margins. It’s almost as if we have floated another block to the side except that we haven’t.

The overflow:auto (or overflow:hidden) causes the element to form a rectangular block that will not only stay at the side of the floated image but will also contain any floated children. As another bonus It will also contain the effect of any clearing of floats in that section. Float clearing from within that overflow:auto container will be restricted to that container only and not just clear all floats above in the HTML as per usual.

The overflow method doesn’t work in IE6 but fortunately forcing “haslayout” on the element concerned has exactly the same effects and with an added bonus of partially curing the “3px jog” mentioned earlier. As we don’t want a dimension in this container we can use the height:1% hack supplied via the star selector hack to target IE6 and under only.

  1. * html dd{height:1%}

Therefore all we need to add to the CSS already shown is this:

  1. dd{overflow:auto}
  2. * html dd {height:1%}

If you run that code you will get a display similar to Figure 1 above.

The only extra element in Figure 1 is that I have placed some text to the right of the product title. I did this by placing the text in a strong element and floated it to the right. However as floats need to be in front of the content that they will wrap (except for inline content on the same first line as the float but few browsers obey this anyway so its not worth arguing about) I have moved the strong element in front of the product description as follows.

  1. <dt>
  2. <img src="images/product.jpg" alt="Product image" width="93" height="62" />
  3. <strong>Some info text here</strong>
  4. <a href="#">The Name of the Product Goes here</a>
  5. </dt>

There you have it. With relatively little code we have avoided a number of bugs and behaviors and produces a nice looking layout. I mentioned earlier that our fix only partially cured the 3px jog and the eagle eyed among you will note that although there is no jog on the content it does happen to be 3px further away than other browsers. If this is an issue for you then you can always offset this with a hack that applies 3px less right margin on the image. However I don’t think many people will notice so I am not bothering to apply another hack.

The finished layout can be found here and I suggest that you copy the code from the demo itself (view source) if you want to practice these techniques.

8 Responses to “My CSS is Cat -(Categories With CSS)”

1 Golgotha

Paul, that is a great article, I’m sure I will be returning to it in the future.

2 Paul OB

Thanks Mark, I’m always coding similar structures for my clients so I’m sure it will be useful to someone :)

3 me

The semantics are OK btw;-)

4 Create a Amazon-like product listing using CSS

[…] CSS Tutorial on how to produce a product category list with associated images and text. The final result should look like this […]

5 Jon

Thanks for this, I used the margins solution with conditional styles for IE on a situation recently, but I will definately return to yours the next time!

6 Prawydh

Great thing!

7 Johan

Will adding a link to the image have an impact on the display?

8 Paul OB

Hi Johan,

If you put a link around the image then just apply the rules that were originally applied to the image and apply them to the anchor instead and it will be fine :).

mulberry sale spyder womens jacket cheap new balance 574 mulberry outlet cheap new balance 574 arcteryx outlet mulberry sale spyder womens jacket mulberry sale spyder womens jacket mulberry outlet mulberry outlet new balance 574

Popular Articles

Top 10 Commentators


Subscribe to this feed! Subscribe by Email!

Random Bits Podcast

Blogs Worth Reading