Поведение изображения в flexbox (строки в столбцах)
У ниже скрипки есть три блока.
Блок 1 содержит три столбца. В среднем столбце есть две строки, каждая из которых настроена на изгиб:1.
Блок 2 содержит три столбца. В среднем столбце есть две строки, каждая из которых настроена на изгиб:1. Второй ряд содержит изображение собаки. Изображение не будет уменьшаться до высоты строки, в которой оно содержится.
блок 3 содержит только средний столбец, в котором есть две строки, каждая из которых настроена на сгибание:1. Второй ряд содержит изображение собаки. Изображение сжимается до высоты строки, в которой оно содержится.
Вопрос в том, почему изображение во втором ряду среднего столбца блока 2 не уменьшается до высоты строки, в которой оно содержится? Какие правила CSS я могу добавить, чтобы это произошло?
.block{
height:100px;
}
.wrapper{
border:5px solid purple;
display:flex;
flex-direction:row;
}
.column{
flex:1;
border:3px solid yellow;
}
.middle{
display:flex;
flex-direction:column;
}
.first{
background:red;
}
.second{
background:orange;
}
.third{
background:purple;
}
.row{
flex:1;
border:1px solid black;
display:flex;
align-items:stretch;
}
img{
flex:1;
}
<div class="wrapper block">
<div class="left column"></div>
<div class="middle column">
<div class="row first"></div>
<div class="row second"></div>
</div>
<div class="right column"></div>
</div>
<div class="wrapper block">
<div class="left column"></div>
<div class="middle column">
<div class="row first"></div>
<div class="row second">
<img src="https://upload.wikimedia.org/wikipedia/commons/8/89/Dog.svg" />
</div>
</div>
<div class="right column"></div>
</div>
<div class="middle block">
<div class="row first"></div>
<div class="row second">
<img src="https://upload.wikimedia.org/wikipedia/commons/8/89/Dog.svg" />
</div>
</div>
2 ответа
Решение
заменить:
.row {
flex: 1;
border: 1px solid black;
display: flex;
align-items: stretch;
}
с:
.row {
flex: 1 1 0px; /* adjustment on this line */
border: 1px solid black; /* no change */
display: flex; /* no change */
align-items: stretch; /* no change */
}
объяснение
Вы написали:
Вопрос в том, почему изображение во втором ряду среднего столбца блока 2 не уменьшается до высоты строки, в которой оно содержится?
Похоже, что вы тестировали свой код только в Chrome, потому что предпосылка вашего вопроса ложна, когда речь идет о Firefox и IE11.
В этих браузерах изображение собаки во втором блоке содержится в гибком элементе. В IE изображение немного растянуто, но, тем не менее, оно содержится.
Похоже, ваш вопрос относится к Chrome. (Я не тестировал в Safari, но это браузер WebKit, такой как Chrome, поэтому решение может быть похожим.)
Вот демонстрация вашего исходного кода на тот случай, если вы хотите протестировать браузеры:
Решение этой проблемы интересно, потому что небольшая и, казалось бы, незначительная разница в значении свойства сильно влияет на рендеринг Chrome.
Ваше изображение является дочерним элементом (точнее, гибким элементом) div.row
, гибкий контейнер с направлением строки.
div.row
также является гибким элементом большого контейнера (в направлении столбца) и имеет flex: 1
применяется. Проблема в Chrome кроется в том, что flex: 1
декларация.
Что значит flex: 1
имею в виду?
flex
свойство является сокращением для flex-grow
, flex-shrink
а также flex-basis
,
flex: 1
является эквивалентом flex-grow: 1
, flex-shrink: 1
а также flex-basis: 0%
,
Обратите внимание, что знак процента (%) после 0
, Это определено в общих значениях спецификации flexbox: flex
и это на самом деле имеет значение.
Попробуйте это в Chrome:
замещать flex: 1
в div.row
с его эквивалентом flex: 1 1 0%
, Вы заметите, что ничего не меняется при визуализации.
Теперь удалите знак процента и запустите его снова. Изображение встанет на место.
Делая это flex: 1 1 0px
, как указано в CSS-хитрости, также работает.
Итак, используя px
или нет единицы - и не в процентах - на 0
исправляет проблему в Chrome... и ничего не ломает в Firefox.
В IE11, однако, px
работает, но без единиц не работает. На самом деле, без единого целого стирает макет.
Но IE11 это другая история...
На веб-сайте данных поддержки браузера caniuse.com IE11 до недавнего времени демонстрировал полную поддержку flexbox, когда он был понижен до частичной поддержки из-за "большого количества ошибок". При тестировании приведенных выше демонстраций IE11 регулярно обновлял один и тот же код по-разному. См. Вкладку Известные проблемы на caniuse.com для получения списка проблем.
Обратите внимание, что flexbox поддерживается всеми основными браузерами, кроме IE 8 и 9. Для некоторых последних версий браузеров, таких как Safari 8 и IE10, требуются префиксы поставщиков. IE11, как упоминалось выше, предлагает частичную поддержку из-за нескольких известных ошибок. Для быстрого добавления всех необходимых префиксов используйте Autoprefixer. Подробнее о совместимости браузера в этом ответе.
Вот одно решение, использующее относительное / абсолютное позиционирование. Не уверен, что он "кошерный", как сказали бы некоторые типы MXMJ, но он работает. Смотрите добавленный код в нижней части CSS.
.block{
height:100px;
}
.wrapper{
border:5px solid purple;
display:flex;
flex-direction:row;
}
.column{
flex:1;
border:3px solid yellow;
}
.middle{
display:flex;
flex-direction:column;
}
.first{
background:red;
}
.second{
background:orange;
}
.third{
background:purple;
}
.row{
flex:1;
border:1px solid black;
display:flex;
align-items:stretch;
}
img{
flex:1;
}
/* Added Code */
.middle .row {
position: relative;
}
.middle .row img {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
max-width: 95%;
max-height: 95%;
}
<div class="wrapper block">
<div class="left column"></div>
<div class="middle column">
<div class="row first"></div>
<div class="row second"></div>
</div>
<div class="right column"></div>
</div>
<div class="wrapper block">
<div class="left column"></div>
<div class="middle column">
<div class="row first"></div>
<div class="row second">
<img src="https://upload.wikimedia.org/wikipedia/commons/8/89/Dog.svg" />
</div>
</div>
<div class="right column"></div>
</div>
<div class="wrapper block">
<div class="row first"></div>
<div class="row second">
<img src="https://upload.wikimedia.org/wikipedia/commons/8/89/Dog.svg" />
</div>
</div>