Я хочу иметь вертикальное меню с определенной высотой.
Каждый ребенок должен заполнить рост родителя и выровнять текст по центру.
Число детей случайное, поэтому мне приходится работать с динамическими значениями.
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>
css
google-chrome
webkit
flexbox
Рикардо Кастаньеда
источник
источник
top:0
иleft:0
иметь вид , как и следовало ожидать.Ответы:
Решение
Используйте вложенные гибкие контейнеры.
Избавьтесь от высоты в процентах. Избавьтесь от свойств таблицы. Избавиться от
vertical-align
. Избегайте абсолютного позиционирования. Просто придерживайтесь flexbox до конца.Примените
display: flex
к элементу flex (.item
), превратив его в контейнер flex. Это автоматически устанавливаетalign-items: stretch
, что говорит child (.item-inner
) увеличить полную высоту родителя.Важное замечание: Удалите указанные высоты из гибких элементов, чтобы этот метод работал. Если у ребенка указана высота (например
height: 100%
), он будет игнорироватьalign-items: stretch
поступление от родителя. Для работы поstretch
умолчанию рост ребенка должен быть вычислен доauto
(полное объяснение ).Попробуйте это (без изменений в HTML):
Показать фрагмент кода
демоверсия jsFiddle
объяснение
Это не работает, потому что вы используете процентную высоту таким образом, который не соответствует традиционной реализации спецификации.
Другими словами, чтобы высота в процентах работала с дочерним объектом в потоке, родитель должен иметь заданную высоту.
В вашем коде контейнер верхнего уровня имеет определенную высоту:
.container { height: 20em; }
Контейнер третьего уровня имеет определенную высоту:
.item-inner { height: 100%; }
Но между ними контейнер второго уровня
.item
- не имеет определенной высоты. Webkit видит это как недостающую ссылку..item-inner
говорит Chrome: дай мнеheight: 100%
. Chrome смотрит на parent (.item
) для справки и отвечает: 100% чего? Я ничего не вижу (игнорируя существующее тамflex: 1
правило). В результате применяетсяheight: auto
(высота содержимого), в соответствии со спецификацией.Firefox, с другой стороны, теперь принимает высоту изгиба родителя как ссылку на процентную высоту ребенка. IE11 и Edge также допускают гибкие высоты.
Кроме того, Chrome примет
flex-grow
как адекватную родительскую ссылку, если используется вместе сflex-basis
(любое числовое значение работает (auto
не будет), в том числеflex-basis: 0
). Однако на момент написания этой статьи это решение не работает в Safari.Показать фрагмент кода
Четыре решения
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
удалить ненужную наценку.Вот пример:
Показать фрагмент кода
4. Вложенные гибкие контейнеры (рекомендуется)
Избавьтесь от высоты в процентах. Избавьтесь от свойств таблицы. Избавиться от
vertical-align
. Избегайте абсолютного позиционирования. Просто придерживайтесь flexbox до конца.Примените
display: flex
к элементу flex (.item
), превратив его в контейнер flex. Это автоматически устанавливаетalign-items: stretch
, что говорит child (.item-inner
) увеличить полную высоту родителя.Важное замечание: Удалите указанные высоты из гибких элементов, чтобы этот метод работал. Если у ребенка указана высота (например
height: 100%
), он будет игнорироватьalign-items: stretch
поступление от родителя. Для работы поstretch
умолчанию рост ребенка должен быть вычислен доauto
(полное объяснение ).Попробуйте это (без изменений в HTML):
Показать фрагмент кода
jsFiddle
источник
Решение: Удалить
height: 100%
в .item-inner и добавитьdisplay: flex
в .itemДемо: https://codepen.io/tronghiep92/pen/NvzVoo
источник
Определение атрибута flex для контейнера сработало для меня:
Это гарантирует, что высота установлена и не увеличивается.
источник
Для мобильного Safari Есть исправление браузера. вам нужно добавить -webkit-box для устройств iOS.
Ex.
если вы используете
align-items: stretch;
свойство для родительского элемента, удалите егоheight : 100%
из дочернего элемента.источник
У меня была похожая проблема в iOS 8, 9 и 10, и приведенная выше информация не могла ее исправить, однако я нашел решение после дня работы над этим. Конечно, это не будет работать для всех, но в моем случае мои элементы были сложены в столбец и имели нулевую высоту, когда это должна была быть высота содержимого. Переключение css на row и wrap устранило проблему. Это работает, только если у вас есть один предмет, и они сложены, но, так как мне потребовался день, чтобы выяснить это, я решил поделиться своим исправлением!
источник
У меня была похожая ошибка, но при использовании фиксированного числа для роста, а не в процентах. Это был также гибкий контейнер внутри тела (который не имеет указанной высоты). Оказалось, что в Safari мой flex-контейнер по какой-то причине имел высоту 9px, но во всех других браузерах он отображал правильную высоту 100px, указанную в таблице стилей.
Мне удалось получить его на работу, добавляя как
height
иmin-height
свойства класса CSS.У меня на Safari 13.0.4 и Chrome 79.0.3945.130 сработало следующее:
Надеюсь это поможет!
источник