Adapting a block and a caption to the width of an image

How do you make a block containing an image fit the width of that image, and how do you make its caption automatically span several lines if necessary? CSS provides answers to these questions.

How to make an illustration block with an image and a caption that would respect the following two criteria: first, the block must adapt to the width of the image; second, the text given in the caption must never exceed the width of the image, and will go on several lines if necessary.

The easy solution would be to freeze the width of the block and always work with images of the same dimensions. But CSS allows us to be a little more subtle. Let me remind you of our conundrum: we want to create an illustration block composed of an image of variable width and a caption of variable length. What is the most efficient way to do this?

The answer lies in using a “table” type rendering… Come on, don’t panic! You’re probably already familiar with some of the rendering types in CSS: inline, block, etc. I’m talking about the display property values, which are not limited to these few commonly used values, but also include inline-block or table, table-cell, and others.

The trick is this: the behavior we want to achieve corresponds to a property of tables. (A quick reminder: yes, tables, or rather their rendering, are useful for layout. I won’t go back to that point).

1. display : table; which allows us to use the desired HTML elements and pass them to a table or table cell display;
2. HTML elements table, tr, td, etc.

The first solution is compatible with all recent browsers, including IE 8, but not IE 6 and 7. So we’ll see the two solutions in turn.

Here is what our illustration block might look like, on the HTML side:


Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam.

One image, two paragraphs, all in one div. With a little layout, you get a caption that is longer than the width of the image.

Let’s say we want to place this block as a floating box on the right of a content (the text of an article for example). If we just use float: right;, because of the second paragraph which is a bit long, our floating block will take all the available width in the container, and the content will be placed under the float and not to its left.

Our problem, then, is that any text that is a bit long will expand our float beyond the width of the image.

We could prevent this behavior with the width property, but then our illustration block will always be the same width, and we’ll have to adapt our images. Why not, but here we’re looking for the opposite effect: a block that adapts to the image.

Table cells adapt to their content. To say this is a huge shortcut, because the algorithms for displaying tables are complex. However, if a browser is asked to display a table cell of 50 pixels wide (for example), and the content cannot be “compressed” to that width by making the text go to the line, the cell will adapt to the longest content: image, fixed-width block, word or string too long, etc.

We will use this behavior. We’ll ask for a reduced width for our illustration block (200 pixels, to avoid a too small width if the image is not displayed), and it will adapt to our image if it is wider than this basic width.

                           .illustration {
 display: table;
 width: 200px;
 float: right;

I’m only listing the essential styles here. The rest is cosmetic. […]

The result is correct with all modern browsers, but not with Internet Explorer versions 6 and 7. It should be correct with IE 8 ( display: table support announced).

For an IE 6 and 7 compatible version, we have to switch to the equivalent system, with a table in the HTML code.

So we replace our div in the illustration block with a single cell table:


Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Sed non risus. Suspendisse lectus tortor, dignissim sit amet,
adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam.

The behaviour is the same as before. We just had to correct some default styles of the browsers for the tables.

We can summarize the CSS code for these two examples. Here is the first one:

And the second example (with its cosmetic corrections for the tables):

Leave a Comment