I want to make images centered horizontally and vertically inside their containers. And if their width or height is greater than their containers' width or height, then make them automatically shrink while keeping their proportions.
The following CSS code is what I use on the container to try to 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:
Besides, I know the goal can also be achieved by using CSS position and transform. But such a method often creates 1 pixel gap between the resized image and the container's border. That is, the resized image fails to touch the container's border, at where it should do. Therefore I have to resort to CSS flexbox.
Fortunately, the solution is simple. You just need to replace your image/flex item's align-self property's default stretch value with another value. Instead of stretch you can use center , which will remove the image stretching, and vertically align your image in the middle of its parent container.
To center a div vertically and horizontally using flexbox, you need to wrap the div or div's inside a container with properties ' display: flex; flex-direction: column; justify-content: center;align-items: center; ', then just make the div ' text-align: center; ' if it has text.
We use justify-content to align the item on the main axis, which in this case is the inline axis running horizontally. You can take a look at the code of this example below. Change the size of the container or nested element and the nested element always remains centered.
To center both vertically and horizontally, use padding and text-align: center : I am vertically and horizontally centered.
The problem is that the initial value of align-items
is stretch
and the initial value of 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>
But note that the middle image is still a bit stretched. That's because if the images are taller than the container, they will shrink vertically but not horizontally (it would be the opposite with a row layout).
To prevent that, use object-fit
(not supported by IE and Edge):
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With