Поведение изображения в 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>

Ответ 1

Решение

заменить:

.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 */
}

DEMO 1


Объяснение

Вы писали:

Вопрос в том, почему изображение во второй строке среднего столбец блока 2 не сжимается до высоты строки, в которой она содержится?

Похоже, что вы протестировали свой код только в Chrome, потому что предпосылка вашего вопроса неверна, когда дело доходит до Firefox и IE11.

В этих браузерах изображение собаки в блоке два содержится в элементе flex. Изображение немного растянуто в IE, но оно все же содержалось.

Ваш вопрос, похоже, зависит от Chrome. (Я не тестировал в Safari, но это браузер WebKit, например Chrome, поэтому решение может быть похоже.)

Здесь приведен пример вашего исходного кода, если вы хотите протестировать браузеры:

DEMO 2

Решение этой проблемы интересно, потому что небольшая и, казалось бы, незначительная разница в значении свойства имеет большое значение в рендерингх 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 spec Общие значения flex, и это действительно имеет значение.

Попробуйте в Chrome:

Замените flex: 1 в div.row эквивалентом flex: 1 1 0%. Вы заметите, что при рендеринге ничего не меняется.

Теперь уберите знак процента и запустите его снова. Изображение защелкнулось на месте.

Сделать это flex: 1 1 0px, как указано в CSS-Tricks, также работает.

DEMO 3

Итак, с помощью px или без устройства – а не процент. на 0 устраняет проблему в Chrome... и она ничего не сломает в Firefox.

В IE11, однако, px работает, но без единицы нет. Фактически, unlessless уничтожает компоновку.

Но IE11 - это еще одна история...

На веб-сайте поддержки поддержки браузера caniuse.com IE11 показывал полную поддержку для flexbox до недавнего времени, когда он был понижен до частичной поддержки из-за "большого количества присутствующих ошибок". При тестировании вышеприведенных демонстраций IE11 регулярно отображал один и тот же код по-разному при обновлении. Перейдите на вкладку Известные проблемы на странице caniuse.com для получения списка проблем.


Обратите внимание, что flexbox поддерживается всеми основными браузерами, за исключением IE 8 и 9. Некоторые недавние версии браузера, такие как Safari 8 и IE10, требуют префиксы поставщика. IE11, как упоминалось выше, предлагает частичную поддержку из-за нескольких известных ошибок. Для быстрого добавления всех префиксов, которые вам нужны, используйте Autoprefixer. Подробнее о совместимости браузера в этом ответе.

Ответ 2

Вот одно решение, использующее относительное/абсолютное позиционирование. Не уверен, что это "кошерный", как говорят некоторые типы 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>