Как я могу сделать детей Flexbox на 100% ростом их родителей?

459

Я пытаюсь заполнить вертикальное пространство элемента Flex внутри Flexbox.

.container {
  height: 200px;
  width: 500px;
  display: flex;
  flex-direction: row;
}
.flex-1 {
  width: 100px;
  background-color: blue;
}
.flex-2 {
  position: relative;
  flex: 1;
  background-color: red;
}
.flex-2-child {
  height: 100%;
  width: 100%;
  background-color: green;
}
<div class="container">
  <div class="flex-1"></div>
  <div class="flex-2">
    <div class="flex-2-child"></div>
  </div>
</div>

А вот и JSFiddle

flex-2-child не заполняет необходимую высоту, за исключением двух случаев, когда:

  1. flex-2 имеет высоту 100% (что странно, потому что гибкий элемент по умолчанию имеет 100% + он глючит в Chrome)
  2. flex-2-child имеет абсолютную позицию, что также неудобно

Это не работает в Chrome или Firefox в настоящее время.

Raz
источник
в чем проблема с использованием высоты: 100%; для .flex-2?
rmagnum2002
Он не соответствует цели элемента flex, который состоит в том, чтобы заполнять контент сам по себе, и это дает мне самую странную ошибку в chrome, когда высота возвращается к нулю всякий раз, когда я изменяю размер окна
Raz
3
На самом деле, последняя версия Firefox - единственная, которая работает должным образом
Raz
1
В настоящее время между браузерами существуют значительные различия в поведении, когда речь заходит о процентном отображении высоты во flexbox: stackoverflow.com/a/35537510/3597276
Майкл Бенджамин
2
Да, у Chrome есть некоторые проблемы, особенно с вложенными флексбоксами. Например, у меня есть вложенный flex-бокс с дочерними элементами, которые height:100%вместо этого рендерится с естественным ростом. И странная вещь, если я изменю их высоту на auto, то они будут отображаться так, height:100%как я пытался это сделать. Это определенно не интуитивно понятно, если так должно работать.
trusktr

Ответы:

238

использование align-items: stretch

Как и ответ Дэвида Стори, мой обходной путь:

.flex-2 {
    display: flex;
    align-items: stretch;
}

В качестве альтернативы align-items, вы можете использовать align-selfтолько на .flex-2-childэлемент, который вы хотите растянуть.

BT
источник
7
stretchЭто должен быть выбранный ответ.
Дейв Эверитт
1
Определенно это далеко не лучший ответ на вопрос. Работает отлично.
Марсия
Да, это действительно лучший ответ на этот вопрос.
Ойвинд Братен
20
не забудьте также удалить height: 100%из дочернего компонента тот же рост, что и родительский
Ilham Wahabi GX
Пожалуйста, добавьте удаление height: 100%к ответу - я почти сдался и увидел это только в последний момент, прежде чем вернуться к absolute- что сопряжено со всеми видами проблем.
Петр
274

Я ответил на аналогичный вопрос здесь .

Я знаю, вы уже сказали, что position: absolute;это неудобно, но это работает. См. Ниже для получения дополнительной информации об устранении проблемы изменения размера.

Также ознакомьтесь с этим jsFiddle для демонстрации, хотя я добавил только префиксы webkit, которые открыты в Chrome.

У вас в основном есть 2 вопроса, с которыми я буду иметь дело отдельно.

  1. Заставить ребенка согнуть предмет на 100%
    • Установить position: relative;на родителя ребенка.
    • Установить position: absolute;на ребенка.
    • Затем вы можете установить ширину / высоту, как требуется (100% в моем образце).
  2. Исправление прокрутки изменения размера "причуды" в Chrome
    • Поставьте overflow-y: auto;прокручиваемый div.
    • У прокручиваемого элемента div должна быть указана явная высота. Мой образец уже имеет высоту 100%, но если он еще не применен, вы можете указатьheight: 0;

Посмотрите этот ответ для получения дополнительной информации о проблеме прокрутки.

Бретт Постин
источник
10
Пункт 1) отлично работает в Chrome, Firefox не нуждается в абсолютной позиции.
Юрий
224

Если я правильно понимаю, вы хотите, чтобы flex-2-child заполнил высоту и ширину своего родителя, чтобы красная область была полностью покрыта зеленым?

Если это так, вам просто нужно установить flex-2 для использования flexbox:

.flex-2 {
    display: flex;  
}

Затем скажите flex-2-child, чтобы он стал гибким:

.flex-2-child {    
    flex: 1;
}

Смотрите http://jsfiddle.net/2ZDuE/10/

Причина в том, что flex-2-child не элемент flexbox, а его родитель.

Дэвид Стори
источник
Как я могу сделать то же самое, просто с ростом 100% и каждому ребенку 50/50?
Рики Леви
7
Имейте в виду, что если вы используете «align-items: center», вы не сможете использовать это исправление, поскольку ваши предметы теперь станут равными по высоте.
Нил Монро
10
@NeilMonroe Вы все еще можете использовать, align-items: centerесли вы используете align-self: stretchтолько на одного ребенка.
BT
1
Привет @David, я попробовал ваше решение, оно отлично работает для flex-direction: макет строки, кажется, не работает с flex-direction: макет столбца, или у меня есть какие-то ошибки в коде. Не могли бы вы помочь проверить, почему в этой скрипке jsfiddle.net/78o54Lmv внутреннее поле не будет занимать всю высоту своего родителя?
Хуан Фэн
Я должен добавить min-height: 100vh;к .flex-2элементу, чтобы он работал. Спасибо за помощь!
Tenaciousd93
24

Я полагаю, что поведение Chrome более соответствует спецификации CSS (хотя и менее интуитивно понятно). В соответствии со спецификацией Flexbox stretchзначение align-selfсвойства по умолчанию изменяет только используемое значение «свойства поперечного размера» элемента ( heightв данном случае). И, как я понимаю в спецификации CSS2.1 , процентные высоты рассчитываются исходя из указанного значения родительского элемента height, а не его используемого значения. На указанное значение родительского элемента heightне влияют никакие свойства flex, и он остается неизменным auto.

Установка в явном виде height: 100%делает возможным формально вычислить процентную высоту дочернего элемента, точно так же, как установка height: 100%в htmlпозволяет вычислять процентную высоту bodyв CSS2.1.

Илья Стрельцын
источник
2
Точно! Для того, чтобы это на практике, просто добавьте height:100%к .flex-2. Вот этот jsfiddle .
CourtDemone
7
Поведение Chrome более соответствует интерпретации Chrome Team CSS-спецификации. Хотя это может быть истолковано таким образом, есть гораздо лучшие способы его интерпретации, любой из которых не привел бы нас в ловушку к этому базарному, раздражающему и утомительному поведению. Они должны были обдумать это больше.
WraithKenny
1
@RickDoesburg, это было больше года назад, но я считаю, что мне пришлось прибегнуть к элементам фиксированной высоты. Я хотел бы, чтобы эти браузеры соединились. Мне действительно начинает не нравиться мобильное пространство.
Иордания
1
Установка дочернего элемента для вертикального контейнера flexbox height: 100%дает очень странные результаты для меня в Chrome. Кажется, что это приводит к тому, что «указанная высота» устанавливается на общую высоту контейнера , а не на высоту самого элемента, поэтому вызывает нежелательную прокрутку, когда другие элементы имеют размеры, рассчитанные относительно него.
Жюль
13

Я нашел решение самостоятельно, предположим, у вас есть CSS ниже:

.parent {
  align-items: center;
  display: flex;
  justify-content: center;
}

.child {
  height: 100%; <- didn't work
}

В этом случае установка высоты 100% не будет работать, поэтому я установил margin-bottomправило auto, например:

.child {
  margin-bottom: auto;
}

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

.child {
  align-self: flex-start;
}
user3896501
источник
Хороший взлом, но проблема в том, что: если child это боковая панель и у нее есть цвет фона, пространство поля все еще белое.
Борис Бурков
Что хорошего в этом решении, так это то, что высота родительского элемента может быть динамической! Предыдущие решения требовали, чтобы у родителя была заданная высота. Спасибо за это.
Bribbons
4

Идея заключалась бы в том, чтобы display:flex;with flex-direction: row;заполнял containerdiv с помощью .flex-1and .flex-2, но это не значит, что он .flex-2имеет значение по умолчанию, height:100%;даже если оно расширено до полной высоты и имеет дочерний элемент ( .flex-2-child), с которым height:100%;вам нужно установить родительский параметр height:100%;или использовать display:flex;с flex-direction: row;на.flex-2 DIV тоже.

Из того, что я знаю display:flex, не распространятся все ваши дочерние элементы на высоту до 100%.

Небольшое демо, снято с высоты .flex-2-childи использовано display:flex;на .flex-2: http://jsfiddle.net/2ZDuE/3/

rmagnum2002
источник
3

HTML

<div class="container">
    <div class="flex-1"></div>
    <div class="flex-2">
        <div class="flex-2-child"></div>
    </div>
</div>

CSS

.container {
    height: 200px;
    width: 500px;
    display: -moz-box;
    display: -webkit-flexbox;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: -moz-flex;
    display: flex;
    -webkit-flex-direction: row;
    -moz-flex-direction: row;
    -ms-flex-direction: row;
    flex-direction: row;
}
.flex-1 {
   flex:1 0 100px;
    background-color: blue;
}
.flex-2 {
    -moz-box-flex: 1;
    -webkit-flex: 1;
    -moz-flex: 1;
    -ms-flex: 1;
    flex: 1 0 100%;
    background-color: red;
}
.flex-2-child {
    flex: 1 0 100%;
    height:100%;
    background-color: green;
}

http://jsfiddle.net/2ZDuE/750/

Кэрол Маккей
источник
0

Это также можно решить с align-self: stretch;помощью элемента, который мы хотим растянуть.

Иногда желательно растянуть только один элемент в настройке flexbox.

.container {
  height: 200px;
  width: 500px;
  display: flex;
  flex-direction: row;
}
.flex-1 {
  width: 100px;
  background-color: blue;
}
.flex-2 {
  position: relative;
  flex: 1;
  align-self: stretch;
  background-color: red;
}
.flex-2-child {
  background-color: green;
}
<div class="container">
  <div class="flex-1"></div>
  <div class="flex-2">
    <div class="flex-2-child"></div>
  </div>
</div>

GiorgosK
источник
-7

.container {. , , , align-items: stretch; , , , , }

HRK
источник
5
Добро пожаловать в stackoverflow. Вы должны полностью объяснить свой ответ и то, что он дает, который отличается от существующих ответов. См stackoverflow.com/help/how-to-answer
Simon.SA
1
Ваш ответ, похоже, такой же, как и у Б.Т. (написанный более трех лет назад), но выражен гораздо хуже.
Квентин
-12

Это мое решение с использованием CSS +

Прежде всего, если первый ребенок (flex-1) должен быть 100px, не должен быть flex. В CSS + на самом деле вы можете установить гибкие и / или статические элементы (столбцы или строки) и ваш пример становятся столь же легко , как это:

<div class="container">
  <div class="EXTENDER">
    <div class="COLS">
      <div class="CELL _100px" style="background-color:blue">100px</div>
      <div class="CELL _FLEX" style="background-color:red">flex</div>
    </div>
  </div>
</div>

контейнер css:

.container {
    height: 200px;
    width: 500px;
    position:relative;
}

и, очевидно, включают ядро CSS + 0,2

услышать скрипку

Марко Аллори
источник