Flex в Firefox сжимает изображения автоматически, но не в Chrome

<h1>Window width:</h1>

<div style="display: flex">
  <img src="https://unsplash.it/400/225?image=10" alt="1">
  <img src="https://unsplash.it/400/225?image=11" alt="2">
  <img src="https://unsplash.it/400/225?image=12" alt="3">
</div>

<h1>Wrapped in 500px wide div:</h1>

<div style="width: 500px; overflow: auto">
  <div style="display: flex">
    <img src="https://unsplash.it/400/225?image=10" alt="1">
    <img src="https://unsplash.it/400/225?image=11" alt="2">
    <img src="https://unsplash.it/400/225?image=12" alt="3">
  </div>
</div>

Вот как выглядит результат в Firefox:

Скриншот страницы в Firefox 53

Вот как выглядит результат в Chrome:

Скриншот страницы в Chrome 59

Как вы можете видеть, в Firefox изображения были хорошо сжаты и изменены в размерах, так что все эти изображения помещаются в одну строку без переноса или обрезки. В Chrome изображения остаются в своем первоначальном размере, что приводит к обрезке в небольших окнах или разделениях.

Это ожидается? Я делаю что-то неправильно? Как я могу получить одинаковый результат как в Firefox, так и в Chrome?

2 ответа

Решение

Это начальные настройки в гибком контейнере:

  • flex-grow: 0
  • flex-shrink: 1
  • flex-basis: auto

Сокращение будет:

  • flex: 0 1 auto

Поэтому, даже если вы не указали эти правила в своем коде, они применяются к изображениям.

Изображения не могут расти, они могут уменьшаться (одинаково и достаточно, чтобы избежать переполнения контейнера), и они изначально имеют размер, равный их естественной ширине (400 пикселей).

Это то, что вы видите в Firefox. Изображения сжимаются, чтобы хорошо вписаться в контейнер.

В Firefox гибкие правила переопределяют естественные размеры изображения.

В Chrome, однако, верно обратное. Размеры изображений преобладают.

Простое кросс-браузерное решение заключается в том, чтобы обернуть изображения в другой элемент, поэтому эта новая оболочка становится гибким элементом и принимает значение по умолчанию flex: 0 1 auto и ничего не нужно переопределять.

img {
  width: 100%;
}
<h1>Window width:</h1>

<div style="display: flex">
  <span><img src="https://unsplash.it/400/225?image=10" alt="1"></span>
  <span><img src="https://unsplash.it/400/225?image=11" alt="2"></span>
  <span><img src="https://unsplash.it/400/225?image=12" alt="3"></span>
</div>

<h1>Wrapped in 500px wide div:</h1>

<div style="width: 500px; overflow: auto">
  <div style="display: flex">
    <span><img src="https://unsplash.it/400/225?image=10" alt="1"></span>
    <span><img src="https://unsplash.it/400/225?image=11" alt="2"></span>
    <span><img src="https://unsplash.it/400/225?image=12" alt="3"></span>
  </div>
</div>

С точки зрения того, какой браузер придерживается спецификаций, кажется, что это будет Firefox. В гибком контейнере должны преобладать гибкие правила:

7.1. flex стенография

Когда коробка представляет собой гибкий элемент, flex вместо основного размера используется свойство, чтобы определить основной размер поля.

Основное свойство размера элемента Flex - это либо width или же height имущество.

Я говорю, что Firefox "кажется" правильным, потому что в спецификации говорится, что гибкие правила должны преобладать над CSS width а также height свойства.

Конечно, размеры изображений в этом случае не определены в CSS. Это естественные размеры изображения. Таким образом, этот сценарий может быть оставлен открытым для интерпретации, и Chrome может не нарушать никаких рекомендаций.

Однако в другом сценарии, где height собственность была фактором, Firefox застрял с flex в то время как Chrome пошел с height: Почему Firefox не учитывает высоту согнутого div, а Chrome?

Я этот случай добавляю align-items: flex-start к гибкому контейнеру, а затем это правило к изображениям

img {
  min-width: 0;
  width: 100%;
}

Как align-items по умолчанию stretch так они растягиваются min-width по умолчанию auto которые снова говорят им, чтобы они были их первоначального размера, и, наконец, дают им width: 100% поэтому они подходят горизонтально и регулируют его высоту, чтобы сохранить пропорции.

Обратите внимание, что после быстрого тестирования браузера это не сработает в IE11 (но работает в Edge), поэтому ошибки существуют повсюду, в зависимости от используемого кода. Второй вариант, при котором изображение оборачивается, работает на IE11.

Фрагмент стека

img {
  min-width: 0;
  width: 100%;
}
<h1>Window width:</h1>

<div style="display: flex; align-items: flex-start;">
  <img src="https://unsplash.it/400/225?image=10" alt="1">
  <img src="https://unsplash.it/400/225?image=11" alt="2">
  <img src="https://unsplash.it/400/225?image=12" alt="3">
</div>

<h1>Wrapped in 500px wide div:</h1>

<div style="width: 500px; overflow: auto">
  <div style="display: flex; align-items: flex-start;">
    <img src="https://unsplash.it/400/225?image=10" alt="1">
    <img src="https://unsplash.it/400/225?image=11" alt="2">
    <img src="https://unsplash.it/400/225?image=12" alt="3">
  </div>
</div>


Другой вариант - обернуть изображения и установить img в width: 100%

img {
  width: 100%;
}
<div style="display: flex;">
  <div>
    <img src="https://unsplash.it/400/225?image=10" alt="1">
  </div>
  <div>
    <img src="https://unsplash.it/400/225?image=11" alt="2">
  </div>
  <div>
    <img src="https://unsplash.it/400/225?image=12" alt="3">
  </div>
</div>


Этот пост css3-flexbox-keep-image-aspect-ratio содержит ссылки вместе с хорошим объяснением того, как / почему браузеры отображают по-разному.

Другие вопросы по тегам