0

How can I set up a group of 3 divs (dynamic size and visibility) to automatically fill (height) a specific space on the page.

For example I have so far created:

<div id="container">
    <div id="details">...</div>
    <div id="video">...</div>
    <div id="map">...</div>
</div>

<div id="other_content">...</div>

The #container should be full width, with automatic height depending on the size of the largest child div.

The #details div should be displayed on left 'column' (this is normally the tallest div, but sometimes will be smaller than the combination of both #video and #map).

Both #video and #map divs should be displayed as right 'column' with #video on top of #map.

NOTE: #video is not always visible - in such cases #map should resize to height of #details (if larger) | or display as a minimum height (if #details is smaller).

CSS

#container {
    float: left;
}

#details {
    float: left;
    width: 290px;
}

#video {
    float: left;
    width: 560px;
}

#map {
    float: left;
    width: 560px;
    min-height: 345px;
    height: 100%
}

#other_content {
    clear: left;
}

I can't quite seem to get this to work, having a dynamically sized (height of largest child) container with all child objects displaying the full height.

kaipee
  • 55
  • 1
  • 5

2 Answers2

1

Generally speaking, floats aren't well suited for layout purposes.

For equal height columns, using the table display properties is your best bet for maximum browser support. First, you'll need to make a slight modification to the markup.

http://cssdeck.com/labs/eipgkxef

<div id="container">
  <div id="details">...</div>
  <div class="foo">
    <div id="video">...</div>
    <div id="map">...</div>
  </div>
</div>

#container {
    display: table;
    width: 100%; /* optional */
}

#details {
    display: table-cell;
    width: 290px;
}

.foo {
  display: table-cell;
}

#video {
    width: 560px;
}

#map {
    width: 560px;
}

Flexbox can be used to achieve the same effect (and you'll still need to use the extra element), but support for it is considerably lower than using this method.

http://codepen.io/cimmanon/pen/Ecerl

#container {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  /* fix for old Firefox */
  width: 100%;
}

#details {
  width: 290px;
}

.foo {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-box-orient: vertical;
  -moz-box-orient: vertical;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  -webkit-box-flex: 1;
  -moz-box-flex: 1;
  -webkit-flex: 1;
  -ms-flex: 1;
  flex: 1;
  /* fix for old Firefox */
  width: 100%;
}

#video, #map {
  -webkit-box-flex: 1;
  -moz-box-flex: 1;
  -webkit-flex: 1;
  -ms-flex: 1;
  flex: 1;
}
cimmanon
  • 67,211
  • 17
  • 165
  • 171
  • This almost works. If #container was 850px width, I need #video to display above #map. (your CSSSDeck doesn't reflect this code btw). – kaipee Jun 04 '13 at 14:54
  • Here is my updated code (http://cssdeck.com/labs/yv5zcaxr) which almost works. All I need is to make the 'right column' adjust its height automatically as the 'left column' does. – kaipee Jun 04 '13 at 14:59
  • I forgot to change the link to the demo (it's fixed now) when I modified the code. – cimmanon Jun 04 '13 at 15:04
  • Thanks cimmanon, though as you can see the .foo does not resize as #details div is expanded. However, the other way around works fine – kaipee Jun 04 '13 at 15:39
  • .foo *does* expand. You just can't tell because it has no background: http://cssdeck.com/labs/wz8ofmpq – cimmanon Jun 04 '13 at 16:01
  • Aah, yes .foo does expand, may apologies. But how do I then make #map fill 100% height as .foo expands? – kaipee Jun 04 '13 at 21:52
  • Styling .foo to give the illusion that #map is 100% tall isn't good enough? You'll have to go with Flexbox then (I added the solution for that earlier). – cimmanon Jun 04 '13 at 23:09
-1

If you are looking for a pure CSS solution, that works across browsers: it's not possible. CSS, in terms of how it's implemented in most browsers today, does not provide that kind of logic.

If you are open, though, to using JavaScript, you can write a small script that looks at the three div's in question, figure out which one has the largest height, and then assign the other div's that height. This SO answer is a good place to start.

There is hope, though, for the future of CSS - Flexbox is emerging, and will make this kind of layout easy to achieve. Basically, div's will be able to act like table cells of old.

Community
  • 1
  • 1
chipcullen
  • 6,840
  • 1
  • 21
  • 17