How to Maintain Image Aspect Ratios in Responsive Web Design
Consider a typical set of image gallery thumbnails:
<ul>
<li><a href="#"><img src="https://lorempixel.com/320/180/sports" /></a></li>
<li><a href="#"><img src="https://lorempixel.com/320/180/city" /></a></li>
<li><a href="#"><img src="https://lorempixel.com/352/198/technics" /></a></li>
</ul>
We can show this gallery at any size in a responsive page template using CSS (essential properties shown):
ul
{
width: 100%;
padding: 0;
margin: 0 0 2em 0;
list-style-type: none;
}
li
{
float: left;
width: 33.3%;
padding: 0;
margin: 0;
background-color: #000;
border: 10px solid #fff;
-moz-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
}
li a
{
display: block;
width: 100%;
}
img
{
display: block;
max-width: 100%;
}
This works well because all our images have the same 16:9 aspect ratio. The height of the image is exactly 56.25% of the width (9 divided by 16 expressed as a percentage).
However, we web designers are paranoid: people conspire against us and supply photographs in an infinite range of sizes and aspect ratios, e.g.
<ul>
<li><a href="#"><img src="https://lorempixel.com/320/180/sports" /></a></li>
<li><a href="#"><img src="https://lorempixel.com/320/320/city" /></a></li>
<li><a href="#"><img src="https://lorempixel.com/200/150/technics" /></a></li>
</ul>
There are various solutions to this problem:
- We could resize every image by hand. That’s time-consuming and tedious.
- We could implement a clever automated server-based image resizing solution. That could take a while and resulting images may not be as polished or optimized as we like.
- We could throw a diva-like tantrum and refuse to work under such conditions. Of course, that’s unprofessional and none of us would resort to such tactics (too often).
Or can we use CSS to solve the issue?
We can, but it’s not as straight-forward as you may expect. In the old fixed-width design days we would have known the width of our image placeholder. If it was 160px, we could make the height 90px and leave early for a beer. In this example, our width is 33.3% of the container minus 20px for the border on the left and right-hand edges. It could be any size so setting a fixed height will impede our required aspect ratio.
The Percentage Padding Ploy
A little-known quirk of padding is that setting a top or bottom percentage bases it on the width of the containing block. If your block is 100px in width, padding-top: 30%;
will equate to 30 pixels. I suspect this was done to make rendering calculations easier since element heights are normally determined by their content. Besides, if you had a fixed-height parent of 300px and set padding-top: 200%;
on a child, the parent would become at least 600px — thus leading to a recursive cascade which breaks the web.
Whatever the reason, it’s very useful since it permits you to set an intrinsic ratio, e.g.
#element
{
position: relative;
height: 0;
padding: 56.25% 0 0 0;
}
This element will retain a 16:9 ratio based on the width of the container. The height has been set at 0px but, since we have set position: relative;
, we can absolutely position any child element.
As far as I’m aware, the padding trick was first highlighted by Thierry Koblentz to create responsive videos, but the same concept can be applied to images or any other content. Let’s update our thumbnail CSS:
li a
{
display: block;
width: 100%;
position: relative;
height: 0;
padding: 56.25% 0 0 0;
overflow: hidden;
}
img
{
position: absolute;
display: block;
max-width: 100%;
max-height: 100%;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}
The result will show the image with black borders if it does not have a matching 16:9 dimension:
Play around with the CSS. Removing the image max-width
or max-height
can apply cropping effects rather than resizing. I hope you find it useful.
If you’re interesting in learning more about Responsive Web Design, check out our new book, Jump Start Responsive Web Design. It’s tech edited by Craig Buckler, the author of this article.