Use flexbox and maintain an aspect ratio even though content is sized differently
To maintain the aspect ratio of responsive elements, you can use the padding technique.
Note that you shouldn't use percentages on padding bottom/top for flex children, see here for more info.
You can make a grid of responsive squares and add border-radius to make them circles.
For the images, the object-fit: cover;
property does exactly what you need : keep the image original aspect ratio and covering the element completely.
I changed the first image to a landscape image to show this technique works also with those.
Here is an example of how you can achieve your aim (I stripped some of your CSS out to keep the demo simple) :
*,*::before,*::after { box-sizing: border-box; margin: 0; padding: 0;}
.img-gallery { background: #fafafa; padding: 24px; min-width: 320px; width: 90%; margin: 0 auto;}
.img-gallery .row { display: flex; flex-wrap: nowrap; justify-content: space-around; align-items: center;}
.img-gallery a { display: block; position:relative; text-decoration: none; background-image: linear-gradient(60deg, #004494 0%, #7db9e8 78%, #c2dfed 100%); overflow: hidden; border-radius: 50%; flex: 1; margin: 24px;}.img-gallery a::before{ content:''; display:block; padding-bottom:100%;}
.img-gallery .row:first-of-type a:not(:nth-child(2)) { width: 30%; width: calc((60% - 96px) / 2);}
.img-gallery .row:first-of-type a:nth-child(2) { flex: 2;}
.img-gallery span { position:absolute; top:3px;left:3px;right:3px;bottom:3px; border-radius: 50%; overflow: hidden; transition: transform 250ms;}
.img-gallery img { width: 100%; height: 100%; object-fit: cover; transition:transform 0.5s;}.img-gallery a:hover img{ transform:scale(1.25);}
<div class="img-gallery"> <div class="row"> <a href="#" title="Show large image"><span><img itemprop="image" src="https://farm7.staticflickr.com/6217/6216951796_e50778255c.jpg" id="img-1-3"></span></a> <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/d6/df/51/d6df512a2f15f517767b4d82d2d97a4c.jpg" id="img-1-4"></span></a> <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/ec/a9/dd/eca9dd106a04cdbee399870252ef711f.jpg" id="img-1-5"></span></a> </div> <div class="row"> <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/7d/01/19/7d0119a2fec989e208f288326c7cad0f.jpg" id="img-1-6"></span></a> <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/d8/c3/32/d8c332d09b03673845b2e92a48816233.jpg" id="img-1-7"></span></a> <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/88/3b/dd/883bddab14168f5f0807fec021002d8d.jpg" id="img-1-8"></span></a> </div> <div class="row"> <a href="#" title="Show large image"><span><img itemprop="image" src="https://s-media-cache-ak0.pinimg.com/originals/8e/4f/bb/8e4fbb89b155d15521b80d1baf9290d1.jpg" id="img-1-9"></span></a> </div></div>
Maintain image aspect ratio when changing height
For img tags if you define one side then other side is resized to keep aspect ratio and by default images expand to their original size.
Using this fact if you wrap each img tag into div tag and set its width to 100% of parent div then height will be according to aspect ratio as you wanted.
http://jsfiddle.net/0o5tpbxg/
* {
margin: 0;
padding: 0;
}
.slider {
display: flex;
}
.slider .slide img {
width: 100%;
}
Why does flexbox stretch my image rather than retaining aspect ratio?
It is stretching because align-self
default value is stretch
.
Set align-self
to center
.
align-self: center;
See documentation here:
align-self
max-width of img inside flexbox doesn't preserve aspect ratio
How to fix IE and Firefox
The following changes should result in the same result across Chrome, Firefox and IE:
- Add
flex: 0 0 auto;
to.flex-item img
. This fixes IE - Add
object-fit: scale-down;
to.flex-item img
. This fixes Firefox
.flex-container {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
-ms-flex-flow: row wrap;
flex-flow: row wrap;
justify-content: flex-start;
}
.flex-item {
height: 222px;
width: 200px;
border: 1px solid lightgray;
padding: 5px;
margin: 5px;
}
.flex-item img {
flex: 0 0 auto;
max-width: 100%;
max-height: 100%;
align-self: center;
-webkit-align-self: center;
margin: auto;
object-fit: scale-down;
}
.item-image {
border: 1px solid lightgray;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
width: 190px;
height: 120px;
}
<div class="flex-container">
<div class="flex-item">
<div class="item-image">
<img src="http://www.joshuacasper.com/contents/uploads/joshua-casper-samples-free.jpg">
</div>
</div>
<div class="flex-item">
<div class="item-image">
<img src="https://c1.staticflickr.com/9/8264/8700922582_d7b50280b4_z.jpg">
</div>
</div>
<div class="flex-item">
<div class="item-image">
<img src="http://www.pinaldave.com/bimg/ilovesamples.jpg">
</div>
</div>
<div class="flex-item">
<div class="item-image">
<img src="http://appslova.com/wp-content/uploads/2014/11/Android-.png">
</div>
</div>
</div>
Padding-bottom/top in flexbox layout
Update September 2020
Firefox and edge have implemented the behaviour from the specs and margin + padding for flex elements are both calculated according to the width of the containing block.
Just like block elements.
Update February 2018
Firefox and edge have agreed to change their behaviour on top, bottom margin and padding for flex (and grid) items :
[...] e.g. left/right/top/bottom percentages all resolve against their containing block’s width in horizontal writing modes. [source]
This is not yet implemented (tested on FF 58.0.2).
Update April 2016
(still valid in may 2017)
The specs have been updated to:
Percentage margins and paddings on flex items can be resolved against either:
- their own axis (left/right percentages resolve against width, top/bottom resolve against height), or,
- the inline axis (left/right/top/bottom percentages all resolve against width)
source: CSS Flexible Box Layout Module Level 1
This means that chrome IE FF and Edge (even if they don't have the same behaviour) follow the specs recommendation.
Specs also say:
Authors should avoid using percentages in paddings or margins on flex
items entirely, as they will get different behavior in different
browsers. [source]
Workaround
You can wrap the first child of the flex container in an other element and put the padding-bottom
on the second child :
#flexBox {
border: 1px solid red;
width: 50%;
margin: 0 auto;
padding: 1em;
display: flex;
flex-direction: column;
}
#text {
border: 1px solid green;
padding: .5em;
}
#padding {
margin: 1em 0;
border: 1px solid blue;
}
#padding > div {
padding-bottom: 56.25%; /* intrinsic aspect ratio */
}
<div id='flexBox'>
<div id='padding'><div></div></div>
<div id='text'>Some text</div>
</div>
Images to fit its container preserving size ratio
Seems to work pretty much as expected. What seems to be your problem?
.container-images {
align-items: flex-end;
display: flex;
justify-content: center;
height: 400px;
max-height: 400px;
max-width: 418px;
width: 100%;
}
.container-images img {
width: 50%;
object-fit: contain;
background-color: black;
}
<div class="container-images" style="background-color: red;">
<img src="https://interactive-examples.mdn.mozilla.net/media/examples/plumeria.jpg" />
</div>
<div class="container-images" style="background-color: blue;">
<img src="https://www.w3schools.com/css/paris.jpg" />
</div>
Related Topics
Changing Jupyter's Matching Parenthesis Color
What Is The Meaning of an Ampersand in Less Selectors
Shiny Dashboadpage Lock Dashboardheader on Top
CSS Transform Square into Thinner Rhombus
Adjust Size of Shiny Progress Bar and Center It
Horizontally Center <P> Within a Div While Keeping The Text Left-Aligned
Less CSS Background with Relative Path
An Alternative to -Webkit-Transform: Transformy
Why Does Bootstrap Use a 0.02Px Difference Between Screen Size Thresholds in Its Media Queries
Align Text to The Right of an Image && Text Doesn't Wrap Around The Image
How to Target The First and The Last Element Per Row in a Flex Layout
How to Insert an Element's Index (Child Number) as Text Within The Element Solely Using CSS