Flex basis 100% в столбце flexbox: полная высота в Firefox, а не в Chrome

Я хотел бы столбец divs любого числа, каждый с шириной 100% и высотой 100% их родительского div, поэтому один виден изначально, а другие переполняют Родительский вниз. Я установил divs иметь flex: 0 0 100%;, внутри родительского div с display: flex и flex-direction: column для достижения этой цели.

Родительский div сам неизвестной высоты, так что это также ребенок display: flex и flex-direction: column, установлено flex: 1 0 0, чтобы занять оставшееся место в контейнере.

в Firefox вывод такой, как мне бы хотелось:

Firefox nested flex boxes

однако, не в Chrome:

Chrome nested flex boxes

как я могу достичь стиля Firefox в Chrome без Javascript?

вы можете увидеть это в действии на http://plnkr.co/edit/WnAcmwAPnFaAhqqtwhLL?p=preview, а также соответствующая версия с flex-direction: row, которая стабильно работает в Firefox и Chrome.

для ссылка, полный CSS

.wrapper {
  display: flex;
  flex-direction: column;
  height: 150px;
  width: 200px;
  border: 4px solid green;
  margin-bottom: 20px;
}

.column-parent {
  flex: 1 0 0;
  display: flex;
  flex-direction: column;
  border: 2px solid blue;
}

.column-child {
  flex: 0 0 100%;
  border: 2px solid red;
}

и HTML

<div class="wrapper">
  <p>Some content of unknown size</p>
  <div class="column-parent">
    <div class="column-child">
      Should be inside green
    </div>
    <div class="column-child">
      Should be outside green
    </div>
  </div>
</div>

4 ответов


Как указано в ответе Abhitalks, существует ошибка (или другая интерпретация стандарта) в том, как Chrome обрабатывает высота здесь.

Я нашел хак, который работает как в Chrome FF, так и в IE

единственная проблема заключается в том, что у вас должно быть столько правил, сколько возможно детей.

трюк состоит в том, чтобы установить flex-направление в строку, установить flex-basis (то есть теперь ширину) на 100%, а затем перевести элементы

.container {
    border: solid 2px blue;
    height: 200px;
    width: 200px;
    display: flex;
    flex-direction: column;
    position: relative;
}

.filler {
    border: solid 1px black;
    flex: 0 0 80px;
    background-color: lightgreen;
    transition: flex 1s;
}

.container:hover .filler {
    flex: 0 0 40px;
}

.test {
    border: solid 1px red;
    flex: 1 0 25px;
    display: flex;
    flex-direction: row;
    position: relative;
}

.child {
    background-color: rgba(200, 0, 0, 0.26);
    flex: 0 0 100%; 
}

.child:nth-child(2) {
    background-color: rgba(255, 255, 0, 0.48);
    transform: translateX(-100%) translateY(100%);
}

.child:nth-child(3) {
    background-color: rgba(173, 216, 230, 0.28);
    transform: translateX(-200%) translateY(200%);
}
<div class="container">
    <div class="filler"></div>
    <div class="filler"></div>
    <div class="test">
    	   <div class="child">1</div>
    	   <div class="child">2</div>
    	   <div class="child">3</div>
    </div>
</div>

Если бы мог быть другой ребенок, вам понадобилось бы правило nth-child (4), и так далее

я добавил эффект наведения, чтобы проверить, как адаптируется размер


это, кажется, ошибка с Chrome. Похожие на те, о которых сообщалось здесь (вопрос 428049) и, возможно, связанные с (вопрос 346275).

об этом говорит:

- Browsers are supposed to resolve percentages on the flex item's child, *if* its flex-basis is definite.
- Gecko is *always* resolving percentages regardless of the flex-basis.
- Chrome is *never* resolving percentages, regardless of the flex-basis. 

в целом, Chrome не разрешает процентные высоты на дочернем элементе flex-item (даже если сам ребенок является flex-item), в то время как все остальные браузеры.

это можно продемонстрировать в ниже фрагмент: (скрипку здесь)

* { box-sizing: border-box; margin: 0; padding: 0; }
div.wrap {
    height: 120px; width: 240px; margin: 0px 12px;
    border: 1px solid blue; float: left;
    display: flex; flex-direction: column;    
}
div.parent {
    flex: 0 0 100%;
    border: 1px solid green; 
    display: flex; flex-direction: column;    
}
div.item {
    flex: 0 0 100%;
    border: 1px solid red;
}
<div class="wrap">
    <div class="item">a</div>
    <div class="item">b</div>
    <div class="item">c</div>
</div>
<div class="wrap">
    <div class="parent">
        <div class="item">a</div>
        <div class="item">b</div>
        <div class="item">c</div>
    </div>
</div>

второй div должен показывать то же поведение, что и первый. Другие браузеры (IE11, Edge, FF39) показывают это правильно. Chrome не работает здесь и не разрешает div.item правильно. Ему нужна фиксированная высота на его родителе, без которой он использует min-content как своя высота и таким образом не переполняет.

тогда как, в первом div, the div.itemС правильно разрешены и переполнение соответственно. Это потому, что есть фиксированная высота на родителе (т. е. div.wrap)


Возможное Решение:

в качестве обходного пути, если вы уверены, что только два элемента (p и div) внутри вашей обертки, то вы могли бы дать им 50% высота. Вы должны предоставить height:50% на .column-parent. Chrome нуждается в фиксированной высоте на родителе, как показано выше.

тогда все будет работать как нужно.

Демо Скрипка:http://jsfiddle.net/abhitalks/kqncm65n/

соответствующий CSS:

.wrapper > p { flex: 0 0 50%; }  /* this can be on flex-basis */
.column-parent {
    flex: 1 0 auto; height: 50%; /* but, this needs to be fixed height */
    display: flex; flex-direction: column;
    border: 2px solid blue;
}
.column-child {
    flex: 0 0 100%;              /* this flex-basis is then enough */
    border: 2px solid red;
}

PS: также, похоже, существуют различия в способе визуализации jsfiddle и plnkr. Я не знаю почему, но иногда я получаю разные результаты!


мой предыдущий ответ-это хак,который использует определенную настройку макета.

альтернативный способ, более общий, обойти эту ошибку Chrome-использовать промежуточный элемент в макете и установить размер этого элемента с помощью top: 0px и bottom: 0px. (вместо высоты: 100%) есть еще ошибка в том, как Chrome обрабатывает исчисление, которое нуждается в поддельной анимации, чтобы заставить его правильно настроить

.container {
    border: solid 2px blue;
    height: 200px;
    width: 200px;
    display: flex;
    flex-direction: column;
    position: relative;
}

.filler {
    border: solid 1px black;
    flex: 0 0 94px;
    background-color: lightgreen;
    transition: 1s;
}

.container:hover .filler {
    flex: 0 0 50px;
}

.test {
    border: solid 1px red;
    flex: 1 0 25px;
    display: flex;
    flex-direction: row;
    position: relative;
}

@-webkit-keyframes adjust2 {
    0% {flex-basis: 100%;}
  100% {flex-basis: 100.1%;}
}
.child {
    background-color: rgba(200, 0, 0, 0.26);
    width:  100%;
    height: 100%;
    flex: 1 0 100%;
    -webkit-animation: adjust2 1s infinite; /* only needed for webkit bug */
}

.intermediate {
    width:  100%;
    position: absolute;
    top: 0px;
    bottom: 0px;
    display: flex; 
    flex-direction: column; 
}

.child:nth-child(n+2) {
    background-color: rgba(255, 255, 0, 0.48);
}

.child:nth-child(n+3) {
    background-color: rgba(173, 216, 230, 0.28);
}
<div class="container">
    <div class="filler"></div>
    <div class="test">
        <div class="intermediate">
    	       <div class="child"></div>
    	       <div class="child"></div>
    	       <div class="child"></div>
        </div>
    </div>
</div>

Как насчет добавления 100% в контейнер:

.column-parent {
  flex: 1 0 100%;
}

и flex-растут до 1 в содержащемся элементе без регулировки основы flex:

.column-child {
  flex: 1 0 0;
}

вот как это будет выглядеть:http://plnkr.co/edit/H25NQxLtbi65oaltNVax?p=preview