为什么 `height: 100%` 和绝对定位在 flexbox 中不起作用?

Why isn't `height: 100%` and absolute positioning working in flexbox?

我正在尝试让 flexbox 布局的子项 div 填充其父项。在任何其他上下文中,将 width/height 设置为 100% 会导致 div 填充其父级...我只想将 flexbox 用于我的顶级布局。

问题

我期望 #map-container#map 填充 #col1#controls#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>

问题是它被包裹在 #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>

以这种方式添加绝对位置 controls 并不是最佳选择(在代码片段中我将其注释掉);您可以将 controls 嵌套在 #map 中(并使用 flex 属性来更正位置)

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

它不会那样工作,因为要使百分比单位工作,它需要在其父项上一直设置高度。这与 flex 模型相冲突,在该模型中,弹性项目按弹性盒布局分布和排列,并且没有设置尺寸。 当所有元素都是 100% 时,为什么要使用 flex 布局? 要么对所有元素一直向上执行 100%,要么对所有容器执行 flex .

如果您坚持使用弹性布局,那么您将不得不进入嵌套 flex。否则,您将得到 #map-container 来填充,而不是 #map.

这个 fiddle http://jsfiddle.net/abhitalks/sztcb0me 说明了这个问题。

  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.

唯一的问题是你对它的定位是绝对的,但是相对于什么?你需要相对定位你的 #map-container 才能工作。

方法如下:

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

片段:

* { 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>