Look at this cat. This image of my cat is the crux of this entire post. Now resize your browser and watch what happens (spoiler alert: the image resizes intelligently).

Desmond

If you’d rather see an animated demo, then check out this CodePen.

The Goal

When I revamped this blog, I had some very specific criteria in mind for how I wanted to present images, much of it with regard to responsive design. Slapping width: 100% on my images wasn’t good enough.

  • Images must be centered and nicely framed with a border and shadow.
  • Space permitting, images must display at their original size, without stretching.
  • Images can never exceed the width of the space they’re in. No overflow or cutoff.
  • If an image were to exceed the width of its container, it must scale down to fit.
  • All of this must work whether or not the image is wrapped in a link tag.
  • No JavaScript. window.onresize? Gross.

The Solution

Fortunately, I was able to achieve all of this with a single wrapper div and a modest amount of CSS. You already saw the solution in action when you resized your browser.

Here’s what the HTML looks like:

<!-- image only -->
<div class="blog-insert">
  <img src="http://codersblock.com/desmond.jpg" alt="Desmond">
</div>

<!-- image with link -->
<div class="blog-insert">
  <a href="http://codersblock.com">
    <img src="http://codersblock.com/desmond.jpg" alt="Desmond">
  </a>
</div>

And here’s the CSS:

.blog-insert {
  max-width: 100%;
  text-align: center;
  font-size: 0;
}
.blog-insert > * {
  display: inline-block;
  border: solid 4px #fff;
  box-shadow: 0 0 10px #666;
}
.blog-insert img {
  max-width: 100%;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
.blog-insert a img {
  width: 100%;
}

I won’t bore you with a CSS line-by-line, but the basic idea is to use width and max-width in just the right combination, while box-sizing: border-box prevents the added border pixels from throwing off the widths. Centering is done with text-align: center and display: inline-block.