November 18, 2014

Proportionally Scale or Crop Images Using CSS

How do you resize an image so that it fits inside a fixed size container while maintaining its aspect ratio? The apparent solution is to set the image width, height, min-width and/or min-height to 100% or auto. However, this solution is not generic enough to handle images with varying aspect ratios properly. Here is an example:

Proportionally Resized Images

The green borders indicate the desired output i.e. fit the image inside the container (or conversely, fill the container with the image as indicated by the red borders). It is obvious that you need to use different rules depending on the aspect ratio of the container and the image. CSS alone cannot choose the correct rule; you must use JavaScript to determine whether to fit the image horizontally or vertically.

CSS3 provides a solution (well, sort of): the background-size property. The interesting values for this property are:

contain: Scale the image, while preserving its intrinsic aspect ratio (if any), to the largest size such that both its width and its height can fit inside the background positioning area.

cover: Scale the image, while preserving its intrinsic aspect ratio (if any), to the smallest size such that both its width and its height can completely cover the background positioning area.

Unfortunately, this technique applies to background images. Using background images instead of <img> tags will create accessibility issues, e.g. users cannot right click to save the image. One possible workaround is to use a link that points to the actual image as the background image container. Another, possibly bigger, issue is that search engines do not index background images. One workaround is to use image tags along with this technique but hide them using (SEO-friendly) CSS.

Time to see this technique in action: