Chrome/Safari не заполняет 100% высоту гибкого родителя

Я хочу иметь вертикальное меню с определенной высотой.

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

Число детей случайное, поэтому мне приходится работать с динамическими значениями.

Div .container содержит случайное число детей (.item), которые всегда должны заполнять высоту родителя. Для этого я использовал flexbox.

Для создания ссылок с текстом, выровненным по середине, я использую метод display: table-cell. Но использование табличных дисплеев требует использования высоты 100%.

Моя проблема в том, что .item-inner { height: 100% } не работает в webkit (Chrome).

  • Есть ли исправление для этой проблемы?
  • Или существует другой способ сделать все .item заполнять высоту родителя текстом по вертикали, выровненным до середины?

Пример здесь jsFiddle, должен быть просмотрен в Firefox и Chrome

.container {
  height: 20em;
  display: flex;
  flex-direction: column;
  border: 5px solid black
}
.item {
  flex: 1;
  border-bottom: 1px solid white;
}
.item-inner {
  height: 100%;
  width: 100%;
  display: table;
}
a {
  background: orange;
  display: table-cell;
  vertical-align: middle;
}
<div class="container">
  <div class="item">
    <div class="item-inner">
      <a>Button</a>
    </div>
  </div>

  <div class="item">
    <div class="item-inner">
      <a>Button</a>
    </div>
  </div>

  <div class="item">
    <div class="item-inner">
      <a>Button</a>
    </div>
  </div>
</div>

Ответ 1

Решение

Используйте вложенные гибкие контейнеры.

Избавьтесь от высоты в процентах. Избавьтесь от свойств таблицы. Избавиться от vertical-align. Избегайте абсолютного позиционирования. Просто придерживайтесь flexbox до конца.

Примените display: flex к элементу flex (.item), превратив его в контейнер flex. Это автоматически устанавливает align-items: stretch, который говорит дочернему .item-inner (.item-inner) увеличить полную высоту родительского элемента.

Важное замечание: Удалите указанные высоты из гибких элементов, чтобы этот метод работал. Если у дочернего align-items: stretch указана высота (например, height: 100%), он будет игнорировать align-items: stretch исходящий от родителя. Для того, чтобы stretch умолчанию работал, дочерний рост должен вычисляться в auto (полное объяснение).

Попробуйте это (без изменений в HTML):

.container {
    display: flex;
    flex-direction: column;
    height: 20em;
    border: 5px solid black
}

.item {
    display: flex;                      /* new; nested flex container */
    flex: 1;
    border-bottom: 1px solid white;
}

.item-inner {
    display: flex;                      /* new; nested flex container */
    flex: 1;                            /* new */

    /* height: 100%;                    <-- remove; unnecessary */
    /* width: 100%;                     <-- remove; unnecessary */
    /* display: table;                  <-- remove; unnecessary */  
}

a {
    display: flex;                      /* new; nested flex container */
    flex: 1;                            /* new */
    align-items: center;                /* new; vertically center text */
    background: orange;

    /* display: table-cell;             <-- remove; unnecessary */
    /* vertical-align: middle;          <-- remove; unnecessary */
}
<div class="container">
  <div class="item">
    <div class="item-inner">
      <a>Button</a>
    </div>
  </div>

  <div class="item">
    <div class="item-inner">
      <a>Button</a>
    </div>
  </div>

  <div class="item">
    <div class="item-inner">
      <a>Button</a>
    </div>
  </div>
</div>

Ответ 3

Для мобильного Safari Есть исправление браузера. вам нужно добавить -webkit-box для устройств iOS.

Ex.

display: flex;
display: -webkit-box;
flex-direction: column;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
align-items: stretch;

если вы используете align-items: stretch; свойство для родительского элемента, удалить height: 100% от дочернего элемента.

Ответ 4

У меня была похожая проблема в iOS 8, 9 и 10, и информация, приведенная выше, не могла ее исправить, однако я нашел решение после дня работы над этим. Конечно, это не будет работать для всех, но в моем случае мои элементы были сложены в столбец и имели нулевую высоту, когда это должна была быть высота содержимого. Переключение css на row и wrap устранило проблему. Это работает, только если у вас есть один предмет, и они сложены, но, так как мне потребовался день, чтобы выяснить это, я решил поделиться своим исправлением!

.wrapper {
    flex-direction: column; // <-- Remove this line
    flex-direction: row; // <-- replace it with
    flex-wrap: wrap; // <-- Add wrapping
}

.item {
    width: 100%;
}