Неверная высота в flexbox элементах в Chrome
У меня есть тонкая проблема для любого гуру CSS там.
Мой зеленый div имеет гибкую высоту, занимая оставшиеся.
И теперь я хочу поставить div внутри этого div, который должен быть половиной зеленого div. Но похоже, что Chrome относится к нему как к половине всей страницы, а не к элементу flex.
http://jsfiddle.net/unh5rw9t/1/
HTML
<body>
<div id="wrapper">
<div id="menu">
1
</div>
<div id="content">2
<div id="half_of_content">2.1</div>
</div>
<div id="footer" style="">
3
</div>
</div>
</body>
CSS
html,body {
height: 100%;
margin: 0;
}
#wrapper {
display: flex;
flex-flow: column;
height: 100%;
}
#menu {
height: 70px;
background-color: purple
}
#content {
flex: 1;
height: 100%;
background-color: green;
}
#half_of_content {
height: 50%;
background-color: yellow;
}
#footer {
height: 100px;
background-color: cyan
}
Ответы
Ответ 1
Вы можете полностью позиционировать div id="half_of_content"
.
#content {
flex: 1;
height: 100%;
background-color: green;
position: relative; /* new */
}
#half_of_content {
height: 50%;
background-color: yellow;
position: absolute; /* new */
width: 100%; /* new */
}
DEMO
Что касается вашего заявления:
Но похоже, что Chrome относится к нему как к половине всей страницы а не элемент гибкости.
Вы дали body
a height: 100%
. Затем дал свой ребенок (.wrapper
) a height: 100%
. Затем дал свой ребенок (.content
) a height: 100%
. Таким образом, они равны по высоте. Предоставление следующего ребенка (#half_of_content
) a height: 50%
, естественно, будет 50% высоты body
.
Однако при абсолютном позиционировании вам не нужно указывать высоты родителей.
Ответ 2
@Michael_B объяснил, почему Chrome ведет себя следующим образом:
Вы дали body
a height: 100%
. Затем дал своему ребенку (.wrapper
) a height: 100%
. Затем дал свой ребенок (.content
) a height: 100%
. Таким образом, они равны по высоте. Предоставление следующего ребенка (#half_of_content
) a height: 50%
, естественно, будет 50% высоты body
.
Однако Firefox не согласен с тем, что в действительности height: 100%
of .content
игнорируется, а его высота вычисляется в соответствии с flex: 1
.
То есть, Chrome разрешает процент по отношению к значению родительского свойства height
. Firefox делает это в отношении разрешенной гибкой высоты родителя.
Правильное поведение - это Firefox. Согласно Определенные и неопределенные размеры,
Если процент будет разрешен против flex item s основной размер, а flex item имеет definite flex основы, а flex container имеет definite main размер, flex item s основной размер следует рассматривать как definite с целью разрешения процента, а также процент должен быть разрешен против сгибаемого основного размера flex item (то есть после того, как алгоритм компоновки ниже был завершено для flex item flex container и flex элемент получил свой окончательный размер).
Ниже приведено обходное решение для Chrome:
#content {
display: flex;
flex-direction: column;
}
#content::after {
content: '';
flex: 1;
}
#half_of_content {
flex: 1;
height: auto;
}
Таким образом, доступное пространство в #content
будет равномерно распределено между #half_of_content
и псевдоэлементом ::after
.
Предполагая, что #content
не имеет другого содержимого, #half_of_content
будет 50%
. В вашем примере у вас есть 2
, поэтому он будет немного меньше 50%
.
html,
body {
height: 100%;
margin: 0;
}
#wrapper {
display: flex;
flex-flow: column;
height: 100%;
}
#menu {
height: 70px;
background-color: purple
}
#content {
flex: 1;
height: 100%;
background-color: green;
display: flex;
flex-direction: column;
}
#content::after {
content: '';
flex: 1;
}
#half_of_content {
flex: 1;
background-color: yellow;
}
#footer {
height: 100px;
background-color: cyan
}
<div id="wrapper">
<div id="menu">
1
</div>
<div id="content">2
<div id="half_of_content">2.1</div>
</div>
<div id="footer" style="">
3
</div>
</div>
Ответ 3
Вложенные flexboxes являются немного ошибками. Я немного переработал вашу разметку, добавив внутреннюю оболочку с display: flex;
, которая, похоже, выполняет эту работу. Вот fiddle (также используя имена классов вместо ids).
<div class="content">
<div class="wrapper-inner">
2
<div class="half">
2.1
</div>
</div>
</div>
.wrapper-inner {
position: absolute;
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
}
Ответ 4
Fix:
on #content
set
display: flex;
flex-flow: column nowrap;
justify-content: flex-end
on #half_of_content
set flex: 0 0 50%
;
Предостережение: вам нужно добавить div extra
как дочерний элемент #content
.
Вот полный пример:
html,body {
height: 100%;
margin: 0;
}
#wrapper {
display: flex;
flex-flow: column;
height: 100%;
}
#menu {
height: 70px;
background-color: purple
}
#content {
flex: 1;
height: 100%;
display:flex;
flex-flow: column nowrap;
justify-content: flex-end;
background-color: green;
}
#half_of_content {
flex: 0 0 50%;
background-color: yellow;
}
#footer {
height: 100px;
background-color: cyan
}
<body>
<div id="wrapper">
<div id="menu">
1
</div>
<div id="content">2
<div id="half_of_content">2.1</div>
</div>
<div id="footer" style="">
3
</div>
</div>
</body>