Рішення
Використовуйте вкладені гнучкі контейнери.
Позбавтеся від відсоткової висоти. Позбавтеся від властивостей таблиці. Позбутися vertical-align. Уникайте абсолютного позиціонування. Просто дотримуйтесь флексбоксу весь шлях.
Нанесіть display: flexна гнучкий елемент ( .item), зробивши його гнучким контейнером. Це автоматично встановлюється align-items: stretch, що говорить дитині ( .item-inner) розширити повний зріст батьків.
Важливо: Для цього методу видаліть задані висоти з гнучких елементів. Якщо у дитини вказаний зріст (наприклад 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>
демонстрація jsFiddle
Пояснення
Моя проблема полягає в тому, що .item-inner { height: 100% }не працює у веб-програмі (Chrome).
Це не працює, оскільки ви використовуєте відсоткову висоту таким чином, що не відповідає традиційній реалізації специфікації.
10.5 Висота вмісту: heightвластивість
процент
Вказує відсоткове зростання. Відсоток обчислюється відносно висоти сформованого блоку, що містить блок. Якщо висота блоку, що містить, не вказана явно і цей елемент не розташований абсолютно, значення обчислюється до auto.
auto
Висота залежить від значень інших властивостей.
Іншими словами, для відсоткової висоти для роботи над дитиною, що надходить, батько повинен мати задану висоту.
У вашому коді контейнер верхнього рівня має певну висоту: .container { height: 20em; }
Контейнер третього рівня має визначену висоту: .item-inner { height: 100%; }
Але між ними контейнер другого рівня - .item- не має визначеної висоти. Webkit сприймає це як посилання, що відсутнє.
.item-innerговорить Chrome: дай меніheight: 100% . Chrome звертається до батьків ( .item) для довідок і відповідає: 100% чого? Я нічого не бачу (ігноруючи flex: 1правило, яке існує). Як результат, воно застосовується height: auto(висота вмісту) відповідно до специфікації.
Firefox, з іншого боку, тепер приймає батьківську висоту згинання як орієнтир для процентного зросту дитини. IE11 і Edge також приймають гнучкі висоти.
Крім того, Chrome прийме flex-growадекватну батьківську посилання, якщо він використовується разом ізflex-basis (будь-яке числове значення працює ( autoне буде), у тому числі flex-basis: 0). Однак, на момент написання цього рішення, це рішення не вдається в Safari.
#outer {
display: flex;
flex-direction: column;
height: 300px;
background-color: white;
border: 1px solid red;
}
#middle {
flex-grow: 1;
flex-basis: 1px;
background-color: yellow;
}
#inner {
height: 100%;
background-color: lightgreen;
}
<div id="outer">
<div id="middle">
<div id="inner">
INNER
</div>
</div>
</div>
Чотири рішення
1. Вкажіть висоту для всіх батьківських елементів
Надійним крос-браузерним рішенням є визначення висоти для всіх батьківських елементів. Це запобігає відсутності посилань, які браузери на основі Webkit вважають порушенням специфікації.
Зауважте, що це min-heightі max-heightне прийнятно. Це має бути heightвласність.
Детальніше тут: Робота з heightвластивістю CSS та значеннями відсотків
2. Відносне та абсолютне позиціонування CSS
Звертайтеся position: relativeдо батьків і position: absoluteдо дитини.
Розмір дитина з height: 100%і width: 100%, або використовувати офсетна властивість: top: 0, right: 0, bottom: 0, left: 0.
При абсолютному позиціонуванні відсоткова висота працює без заданої висоти на батьківській.
3. Видаліть непотрібні контейнери HTML (рекомендується)
Чи потрібні два контейнери навколо button? Чому б не видалити .itemабо .item-inner, або те і інше? Хоча buttonелементи часом не спрацьовують як гнучкі контейнери , вони можуть бути гнучкими предметами. Подумайте про те, щоб buttonстворити дитину .containerабо .itemвидалити безплатну націнку.
Ось приклад:
.container {
height: 20em;
display: flex;
flex-direction: column;
border: 5px solid black
}
a {
flex: 1;
background: orange;
border-bottom: 1px solid white;
display: flex; /* nested flex container (for aligning text) */
align-items: center; /* center text vertically */
justify-content: center; /* center text horizontally */
}
<div class="container">
<a>Button</a>
<a>Button</a>
<a>Button</a>
</div>
4. Вкладені контейнери Flex (рекомендується)
Позбавтеся від відсоткової висоти. Позбавтеся від властивостей таблиці. Позбутися vertical-align. Уникайте абсолютного позиціонування. Просто дотримуйтесь флексбоксу весь шлях.
Нанесіть display: flexна гнучкий елемент ( .item), зробивши його гнучким контейнером. Це автоматично встановлюється align-items: stretch, що говорить дитині ( .item-inner) розширити повний зріст батьків.
Важливо: Для цього методу видаліть задані висоти з гнучких елементів. Якщо у дитини вказаний зріст (наприклад 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>