Consider a typical set of image gallery thumbnails:
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; 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.
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.
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.