28

In the following HTML, I'd like the frame around the image to be snug -- not to stretch out and take up all the available width in the parent container. I know there are a couple of ways to do this (including horrible things like manually setting its width to a particular number of pixels), but what is the right way?

Edit: One answer suggests I turn off "display:block" -- but this causes the rendering to look malformed in every browser I've tested it in. Is there a way to get a nice-looking rendering with "display:block" off?

Edit: If I add "float: left" to the pictureframe and "clear:both" to the P tag, it looks great. But I don't always want these frames floated to the left. Is there a more direct way to accomplish whatever "float" is doing?

.pictureframe { display: block; margin: 5px; padding: 5px; border: solid brown 2px; background-color: #ffeecc; } #foo { border: solid blue 2px; float: left; } img { display: block; }
<div id="foo"> <span class="pictureframe"> <img alt='' src="http://stackoverflow.com/favicon.ico" /> </span> <p> Why is the beige rectangle so wide? </p> </div>

6 Answers 6

33

The right way is to use:

.pictureframe { display: inline-block; } 

Edit: Floating the element also produces the same effect, this is because floating elements use the same shrink-to-fit algorithm for determining the width.

Sign up to request clarification or add additional context in comments.

2 Comments

Ugly, but out of the answers so far that actually work, this feels the least hacky to me.
The display: inline-block property prevents align-items from having an effect.
4

The beige rectangle is so wide because you have display: block on the span, turning an inline element into a block element. A block element is supposed to take up all available width, an inline element does not. Try removing the display: block from the css.

1 Comment

If I do that, then the image doesn't sit inside the frame -- did you actually try this, and does it look good in your browser?
4

Adding "float:left" to the span.pictureFrame selector fixes the problem as that's what "float:left" does :) Apart from everything else floating an element to the left will make it occupy only the space required by its contents. Any following block elements (the "p" for example) will float around the "floated" element. If you "clear" the float of the "p" it would follow the normal document flow thus going below span.pictureFrame. In fact you need "clear:left" as the element has been "float:left"-ed. For a more formal explanation you can check the CSS spec although it is beyond most people's comprehension.

Comments

2

Yes display:inline-block is your friend. Also have a look at: display:-moz-inline-block and display:-moz-inline-box.

Comments

0

The display: inline-block property prevents align-items or justify-content from having an effect.

So, in order to not mess with the alignment (that was the case with me), it's better to give this property to the parent.

.pictureframe { display: block; margin: 5px; padding: 5px; border: solid brown 2px; background-color: #ffeecc; } #foo { border: solid blue 2px; float: left; display: inline-block; //Add this } img { display: block; }
<div id="foo"> <span class="pictureframe"> <img alt='' src="http://stackoverflow.com/favicon.ico" /> </span> </div>

Comments

-2

The only way I've been able to do picture frames reliably across browsers is to set the width dynamically. Here is an example using jQuery:

$(window).load(function(){ $('img').wrap('<div class="pictureFrame"></div>'); $('div.pictureFrame').each(function(i) { $(this).width($('*:first', this).width()); }); }); 

This will work even if you don't know the image dimensions ahead of time, because it waits for the images to load (note we're using $(window).load rather than the more common $(document).ready) before adding the picture frame. It's a bit ugly, but it works.

Here is the pictureFrame CSS for this example:

.pictureFrame { background-color:#FFFFFF; border:1px solid #CCCCCC; line-height:0; padding:5px; } 

I'd love to see a reliable, cross-browser, CSS-only solution to this problem. This solution is something I came up with for a past project after much frustration trying to get it working with only CSS and HTML.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.