51

I have 2 nested divs inside outer one, which has width:100%. Both nested divs should be in one line and first should get it size from it's contents:

<div id="#outer" style="width:100%; border:1px">
  <div id="#inner1" style="border:1px; display:inline">
    inner div 1. Some text...
  </div>
  <div id="#inner2" style="width:100%????; border:1px; display:inline">
    inner div 2...
  </div>
</div>

Question is how to make #inner2 div to get rest of the horizontal space if width of the #inner1 div is not specified and depends on what it is inside?

P.S. All styles are in separate classes in my case, here I putted CSS into style attributes just for simplification.

I want result to work in IE7+ and FF 3.6

In more details for me it looks like this:

 <style type="text/css">
.captionText
{
 float:left;
} 

.captionLine
{
 height: 1px;
 background-color:black;
 margin: 0px;
 margin-left: 5px;
 margin-top: 5px;
 border: 0px;
 padding: 0px;
 padding-top: 1px;
}
 </style>
<table style="width:300px;">
<caption width="100%">
     <div class="captionText">Some text</div>
     <div class="captionLine"> </div>
</caption>
     <tr>
           <td>something</td>
     </tr>
</table>

Here is the image of what I want: Image of what I want

Artem
  • 7,275
  • 15
  • 57
  • 97
  • I know I can do it with tables, but I want to do it with divs – Artem Feb 04 '10 at 17:36
  • 1
    It probably wouldn’t be that obvious with tables either though. I’ve never quite understood the rules browsers use to calculate non-defined table column widths. – Paul D. Waite Feb 12 '10 at 12:51

10 Answers10

86

The mysterious overflow: hidden; is your friend here. It stops elements adjacent to floats from extending behind the float — I think that’s the layout you’re looking for.

Here’s some slightly edited HTML: I don’t think you can have # characters in your ids:

<div id="outer">
    <div id="inner1">
        inner div 1. Some text...
    </div>
    <div id="inner2">
        inner div 2...
    </div>
</div>

And here’s the CSS to achieve the layout you want.

(I put in additional CSS for IE 6 with HTML conditional comments. I just noticed you didn’t actually need it to work in IE 6 too, but if you fancy being nice to the IE 6 users out there...)

<style type="text/css">
#outer {
    overflow: hidden;/* Makes #outer contain its floated children */
    width: 100%;

    /* Colours and borders for illustration purposes */
    border: solid 3px #666;
    background: #ddd;
}

#inner1 {
    float: left;/* Make this div as wide as its contents */

    /* Colours and borders for illustration purposes */
    border: solid 3px #c00;
    background: #fdd;
}

#inner2 {
    overflow: hidden;/* Make this div take up the rest of the horizontal space, and no more */

    /* Colours and borders for illustration purposes */
    border: solid 3px #00c;
    background: #ddf;
}
</style>

<!--[if lte IE 6]>
<style type="text/css">
#inner2 {
    zoom: 1;/* Make this div take up the rest of the horizontal space, and no more, in IE 6 */
}

#inner1 {
    margin-right: -3px;/* Fix the 3-pixel gap that the previous rule introduces. (Shit like this is why web developers hate IE 6.) */
}
</style>
<![endif]-->

Tested and working in IE 6, 7, and 8; Firefox 3.5; and Chrome 4.

Paul D. Waite
  • 96,640
  • 56
  • 199
  • 270
  • 3
    @Eric I am the one who upvoted your comment, but then a coworker sent me [this](http://colinaarts.com/articles/the-magic-of-overflow-hidden/) which explains it. – Michael Feb 09 '12 at 22:10
  • @Michael: ah, excellent, thank you, I’ve never actually understood why/how `overflow` has this effect on floats. There was a Stack Overflow question on this the other day as well: see http://stackoverflow.com/questions/9193214/why-does-overflow-hidden-stop-floating-elements-escaping-their-container – Paul D. Waite Feb 09 '12 at 23:01
3

If you're reading this now you can probably use calc, so be thankful.

HTML

<div class="universe">
  <div class="somewidth">
  </div>
  <div class="everythingelse">
  </div>
</div>

CSS

.universe {
  width: 100%;
  height: 100%;
}

.somewidth {
  width: 200px;
  height: 100%;
}

.everythingelse {
  width: 800px; /* fallback for emergencies */
  width: calc(100% - 200px);
  width: -moz-calc(100% - 200px);
  width: -webkit-calc(100% - 200px);
  height: 100%;
}

See the working example on JSFiddle.

fiatjaf
  • 11,479
  • 5
  • 56
  • 72
0

You would need to float the inner1 div to the left, like so:

<div id="#outer" ....>
    <div id='#inner1" style="float:left; border: 1px solid #000;">
        blabla
    </div>
    <div id="#inner2" style="... DON'T USE WIDTH AND DISPLAY HERE! ...">
        gnihihi
    </div>
</div>

This should do the trick. Check it out! bye

aefxx
  • 24,835
  • 6
  • 45
  • 55
0

You do not need to use div for nested element, just use SPAN like this

 <div>
     <span style="display:inline-block;width: auto;border: solid 1px black;">
            hey you
     </span>
     <span style="display:inline-block;marging: 0px 2px;border: solid 1px black;">
           always use proper tools.
     </span>
 </div>
Nasser Hadjloo
  • 12,312
  • 15
  • 69
  • 100
  • looks like inline-block is not supported for IE7: http://www.quirksmode.org/css/display.html – Artem Feb 04 '10 at 17:00
  • @Artem — No, IE5.5 is the only version of IE on that chart which doesn't support it. – Quentin Feb 04 '10 at 17:21
  • Just for the record, in IE 7 and earlier, `display:inline-block;` is only supported on elements that are `display:inline;` by default — for example, it *is* supported on `` and ``, but *isn’t* supported on `
    ` or `
  • `.
– Paul D. Waite May 09 '12 at 07:48