views:

44

answers:

6

How can I achieve a layout like this?

Right now I'm using this HTML:

<div class="image">
  <img>
  <div class="caption">
    Caption Text
  </div>
</div>

And this CSS:

.image {
  background-color: #2A2A2A;
}

img {
  max-width: 590px;
}

But the .image box is too big (since it expands to fit its parent):

alt text

A: 

If you set the width of the .image box to the same width as the image, then apply padding to the .image box, you will get the border you are looking for because when you specify width, padding gets added to it.

So basically, you would need the following CSS:

.image {
    padding: 10px;
    width: 300px; /* assuming the picture is 300px */
}
Jared
But I don't know the width of the image ahead of time. I.e., I want the `.image` boxes to be able to hold images of all different widths
Horace Loeb
A: 

Since divs are block-level elements, they expand to fit their parent.

It may not be the best solution, but if you don't know the size of the image ahead of time, you could do the below:

.image
{  
    padding: 10px;
    max-width: 590px;  
    disply: inline;  
}

.caption
{  
    background-color: #2A2A2A;
    disply: inline;  
}

The above will cause the img div to be rendered as an inline element which will shrink it to fit the content rather than its parent, and the padding will add the border.

Kyle Lowry
But then I can't enclose the caption part in the `.image` box
Horace Loeb
A: 

Try the following:

.image {
    position: relative;
    width: 250px;
}
img {
    border: 15px solid #777777;
    -moz-border-radius: 10px;
    -webkit-border-radius: 10px;
    border-radius: 10px;
    width: 100%;
}
.caption {
    border-left: 15px solid #777777;
    border-right: 15px solid #777777;
    border-bottom: 15px solid #777777;
    position: absolute;
    width: 100%;
    bottom: 0px;
    -moz-border-radius: 10px;
    -webkit-border-radius: 10px;
    border-radius: 10px;
}

<div class="image">
    <img src="yourImage" height="150px" />
    <div class="caption">
        Caption TextCaption TextCaption TextCaption TextCaption Text
    </div>
</div>

Now the reason I have applied 3 borders to the caption div is because you do not know the width of the image without the border, but you do know the width of the border for the image. Applying the same border to the caption will give the caption the same width. Of course you will need to adjust the width of .image and the height of the img tag (this can be done through css), but the rest will be done for you. Also the caption div will resize for larger captions.

Regards,

Richard

PS this code has been tried and tested in Chrome - it works fine.

ClarkeyBoy
+2  A: 

The key is to not set a width for the img element, or the parent container. If the parent, .image is simply floated or in any other way adapted so that it shrinks to the size of its contents, this should work.

I used float to achieve the shrink-wrap aspect, but position: absolute; would do the same, as would display: inline-block;.

There's a demo over at JS Bin, which uses some jQuery to swap the images around, but it does nothing to the width of any elements. The CSS is reproduced below:

  .image {
    float: left;    // for the shrink wrap
    padding: 1em;   // To achieve the bordered effect
    background-color: #666;  // just for contrast
    -moz-border-radius: 2em;  // for that web 2.0 goodness...
    -webkit-border-radius: 2em;
    border-radius: 2em;
  }
  .image img {
    -moz-border-radius: 2em;    // no width, anywhere. Presumably width: auto, would  
    -webkit-border-radius: 2em; // work, but that's redundant, since it's the default
    border-radius: 2em;
  }
  .image img + .caption {
    width: 100%;              // forcing the .caption to take up 100% of the width
    background-color: #ffa;   // of its parent, except for the padding, so that it's
  }                           // the same width as the image above.
David Thomas
@David Thomas: I dont think this quite works (although I have not tested it - I am about to). I have posted another answer with some extra code.
ClarkeyBoy
@ClarkeyBoy, the diagram in the question makes mention of *aligning* the caption with the image's sides, it doesn't say anything about the image appearing *over* the image itself. Or have I gone blind? ...it's been a long day, this *is*, sadly, quite possible.
David Thomas
I was correct - this method makes the caption appear below the image. Also if you have the image in from the left, the caption appears all the way along (100% of the page width). If you look at the first example, with the question "How can I achieve a layout like this?" just above it, the image has the caption at the bottom left, about 5 pixels inside the border. The border is dark grey, about 15px with a radius of 10px. I have achieved this in my second answer (couldnt have done it without this answer though).
ClarkeyBoy
be wary though: the display: inline-block; is not fully supported by IE6 (http://www.quirksmode.org/css/display.html), furthermore, IE 6-7 accept this value only on elements with a natural display: inline.Also, using absolute positioning in order to fit the box to its contents, while achieving your main goal, also removes the element from the document flow, possibly causing you more trouble than worth..
Lucius
The problem with floating the `.image` `<div>` is that it stops appearing between paragraphs (because it's floated left). What if I want the image + caption to appear between paragraphs? (The `inline-block` method works, but isn't the most compatible)
Horace Loeb
+1  A: 

As @Kyle said, block elements adjust their width to fit their parent's. Setting a block element as inline though, is not the correct approach: what you need to do, is to set the .image div as a floating element, thus achieving a similar result, while keeping the features of a block element. The css to do the trick should be:

.image {
  float: left;
  display: inline; /* needed to fix the (IE <= 6) "3 pixels out of nowhere bug" */
  /* whatever code you may find appropriate in order to render the rounded border */
}
.image .caption {
  clear: left;
}

I left to you any further style improvement you may feel needed.

Lucius
A: 

I have come up with another solution. I dont believe David Thomas' answer makes the caption appear within the image (by all means correct me if I am wrong), so try the code below (I have used a combination of my code and Davids).

.image {
    position: relative;
    float: left;
    border: 15px solid #777777;
    -moz-border-radius: 10px;
    -webkit-border-radius: 10px;
    border-radius: 10px;
}
.caption {
    position: absolute;
    bottom: 5px;
    left: 5px;
}
.image-container {
    position: relative;
}

<div class="image">
    <img src="/Images/header1.png" />
    <div class="caption">
        Caption Text Caption Text Caption Text Caption Text Caption Text Caption Text Caption Text Caption Text Caption Text Caption Text
    </div>
</div>
ClarkeyBoy