Как получить div с extrinsi c height и intrinsi c width внутри flexbox - PullRequest
3 голосов
/ 12 июля 2020

Проблема

Допустим, у нас есть вертикальный (т.е. flex-direction: column) контейнер flexbox с заданной шириной и высотой. Flexbox содержит div, и каждый div содержит изображение.

  • Предполагается, что все div и изображения сжимаются / растут на один и тот же процент, чтобы заполнить высоту flexbox, что достигается с помощью flex-shrink и / или flex-grow.
  • Все изображения должны сохранять свое соотношение сторон (т. е. без растяжения), что достигается за счет того, что их атрибут css "width" не установлен.
  • Каждое div должен иметь ту же ширину, что и изображение внутри него, чего я ожидал достичь с помощью «width: min-content» или «width: max-content» или «width: fit-content», но это не работает .

Как можно достичь третьей точки?

Примечание: похоже, работает вне flexbox.

Пример

В приведенном ниже примере div с идентификатором «imagecontainer» не уменьшает свою ширину, когда его высота уменьшается ниже flex-base, даже если его содержимое уменьшается по ширине. Однако наличие того же div за пределами flexbox заставляет его правильно уменьшать его ширину, когда он заставляет его дочернее изображение уменьшаться за счет ограничений по высоте.

Как мне сделать так, чтобы div "imagecontainer" во flexbox масштабировал его ширину с изображением (чтобы красный div в первом примере имел тот же размер, что и красный div в третьем примере)?

Image in flex container with limited height
<div style="display: flex; flex-direction: column; border: 1px solid black; height: 110px; width: 200px; align-items: flex-start;">
  <div id="imagecontainer" style="position: relative; flex-shrink: 1; flex-basis: 150px; min-height: 0; box-sizing: border-box; border: 1px solid red; width: min-content;">
    <img src="https://via.placeholder.com/150.png" style="max-height: 150px; height: 100%;" />
  </div>
</div>

Original image<br />
<img src="https://via.placeholder.com/150.png" style="border: 1px solid black;" />

<br />
Image in just a simple div with limited height
<div style="position: relative; height: 110px; border: 1px solid red; width: min-content;">
  <img src="https://via.placeholder.com/150.png" style="max-height: 150px; height: 100%;" />
</div>

Изменить:

Основываясь на одном из приведенных ниже ответов, это версия, которая решает проблему на Chrome, но не работает на Firefox. Единственное существенное изменение по сравнению с приведенным выше примером, заставившее его работать, заключалось в добавлении «height: 100%» в div «imagecontainer».

Image in flex container with limited height
<div style="display: flex; flex-direction: column; border: 1px solid black; height: 110px; width: 200px; align-items: flex-start;">
  <div id="imagecontainer" style="position: relative; flex-shrink: 1; flex-basis: 120px; min-height: 0; box-sizing: border-box; border: 1px solid red; width: min-content; height: 100%;">
    <img src="https://via.placeholder.com/120.png" style="max-height: 120px; height: 100%;" />
  </div>
  <div id="imagecontainer" style="position: relative; flex-shrink: 1; flex-basis: 150px; min-height: 0; box-sizing: border-box; border: 1px solid red; width: fit-content; height: 100%;">
    <img src="https://via.placeholder.com/150.png" style="max-height: 150px; height: 100%;" />
  </div>
</div>

Original image<br />
<img src="https://via.placeholder.com/150.png" style="border: 1px solid black;" />

<br />
Image in just a simple div with limited height
<div style="position: relative; height: 110px; border: 1px solid red; width: min-content;">
  <img src="https://via.placeholder.com/150.png" style="max-height: 150px; height: 100%;" />
</div>

Изменить решение:

На основе принятого ответа решение для приведенного выше примера таково (вычисление процентов высоты на основе значений, которые в противном случае были бы флекс-основа):

Image in flex container with limited height
<div style="border: 1px solid black; height: 110px; width: 200px;">
  <div id="imagecontainer" style="box-sizing: border-box; border: 1px solid red;height: calc(100% / (270 / 120)); width: max-content;">
    <img src="https://via.placeholder.com/120.png" style="height: 100%;" />
  </div>
  <div id="imagecontainer" style="box-sizing: border-box; border: 1px solid red;height: calc(100% / (270 / 150)); width: max-content;">
    <img src="https://via.placeholder.com/150.png" style="height: 100%;" />
  </div>
</div>

Обратите внимание, что для этого больше не требуется flexbox.

Ответы [ 4 ]

1 голос
/ 15 июля 2020

Если вы установите max-height: calc(100% / (total height / own height)) и height: 100% для #imagecontainer, он также будет работать с Firefox. Соответствующий ответ

Image in flex container with limited height
<div style="display: flex; flex-direction: column; border: 1px solid black; height: 110px; width: 200px; align-items: flex-start; ">
  <div id="imagecontainer" style="position: relative; flex-shrink: 1; flex-basis: 120px; min-height: 0; box-sizing: border-box; border: 1px solid red; width: min-content; max-height: calc(100% / (270 / 120));height: 100%;">
    <img src="https://via.placeholder.com/120.png" style=" height: 100%;" />
  </div>
  <div id="imagecontainer" style="position: relative; flex-shrink: 1; flex-basis: 150px; min-height: 0; box-sizing: border-box; border: 1px solid red; width: fit-content; max-height: calc(100% / (270 / 150));height: 100%;">
    <img src="https://via.placeholder.com/150.png" style=" height: 100%;" />
  </div>
</div>

Original image<br />
<img src="https://via.placeholder.com/150.png" style="border: 1px solid black;" />

<br />
Image in just a simple div with limited height
<div style="position: relative; height: 110px; border: 1px solid red; width: min-content;">
  <img src="https://via.placeholder.com/150.png" style="max-height: 150px; height: 100%;" />
</div>

Если в гибком контейнере 3 элемента:

Image in flex container with limited height
<div style="display: flex; flex-direction: column; border: 1px solid black; height: 110px; width: 200px; align-items: flex-start;">
  <div id="imagecontainer" style="position: relative; flex-shrink: 1; flex-basis: 120px; min-height: 0; box-sizing: border-box; border: 1px solid red; width: min-content; max-height: calc(100% / (420 / 120)); height: 100%;">
    <img src="https://via.placeholder.com/120.png" style=" height: 100%;" />
  </div>
  <div id="imagecontainer" style="position: relative; flex-shrink: 1; flex-basis: 150px; min-height: 0; box-sizing: border-box; border: 1px solid red; width: min-content; max-height: calc(100% / (420 / 150));height: 100%;">
    <img src="https://via.placeholder.com/150.png" style=" height: 100%;" />
  </div>
   <div id="imagecontainer" style="position: relative; flex-shrink: 1; flex-basis: 150px; min-height: 0; box-sizing: border-box; border: 1px solid red; width: min-content; max-height: calc(100% / (420 / 150));height: 100%;">
    <img src="https://via.placeholder.com/150.png" style=" height: 100%;" />
  </div>
</div>

Original image<br />
<img src="https://via.placeholder.com/150.png" style="border: 1px solid black;" />

<br />
Image in just a simple div with limited height
<div style="position: relative; height: 110px; border: 1px solid red; width: min-content;">
  <img src="https://via.placeholder.com/150.png" style="max-height: 150px; height: 100%;" />
</div>
0 голосов
/ 14 июля 2020

Причина дополнительного места справа

На самом деле, по моему мнению, сначала img переполняется из контейнера flex (поскольку img загрузка занимает время, т.е. расход), а затем height сжимается из-за покрытия div. width из img настраивается так, как должно быть, но width покрытия div не меняется. Здесь нет возможности сделать это.

Вы можете просто сделать что-то вроде этого ...

.a {
  border: 1px red solid;
  width: 200px;
  height: 110px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.a>div {
  border: 1px blue solid;
  min-height: 0;
  height: 100%;
}

.a>div>img {
  height: 100%;
}
<div class="a">
  <div>
    <img src="https://via.placeholder.com/150.png" />
  </div>
  <div>
    <img src="https://via.placeholder.com/150.png" />
  </div>
  <div>
    <img src="https://via.placeholder.com/150.png" />
  </div>
</div>

Это не требует дополнительных спецификаций размеров и хорошо настраивается.

Я посмотрел на ваши свойства css, кажется, у них проблема с min-height как в здесь .

Изменить: я добавил min-height: 0; к .a>div непосредственно перед свойством height. Я пробовал много решений, но, возможно, этот порядок был важен. Заметил заказ из решения здесь . Спасибо ему.

0 голосов
/ 15 июля 2020

Вот решение вашей проблемы.

    <div
      style="display: flex; border: 1px solid black; width: 200px;"
    >
      <div
        id="imagecontainer"
        style="
          display: flex;
          height: auto;
          box-sizing: border-box;
          border: 1px solid red;
        "
      >
        <img src="https://via.placeholder.com/150.png" style="" />
      </div>
    </div>
    
    Original image<br />
    <img
      src="https://via.placeholder.com/150.png"
      style="border: 1px solid black;"
    />
    
    <br />
    Image in just a simple div with limited height
    <div
      style="
        position: relative;
        height: 110px;
        border: 1px solid red;
        width: min-content;
      "
    >
      <img
        src="https://via.placeholder.com/150.png"
        style="max-height: 150px; height: 100%;"
      />
    </div>

Вам просто не понадобилось большинство свойств flex в контейнере img и его родительских div. Я использовал весь неиспользуемый код из вашего HTML.

Важный совет: никогда не используйте встроенные стили, как здесь. Я никогда не повторяю.

0 голосов
/ 14 июля 2020

Учитывая фрагмент примера, я предполагаю, что вы хотите, чтобы контейнер с красной рамкой был такого же размера, как и внутреннее изображение. Контейнер с черной рамкой не должен меняться в размере.

Чтобы выполнить sh это, достаточно добавить display: flex; к #imagecontainer.

Вы установили для него некоторые свойства гибкости (flex-basis и flex-shrink), которые ничего не делают без гибкого элемента.

По умолчанию отображаемое значение div равно block.

Фрагмент:

Image in flex container with limited height
<div style="display: flex; flex-direction: column; border: 1px solid black; height: 110px; width: 200px; align-items: flex-start;">
  <div id="imagecontainer" style="position: relative; display: flex; flex-shrink: 1; flex-basis: 150px; min-height: 0; box-sizing: border-box; border: 1px solid red; width: min-content;">
    <img src="https://via.placeholder.com/150.png" style="max-height: 150px; height: 100%;" />
  </div>
</div>

Original image<br />
<img src="https://via.placeholder.com/150.png" style="border: 1px solid black;" />

<br />
Image in just a simple div with limited height
<div style="position: relative; height: 110px; border: 1px solid red; width: min-content;">
  <img src="https://via.placeholder.com/150.png" style="max-height: 150px; height: 100%;" />
</div>
...