2

I'm trying to make a child div of a flexbox layout fill its parent. In any other context setting the width/height to 100% causes a div to fill its parent... I only wish to use flexbox for my top level layout.

Problems

  • #map-container div will not fill #col1 even though it has height 100% set.
  • #controls div appears outside #col1 completely. I've previously used absolute layout to align boxes to corners without problems. Being inside a flexbox grand-parent seems to cause issues.

What I'm expecting is #map-container and #map to fill #col1 and #controls to align to bottom right-hand corner of #map.

.wrapper, html, body {
    height:100%;
    margin:0;
}
#col1 {
   display: flex;
}
#map-container {
    background-color: yellow;
    width: 100%;

  height: 100%;    
}
#map {
    background-color: purple;    
    width: 100%;
    height: 100%;
}
#controls {
    background-color: orange;    
    position: absolute;
    right: 3px;
    bottom: 3px;
    width: 100px;
    height: 20px;
}
.wrapper {
    display: flex;
    flex-direction: column;
}
#row1 {
    background-color: red;
}
#row2 {
    flex:2;
    display: flex;
}

#col1 {
    background-color: green;
    flex: 1 1;
}
#col2 {
    background-color: blue; 
    flex :0 0 240px;
}
<div class="wrapper">
    <div id="row1">Header</div>
    <div id="row2">
        <div id="col1">
            <div id="map-container">
                <div id="map">
                    Map
                </div>
                <div id="controls">Controls</div>
            </div>
        </div>
        <div id="col2">Sidebar</div>
    </div>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Adam
  • 35,919
  • 9
  • 100
  • 137

2 Answers2

3
  1. #map-container div will not fill #col1 even though it has height 100% set.

It won't work that way, because for a percentage unit to work, it needs to have height set on its parent all the way up. This fights against the flex model, where the flex-items are distributed and arranged by the flex-box layout and have no dimensions set. Why use a flex layout when all your elements are 100%? Either do a 100% on all your element all the way up, or do a flex on all containers.

If you stick to flex layout, then you will have to get into nested flex. Otherwise, you will get #map-container to fill-up, but not the #map.

This fiddle http://jsfiddle.net/abhitalks/sztcb0me illustrates that problem.

  1. #controls div appears outside #col1 completely. I've previously used absolute layout to align boxes to corners without problems. Being inside a flex-box grand-parent seems to cause issues.

The only issue is that you are positioning it absolutely, but in relation to what? You need to position your #map-container relatively for that to work.

Here is how:

Fiddle: http://jsfiddle.net/abhitalks/sztcb0me/1/

Snippet:

* { box-sizing: border-box; padding: 0; margin: 0; }
html, body, .wrapper { height:100%; width: 100%; }
.wrapper { display: flex; flex-direction: column; }
#row1 { flex: 0 1 auto; background-color: red; }
#row2 { flex: 2 0 auto; display: flex; }
#col1 { flex: 1 0 auto; display: flex; background-color: green; }
#col2 { flex: 0 0 240px; background-color: blue; }
#map-container { 
    flex: 1 0 auto; display: flex;
    position: relative; background-color: yellow; 
}
#map { flex: 1 0 auto; background-color: purple; }
#controls {
    background-color: orange;    
    position: absolute;
    right: 3px; bottom: 3px;
    width: 100px; height: 20px;
}
<div class="wrapper">
    <div id="row1">Header</div>
    <div id="row2">
        <div id="col1">
            <div id="map-container">
                <div id="map">
                    Map
                </div>
                <div id="controls">Controls</div>
            </div>
        </div>
        <div id="col2">Sidebar</div>
    </div>
</div>
Abhitalks
  • 27,721
  • 5
  • 58
  • 81
  • 1
    Thanks for your answer and clear explanation. The reason I was mixing and matching layouts was because #map is actually a third-party widget (Cesium JS library), this brings along height:100% on various nested levels. I was trying to get the two concepts to play nicely, I didn't mention this in the question as things were complicated enough! – Adam Oct 28 '15 at 07:14
  • Thanks @Adam. If you wish you could also very easily use a percent-based fluid layout without flex in this case. See here - http://jsfiddle.net/abhitalks/eqv0jm42/1/ – Abhitalks Oct 28 '15 at 07:38
0

the problem is that it's wrapped in #map-container

.wrapper, html, body {
    height:100%;
    margin:0;
}
#col1 {
   display: flex;
}
#map-container {
    background-color: yellow;
    width: 100%;

  height: 100%;    
}
#map {
    background-color: purple;    
    width: 100%;
   /* height: 100%; */
   display: flex;
   flex-wrap: wrap-reverse;
   justify-content: space-between;
}
#controls {
    background-color: orange;    
    position: relative;
    /*right: 3px;
    bottom: 3px;*/
    width: 100px;
    height: 20px;
    
}
.wrapper {
    display: flex;
    flex-direction: column;
}
#row1 {
    background-color: red;
}
#row2 {
    flex:2;
    display: flex;
}

#col1 {
    background-color: green;
    flex: 1 1;
}
#col2 {
    background-color: blue; 
    flex :0 0 240px;
}
<div class="wrapper">
    <div id="row1">Header</div>
    <div id="row2">
        <div id="col1">
            <!-- <div id="map-container"> -->
                <div id="map">
                    Map
                  <div id="controls">Controls</div> <!--  add it here -->
                </div>
            <!--    <div id="controls">Controls</div> -->
            <!--</div> -->
        </div>
        <div id="col2">Sidebar</div>
    </div>
  
</div>

adding an absolute position controls in that way is not optimal (in the snippet I commented it out) ; you can place the controlsnested in #map (and use flex properties for correcting placement)

maioman
  • 18,154
  • 4
  • 36
  • 42