Shrink-to-fit block elements

If I throw a block-level element into my page, the default display runs the width all the way across the screen. If you add borders to the element, this creates long rectangles.

When this hasn’t worked in my designs, I’ve set the width to an em or %. However is there a way to set the width on a block level element to simply fit to the width of the content inside?

…or display:inline-block

:smiley:

This is working gorgeously. I did stick both paragraph declarations for the caption into one style rule. In IE6, this is working fine, though I’ve never written JS inline in a stylesheet before. Here’s what I’ve got in my new IE7 and below stylesheet. Is this fine? Or is there a reason to break the fallback and JS-set widths out into two separate style rules?

.caption {
width: auto
}

.caption p {
width:150px; /* Fallback width if javascript is off */
width:expression(this.parentNode.offsetWidth-22);
}

In any case, I’m very happy if you can’t tell. The display: table; definitely needs that width: 1px; to work right, but the behavior in ACID2-compliant browsers is exactly what I was looking for.
:nanaman: :Partier: :nanaman: :Partier: :nanaman: :Partier: :nanaman: :Partier:

I guess you could always add <br> tags to the text, but it’s not a very nice solution. I’m sure there is a JS solution, but that’s beyond me.

…or position absolute

Yep.

div {float: left;}

Hi,
I have an example that meets your needs, it is based off of one of the CSS quizzes we had a while back. The trick is to use display:table for the container and set the width to 1px. It will exhibit table behavior then and auto-size it’s width according to any child with a fixed width, the image.

Auto Width Image Captions

Of course IE6/7 do not support display:table so they get a little help from a js expression.

:slight_smile: I love both these solutions. Thanks guys! I liked getting things nailed down to the point where the images and captions played well together, but I really wanted to add the ability to cope with text whatever the length. Based on your description, Rayzur, it sounds like this is what your technique boils down to? I’m definitely going to play around with this a bit, and I love that you’ve adjusted this to cope for <IE7 possibly being without a JS option. Then using that as a baseline, I can play with Kalon’s solution to restore full function if JS is available.

Kalon, that’s so absurdly simple, it’s brilliant; grabbing the image’s fixed width and adjusting the container to a fixed width to match. It’s not something I would ever have thought of, because I think in fluid layouts, but this is a case where it should be a fixed width because we’re stuck with the fixed width of the image that we are trying to accommodate. One of those things that a pain to figure out, but which is so simple afterwards, that it’s the obvious solution. I’m just learning jQuery and will probably play around with implementing it that way; I bet we can reduce this little function to one line.


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

.left {         
float:left;         
clear:left;     
}     

.right {         
float:right;         
clear:right;     
}     

.caption img {         
display:block; 
 }

 <!--[if lte IE 7]> 
<style type="text/css"> 
.caption {width:auto;} 
.caption p {width:150px;} /* Fallback width if javascript is off (smallest img width less "p" margins)*/
.caption p {width:expression(this.parentNode.offsetWidth-22);} /* The offset accounts for all box properties*/ 
</style> 
<![endif]--> 

Actually <br> tags don’t work. You can’t depend on the size of the user’s text. That’s one of the reasons I like working in elastic and fluid designs that morph and adapt to screen resolution, browser configuration, the portion of the screen occupied by the viewport, custom user stylesheets, etc., etc.

I will credit both of you actually. :slight_smile:

I’ve got the results posted here if you’d like to see the final result.

http://www.earthchronicle.com/EC/Content/Computers/Programming/~OOCSSGallery.aspx#advancedCaptions

It seems to work great in all the browsers I’ve got except IE8 with compatibility view on. However, this is also the first time I’ve used an “lte IE 7” stylesheet. I’m wondering if the problem is just that compatibility view is mimicking IE7 behavior, but since it’s IE8 it’s not referencing the conditional styles?

If you’re interested in a javascript soluton, this demo set the width of the div containing the image and text to whatever the physical width of the image is in pixels.

The text then wraps to stay within the container div.

 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<style type="text/css">

#container {
 border: 1px solid red
}

</style>
<script type="text/javascript">

var picO = new Image();
picO.src = 'pic1.jpg';
window.onload=function() {
        document.getElementById("myPic").src = picO.src;
        //set the container div width to the pic width
        document.getElementById("container").style.width = picO.width+'px';
}
</script>
</head>
<body>
 
<div id="container">
 
<img id="myPic" src="" alt="">
 
<p>
Lorem ipsum dolor sit amet, tellus et. Molestie auctor nisl faucibus ut, lorem tortor mattis, fusce nullam enim fringilla vel. 
Mauris vitae gravida dolor praesent. Id in nascetur aut odio, nam et. Pede libero bibendum sit felis pretium sodales, fusce 
pharetra vestibulum bibendum morbi ultricies nullam, est nulla, id amet mollis. Nec consectetuer urna dapibus luctus ut, 
ipsum nascetur consequat dapibus dui ac molestie, est nascetur id nec nunc. Mi etiam mauris facilisi sed, nec ut id, 
aliquam non, taciti donec ut. 
</p>
 
</div>
 
</body>
</html>


Is this fine? Or is there a reason to break the fallback and JS-set widths out into two separate style rules?
Hi,
Yes, that should be fine. There was no specific reason for the two separate rules in my example. The expression width just needs to override the defined width as you have it. Then if js is turned of it will fallback to the defined width. :wink:

The display: table; definitely needs that width: 1px; to work right
Yes, that it what allows it to exhibit table behavior and stretch it’s width according to any child with a fixed width. That is also what restricts the fluid width <p> from forcing it to 100% width.

Glad you found it workable, credit goes to Paul OB’ for that method. :slight_smile:

That’s interesting. I’ve done floats and absolute positioning before, but obviously that affects the position of the element; not to mention both those techniques remove the element from the document flow. Many times that’s fine, but I’d never looked at the more exotic options available for display.

I found this very interesting page @ Quirks mode discussing and demonstrating the various options for display http://www.quirksmode.org/css/display.html

Float is definitely an option for what I’m working on though. I’m trying to build a component that will fit to the size of an image, and let me caption a random amount of accompanying text as a caption, just like a newspaper. To match that look I need the text to…

  1. start under the image
  2. wrap if the text of the caption exceeds the length of the image

It’s been giving me trouble, because one element, the image needs to be able to force the container element to whatever size is necessary, but the other element, the text, needs to wrap when it reaches the edge of the container. So far I’d floated the container to get it to match the image size, and my best results so far are by applying a display: block; to wrap it under the image. However, this requires you to match the text to length of the image, because the text doesn’t wrap, it stays on one line and pushes the container sides out which looks pretty crappy.

Don’t bother trying to get IE8 compat view fixed. It’s not real IE8. That doesn’t quite mimic IE7 behavior btw :).