You may or may not have come across this this little CSS quirk before, but if you have it will most likely have been within the context of creating responsive videos - bootstrap uses this for its Responsive embed component for example.
This technique makes use of the unique way padding-top and padding-bottom work when given percentage values - they will be interpreted as a percent of the width of the containing element, which while slightly perplexing - is the secret sauce of intrinsic ratios.
Ummm.... what is an intrinic ratio?
So, having an intrinsic ratio in this case means that an element will maintain its aspect ratio when resized - think of an <img />
with max-width: 100%
for example - change the width of it's parent and it will change size - but keep the same shape.
But what if we wanted to do that with an element which doesn't have this ratio already defined in the way an image does? Like for example a div
- with a background image.
Example
So let's say our designer has presented us with something like this:
...and some requirements:
- Images will be dynamic - we can't be sure of their dimensions.
- Layout should stay the same on any screen size.
- Images should fit into the grid but not be warped.
On the surface this looks pretty straightforward but the problem comes from not knowing what size the images are going to be - if the images aren't the right size we can't rely on them to hold the shape we want.
This means we can't just put them straight on the page in an <img />
tag - forcing them to be the correct size would warp them. We can use background images and take advantage of background-size: cover
to get around this but we are then left with the problem of not really being able to set the height as a percentage - unlike width
, height
percentages aren't really all that useful.
Here's where intrinsic ratios come in - let's create this component and call it image-grid
. CodePen
<div class="image-grid">
<div class="image-grid-item image-grid-item--2x2" style="background-image: url(https://placeimg.com/640/480/animals)"></div>
<div class="image-grid-item image-grid-item--2x1" style="background-image: url(https://placeimg.com/640/480/any)"></div>
<div class="image-grid-item image-grid-item--2x1" style="background-image: url(https://placeimg.com/640/480/tech)"></div>
</div>
.image-grid-item {
float: left;
height: 0;
background: no-repeat center center;
background-size: cover;
&--2x2 {
padding-bottom: 50%; // percentage of parent width.
width: 50%; // also percentage of width but here it makes more sense.
}
&--2x1 {
padding-bottom: 25%; // as above.
width: 50%; // as above.
}
}
So what's going on here? The first thing you might notice is that the height
is set to 0
- we don't want our items to get their height the conventional way. The padding-bottom
is where the height is going to come from, we set this to a percentage of the container's width, in this example we have one item with is half as tall as the container and two which are quarter height - 50%, and 25% respectively.
The widths are set on the item in relation to the container, though you could abstract that away to another level so that your padding-bottom
percentages were more descriptive of the actual ratios and relative to their own widths instead - 100% (1:1) and 50% (2:1) in this case. CodePen
Learning about intrinsic ratios is a bit like when you buy a particular model of car and then you start to see them everywhere - you spot opportunites to use them where before you might not have bothered, or done something that wasn't properly reponsive - and you don't wanna go and do that now do ya?