views:

3057

answers:

6

I am essentially trying to create a version of the "figure" element (upcoming in HTML5), whereby I have an image with a short description below it.

However, I want to limit the width of this entire element to that of the image, so the text isn't wider than the image (wrapping to multiple lines if necessary).

Basic HTML:

<div class="figure">
<img src="..." alt="..." width="..." height="..." /><br />
A description for the image
</div>

I'm well-versed with CSS but I can't think of any pure CSS solution, without adding a style="width:100px" to the div to match the image width.

Update: After a bit of searching and thinking, the best method seems to be using an inline width on the div. I will keep the width attribute on the image, in case I wish the div to be a bit wider than the image (for example to accomodate a longer caption).

This approach also means I could have two images side-by-side with a caption below. If I have a set of images the same size, I can of course add an extra style to each div.

Thanks to everyone who answered!

A: 

For setting the width to match the image automatically you could use

.figure {
  display: table;
  width: 1px;
}

This makes the div behave like a table (not supported in Internet Explorer). Or you could use a table instead of the div. I don't think there is another way of setting the width automatically.

Edit: The simplest way is to forget about the auto width and set it by hand. If it is really needed you can use JavaScript or a table. In this case the use of a table is not so ugly because you are addressing a limitation of the HTML version. In the case of server-side scripting you could also set the width when generating the page.

Angel Chiang
Your example by setting the display doesn't work in IE7. Not sure about IE6.
strager
According to http://www.quirksmode.org/css/display.html it's not supported by released versions of IE. I guess the only option then is to use a table.
Angel Chiang
A: 

You could use the display:table solution for all other browsers, and a CSS Behaviour for Internet Explorer.

doekman
+1  A: 

Stylesheet

div.figure * { width: 100% }
div.figure div { overflow: hidden; white-space: nowrap; }

note: to enable wrapping just remove that last css line

HTML

<div class="figure" style="width:150px;">
    <img src="logo.png" alt="logo" />
    <div>A description for the image</div>
</div>

I've checked it in Chrome, Firefox and IE7 and it looks good in all three. I realise this has the width on the div and not the img, but at least you only need to set the width in one place. Short of using css-expressions (IE only) I can't see a way of setting the outer divs width to the width of the first child element.

Antony Scott
I normally put a width/height on images because it's better for browser rendering - no layout jumping as the page loads, and the layout is preserved when images are unavailable. In this case I guess I'd put a height on the image and it would inherit the width.
DisgruntledGoat
Also the * selector is a bad idea. I could have more elements in the caption (eg links) that might get messed up. It should be replaced with simply `img` (`duv` is 100% by default)
DisgruntledGoat
fair comment on the * selector
Antony Scott
+2  A: 

I had the same problem and after reading this decided to use an inline-style on the surrounding element. Seems the better solution over using a table to me.

A: 

I came up with a working and fairly clean solution.

The solution uses a table (or div with display:table if you prefer) and adds a second column to "push" the first cell into the minimum space it really needs. The table can be set to 1px width to stop it growing across the page. I've put together a demo to show this in action:

http://test.dev.arc.net.au/caption-layout.html

Tested and working in IE8, Firefox and Safari/Win

SpliFF
Thanks for another solution, but the point of the question was to avoid unsemantic and unnecessary markup. As I posted in my question, setting a width on the outer div is generally a better solution for more control. I'm mixing style with the HTML but sometimes you have to. :)
DisgruntledGoat
A: 

ok, I am trying the table solution which was working, at least it seemed like it was but now it seems to have broken in chrome. I have narrowed the problem to nested divs within the table - why would these interfere with the table's behaviour? I have an image inside the div which is inside the table and the table isnt stretching to fit anymore - anyone have any ideas why>

oompa_l