# Responsive images

Responsive images are images of undeclared dimension which can adjust their size to ﬁll the layout of the page. This means you can have an image which ﬁlls the user’s viewport — no matter if the user is on a phone or a laptop.

## The problem

For obvious reasons, ﬂuid images must not have a declared with and height. Since the width and height of the image are unspeciﬁed, the browser must wait for the image to load to ﬁnalize the page’s layout. This means that the content will jump around as images arrive. It’s frustrating to read an article with lots of images and have to keep scrolling up and down to ﬁnd where that sentence you were just reading has disappeared to.

## The solution

Wrap the image in container whose dimensions are of the same ratio as the image within, then allow the image container to adjust to the size of its parent while remaining no great than the image within.

<span class="fluid_outer" style="max-width: 700px">
<img class="fluid" src="/foo.jpg">
</span>
</span>
.fluid_outer {
display: block;
}

.fluid_inner {
position: relative;
overflow: hidden;
height: 0;
max-width: 100%;
margin: 0 auto;
display: block;
}

img.fluid {max-width: 100%}

{|<} N.B. To omit this container would cause a small image to ﬁll the width of its parent.

To accomplish this we set the maximum width of fluid_outer to width of the image. This ensures the ﬂuid image wrapper is always smaller than the image it contains. We then set the padding-bottom property of ﬂuid_inner to the ratio of the image’s height to its width. The principle of the technique is borrowed from this excellent post on responsive video embeds.

To do this manually would be tedious so Blot automatically retrieves the dimensions of any image embedded in blog posts, calculates the correct ratio then wraps them in the containers. I accomplish this using cheerio to manipulate the entry’s HTML, request to retrieve the image and imagesize to calculate its dimensions.

All told Blot will automatically turn this markdown:

![A book cover](http://i.imgur.com/9S9tLiD.jpg)

into a ﬂuid image. Because we apply max-width` to the image container it will still work with smaller images:

And it works as you’d hope? Ideally one wrapper would be better than two. What about if I want the image to ﬂow inline with text? Then this technique doesn’t work.