У меня здесь довольно сложная проблема. Я хотел бы сделать макет в CSS с несколькими слоями, что означает, что в основном наличие нескольких элементов <div>
сложены друг на друга (или, по крайней мере, делают их похожими на это), и видна только верхняя.
Во многих других GUI Environements это известно как макет карты.
Таким образом, план был следующим:
<div class='layer'>
в одном родительском элементе <div class='container'>
display: none
изначально$.show()
или $.hide()
чтобы показать или скрыть ихHTML:
<div id="containerOne">
<div class="layer a"></div>
<div class="layer b">
<div class="inner b1"></div>
</div>
<div class="layer c"></div>
</div>
CSS:
#containerOne {
width: 150px;
height: 150px;
background: red;
}
#containerOne .layer {
display : none;
width: 100%;
height: 100%
}
.a {
background: green;
}
.b {
background: orange;
}
.b1 {
width: 50%;
height: 50%;
background: yellow;
}
.c {
background: blue;
}
Это работает сначала, так как элементы не будут иметь места, зарезервированные на странице, и будут занимать место только при отображении.
Теперь, если у меня есть вложенный элемент внутри слоя, и я хочу, чтобы он имел размер 50% x 50%, это также хорошо работает: даже если для параметра div слоя установлено значение display: none
изначально.
Теперь по умолчанию мой контейнер Container установлен для display: block
и все вычисления размера, похоже, работают нормально, и здесь, где начинается моя проблема:
Мне нужен контейнер Container для display: flex
чтобы воспользоваться возможностями Flexbox современных браузеров. Вместо того, чтобы устанавливать фиксированную ширину для моих слоев, я теперь настроил их на flex: 1
чтобы они выросли до полного размера контейнера.
Это также работает так, как ожидалось. За одним исключением: вложенный элемент, размер которого должен иметь размер 50% x 50%, вообще не будет иметь размера. Отладка этого в JavaScript показывает, что это связано с тем, что на момент создания слоев они будут иметь размер 0 x 0 и сначала получат свой размер, если они показаны $.show()
.
Я бы ожидал, что когда они будут показаны, вложенный элемент будет расти до 50% х 50%, но это не так.
Я также сделал Fiddle, чтобы продемонстрировать проблему и поиграть.
Случае, которое вы ожидаете, должно произойти, но это не так (в Chrome) из-за ошибки. Он действительно работает правильно в Firefox.
Вот упрощенная версия вашего тестового теста без динамических изменений: http://jsfiddle.net/CN7e8/4/
Это поведение было недавно изменено в спецификации flexbox, на поведение, которое вы ожидаете. Проблема заключается в том, что ваша 50% -ная высота на b1
разрешается против элемента автоматической высоты (элемент гибкости, b
), и Chrome обрабатывает эту автоматическую высоту как недопустимый процентный базис, даже если автоматическая высота может быть фактически разрешена высота контейнера. (Это станет высотой контейнера из align-items: stretch
по умолчанию align-items: stretch
на контейнере flex, что делает элементы гибкости с автоматической высотой высоты).
Для справки, спецификация изменений, чтобы уточнить это, упоминается в разделе я (3) части ISSUE 3 в этом сообщении: http://lists.w3.org/Archives/Public/www-style/2014Mar/0350.html
ТАК ИЛИ ИНАЧЕ. Чтобы обойти Chrome-ошибку, вы не можете иметь автоматическую высоту на элементе flex b
, учитывая, что вы зависите от того, что он является процентным. Вы должны дать ему явную высоту, например height:100%
(что более прямое разрешение на высоту контейнера). Здесь ваша скрипка с этим изменилась: http://jsfiddle.net/CN7e8/5/