A: 

Make the container a table with table-layout:fixed and put the image in the top row. You can also do this with pure CSS using the display:table-* properties (and the IE7-js library for IE6 compatibility).

What table-layout:fixed does is make the table drawing algorithm lock the width of each table column once the width of the first cell in that column is known. The caption will have nowhere to expand to so it will wrap to the width of the image (the first cell).

SpliFF
Trying what you're describing; must be doing something wrong. <table border="1" style="table-layout: fixed;"> <tr><td>hello world</td></tr> <tr><td>hi there guys how are you?</td></tr> </table> as sample code seems to render the table as I usually see it - set by its widest column. Anything else I need to define?
Matchu
Its seems table-layout:fixed fails when table width is auto. I came up with a better solution though that works (see my other answer).
SpliFF
A: 

The table answer would work. Easily. I can't encourage its use but ease-of-use does have merit. I was going to suggest using the clip: CSS property, but I can't get it to work on my local machine (for some reason, though it renders the example at cssplay.co.uk perfectly).

The downside of this is that it probably only works if you define fixed-widths for the containers. I'm sure there must be a way, though. I'll keep looking.

David Thomas
+1  A: 

Check out this great article on the best ways of handling the image-with-a-caption scenario.

Personally this is one of those cases where you gotta suck it up and go with that works.

Paolo Bergantino
A: 

Alright, it looks like there's no simple solution that I can pull off. Thanks for helping me work that out :)

I think that, given how I'll be storing those images, accessing width won't involve constant recalculation. I may just use that server-side magic instead.

Thanks!

Matchu
A: 

Here's a solution that probably does not work for you even though it does produce the layout you requested:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
<html>

<head>
<style>
div.a {float: left;
     position:relative;}

div.b {
     position: absolute;
     top: 100%;
     left: 0;
     right: 0;
     text-align: center;
     background-color:gray;}

</style>
</head>

<body>

<div class="a">
<img src="http://stackoverflow.com/content/img/so/logo.png" alt="">
<div class="b">Caption text Caption text Caption text Caption text Caption text </div>
</div>

</body>
</html>

You see the reason why it is unsatisfactory if you place some content below the div a. It will overlap with the caption, because the absolutely positioned caption did not extend the parent div vertically. It still may work for you if you have enough white space below anyway or you are willing to reserve it.

buti-oxa
A: 

I asked basically this same question before. There may be some useful info there: http://stackoverflow.com/questions/617386/limit-text-to-the-width-of-sibling-image-auto-width-in-css

DisgruntledGoat
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