How to get a div with extrinsic height and intrinsic width inside a flexbox

与世无争的帅哥 提交于 2020-07-30 05:49:26

问题


Problem

Say we have a vertical (i.e. flex-direction: column) flexbox container with a given width and height. The flexbox contains divs and each div contains an image.

  • All divs and images are supposed to shrink/grow by the same percentage to fill the height of the flexbox, which is achieved by using flex-shrink and/or flex-grow.
  • All images are supposed to keep their aspect ratio (i.e. no stretching), which is achieved by leaving their css "width" attribute unset.
  • Each div is supposed to have the same width as the image that's inside of it, which I expected to achieve with "width: min-content" or "width: max-content" or "width: fit-content", but this does not work.

How can the third point be achieved?

Note: It seems to work outside of flexbox.

Example

In the example below the div with id "imagecontainer" does not reduce its width when its height is shrunk below flex-basis, even though its content reduces in width. However, having the same div outside of a flexbox makes it reduce its width correctly when it forces its child image to become smaller through height constraints.

How do I make the "imagecontainer" div in the flexbox scale its width with the image (so that the red div in the first example has the same size as the red div in the third example)?

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>

Edit:

Based on one of the answers below, this is a version that solves the problem on Chrome but doesn't work on Firefox. The only significant change from the example above to make it work was to add "height: 100%" on the "imagecontainer" 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: 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>

Edit Solution:

Based on the accepted answer the solution for the example above is this (calculating height percentages based on the values that would otherwise be the flex-basis):

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>

Note that this doesn't require flexbox anymore.


回答1:


If you set max-height: calc(100% / (total height / own height)) and height: 100% for #imagecontainer it will work on Firefox also. Related answer

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>

If there are 3 elements in flex container:

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>



回答2:


Given the example snippet, I assume you want the red bordered container to be just as big as the inner image. The black bordered container should not change in size.

To accomplish this, it is enough to add display: flex; to #imagecontainer.

You have set some flex properties on it (flex-basis and flex-shrink) that do nothing without a flex element.

By default, the display value of a div is block.

Snippet:

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>



回答3:


Reason for extra space at right

Actually, according to me, first the img overflows out of flex container (since img loading takes time i.e. out of flow) and then height is shrunk due to covering div. The width of img adjusts as it should be but the width of covering div doesn't changes. There is no property here to do that.

You could simply do something like this...

.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>

This doesn't requires extra dimension specifications and adjusts well.

I looked at your css properties, their seemed issue with min-height as in here.

Edit: I have added min-height: 0; to .a>div just before height property. I tried a lot of solutions but maybe this order was important. I spotted the order from the solution here. Thanks to him.




回答4:


Here's the solution for your problem.

    <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>

You simply didn't need most of the flex properties on the img container and it's parent divs. I have used all the unused code from your HTML.

Crucial advice: You should never use inline styling like you did here. I repeat never.



来源:https://stackoverflow.com/questions/62862296/how-to-get-a-div-with-extrinsic-height-and-intrinsic-width-inside-a-flexbox

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!