Can flexbox view lenses horizontally and vertically without stretching them?

I want to make images centered horizontally and vertically inside my containers. And if their width or height is greater than the width or height of their containers, make them automatically shrink while maintaining their proportions.

The following CSS code is what I am using in the container to try and achieve the goal:

display: -ms-flexbox;
display: -webkit-flex;
display:         flex;
    -ms-flex-direction: column;
-webkit-flex-direction: column;
        flex-direction: column;
          -ms-flex-pack: center;
-webkit-justify-content: center;
        justify-content: center;

      

And here are three examples on jsFiddle :

  • The first example is an image that is wider than its height. It works great.
  • The second example is an image whose height is greater than its width. But in this example, its width extends to the width of the container, which is not what I want.
  • The third example has the same problem as the second example.

Also, I know that the goal can also be achieved by using CSS position and transform. But this method often creates a 1 pixel gap between the modified image and the border of the container. That is, the modified image cannot touch the border of the container where it should do. So I have to resort to CSS flexbox.

+3


source to share


1 answer


The problem is that the start value align-items

is stretch

and the start value align-self

is auto

, so the images are stretched.

So, you need one of the following:

.flex-container {
    align-items: center;
}

      

.flex-item {
    align-self: center;
}

      

* {
  margin: 0;
  padding: 0;
}
div {
  display: flex; /* Magic begins */
  flex-direction: column;
  justify-content: center; /* Center in main axis */
  align-items: center; /* Center in cross axis */
  margin: 20px auto;
  width: 300px;
  height: 300px;
  border: 2px solid #000;
}
img {
  max-width: 100%;
  max-height: 100%;
}
      

<div>
  <img src="http://lorempixel.com/400/200/" alt="" />
</div>
<div>
  <img src="http://lorempixel.com/200/400/" alt="" />
</div>
<div>
  <img src="http://lorempixel.com/50/50/" alt="" />
</div>
      

Run codeHide result




But notice that the middle image is still stretched a little. This is because if the images are taller than the container, they will shrink vertically, but not horizontally (this will be the opposite of the line layout).

To prevent this use object-fit

(IE and Edge not supported):

img {
  object-fit: contain;
}

      

* {
  margin: 0;
  padding: 0;
}
div {
  display: flex; /* Magic begins */
  flex-direction: column;
  justify-content: center; /* Center in main axis */
  align-items: center; /* Center in cross axis */
  margin: 20px auto;
  width: 300px;
  height: 300px;
  border: 2px solid #000;
}
img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
      

<div>
  <img src="http://lorempixel.com/400/200/" alt="" />
</div>
<div>
  <img src="http://lorempixel.com/200/400/" alt="" />
</div>
<div>
  <img src="http://lorempixel.com/50/50/" alt="" />
</div>
      

Run codeHide result


+5


source







All Articles