rb612
rb612

Reputation: 5563

Why does wrapping an image with a div in a flexbox scale it correctly but img item doesn't scale?

I'm wondering why wrapping img flex items in divs will cause them to scale correctly but img items alone do not.

If you check out this JSFiddle, you'll see that wrapping an image in a div does work as suggested by other posts on StackOverflow, but it doesn't seem to work otherwise. And align-self doesn't change anything as suggested here. I tried to align-items so that it would override the default stretch but that doesn't work. I also tried clearing the min-height and min-width values since those are by default set to auto. This answer justifies using the div wrapper except it doesn't explain why it works for div flexbox items and not for img items directly.

Here's some HTML:

 .stack {
      display:flex;
      max-width:600px;
      align-items:center;  /* this does not cause image tags to resize */
    }
    .stack img {
       min-height:0;
       min-width:0;
       height:auto;
       align-self:center;
    }
    .test img {
      width:100%;
    }
<div class="stack">
  <div class="test">
    <img src="https://placehold.it/200x200/E8117F/FFFFFF"/> 
    <!--Wrapping in a div works-->
  </div>

  <img src="https://placehold.it/200x200/E8117F/FFFFFF"/>
  <img src="https://placehold.it/200x200/E8117F/FFFFFF"/>
  <img src="https://placehold.it/200x200/E8117F/FFFFFF"/>
  <img src="https://placehold.it/200x200/E8117F/FFFFFF"/>
  <img src="https://placehold.it/200x200/E8117F/FFFFFF"/>
</div>

Why is seemingly the only solution to wrap the image with a div? I don't understand why the only way to scale the image correctly is through a div wrapper.

Upvotes: 1

Views: 2630

Answers (3)

Vickel
Vickel

Reputation: 7997

with CSS flexbox, you need to address the child element directly from a wrapping parent.

In your example, in order to prevent a repeating <div><img><div> structure, you just remove <div class="test"></div>.

in case you need to apply a class (like in your example) to the image you can.

.stack {
  display: flex;
  max-width: 600px;
  align-items: center;
  border:1px solid gold;
}

.stack img {
  min-height: 0;
  min-width: 0;
  height: auto;
  width:200px;
  align-self: center;
}

.test img {
  width: 100%;
}

.test:nth-of-type(1) {
  border: 2px solid #000;
}
<body>
  <div class="stack">
    <img class="test" src="http://picsum.photos/200/200" />
    <img class="test" src="http://picsum.photos/200/200" />
    <img class="test" src="http://picsum.photos/200/200" />
    <img class="test" src="http://picsum.photos/200/200" />
    <img class="test" src="http://picsum.photos/200/200" />
    <img class="test" src="http://picsum.photos/200/200" />
  </div>
</body>

Resize your browser to see it work...

Upvotes: 2

8_bit_hacker
8_bit_hacker

Reputation: 11

The images are being stretched because the default value of align-self is 'stretch'. To maintain aspect ratio, set align-self to 'center'. I have updated your code snippet to demonstrate this.

Please keep in mind that you have 5 images at 200px width and your container width is defined as 600px, so displaying the images correctly at 200x200 causes the container to display a horizontal scrollbar.

Please see this StackOverflow question: Why does flexbox stretch my image?

 .stack {
      display:flex;
      max-width:600px;
    }
    .stack img {
        align-self: center;
    }
<div class="stack">
  <div class="test">
    <img src="https://placehold.it/200x200/E8117F/FFFFFF"/> 
    <!--Wrapping in a div works-->
  </div>

  <img src="https://placehold.it/200x200/E8117F/FFFFFF"/>
  <img src="https://placehold.it/200x200/E8117F/FFFFFF"/>
  <img src="https://placehold.it/200x200/E8117F/FFFFFF"/>
  <img src="https://placehold.it/200x200/E8117F/FFFFFF"/>
  <img src="https://placehold.it/200x200/E8117F/FFFFFF"/>
</div>

Upvotes: 1

McHat
McHat

Reputation: 860

Does this do what you need?

Markup:

<body>
  <div class="stack">
      <img src="https://placehold.it/200x200/E8117F/FFFFFF"/>
      <img src="https://placehold.it/200x200/E8117F/FFFFFF"/>
      <img src="https://placehold.it/200x200/E8117F/FFFFFF"/>
      <img src="https://placehold.it/200x200/E8117F/FFFFFF"/>
      <img src="https://placehold.it/200x200/E8117F/FFFFFF"/>
      <img src="https://placehold.it/200x200/E8117F/FFFFFF"/>
    </div>
</body>

CSS:

.stack {
  display:flex;
}
.stack img {
   align-self:center;
   width: 100px;
}

https://jsfiddle.net/zbac1dxe/6/

Upvotes: 1

Related Questions