Consider a typical set of image gallery thumbnails:

<ul>
  <li><a href="#"><img src="http://lorempixel.com/320/180/sports" /></a></li>
  <li><a href="#"><img src="http://lorempixel.com/320/180/city" /></a></li>
  <li><a href="#"><img src="http://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).

Aspect ratio example images in a row

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="http://lorempixel.com/320/180/sports" /></a></li>
  <li><a href="#"><img src="http://lorempixel.com/320/320/city" /></a></li>
  <li><a href="#"><img src="http://lorempixel.com/200/150/technics" /></a></li>
</ul>

Responsive aspect ratio examples - part 2

There are various solutions to this problem:

  1. We could resize every image by hand. That’s time-consuming and tedious.
  2. 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.
  3. 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:

Responsive aspect ratio examples - example 3

View the demonstration code…

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.

Craig is a freelance UK web consultant who built his first page for IE2.0 in 1995. Since that time he's been advocating standards, accessibility, and best-practice HTML5 techniques. He's written more than 1,000 articles for SitePoint and you can find him @craigbuckler

Get your free chapter of Level Up Your Web Apps with Go

Get a free chapter of Level Up Your Web Apps with Go, plus updates and exclusive offers from SitePoint.


Related books & courses
Lean Websites

Available on SitePoint Premium. Check it out now!