Demo: Responsive Images

Stepping through ideas for the implementation of a picture element. Inspired by this A List Apart post and my own later (but now also old) follow-up blog post. In the course of working on this, this MDN page came in handy as a clarifying agent.

Step 1: Start with something simple but fairly useful

We have some text with a max-width on it; we have an figure/image combo that starts off as a centered block element. Then we float it into the text when there's enough space to support it. Fairly basic responsive effect.

Here's the HTML code.

<figure class="picture_element_demo__image--float-right">
    <img class=""
         src="https://dummyimage.com/300x300"
         alt="">
    <figcaption>Our cool responsive image that sometimes floats.</figcaption>
</figure>
    

And a touch of sass:

.picture_element_demo__image--float-right {
  margin: auto;
  max-width: 300px;

  @media screen and (min-width: 762px) {
    float: right;
    margin: 0 0 1rem 1rem;
  }
}
        

Architecto ex dolorum vel et et porro non. Placeat libero reiciendis consequatur et. Quis illo eos saepe quaerat. Eligendi perferendis itaque cupiditate soluta repellat ut voluptatem qui.

Our cool responsive image that sometimes floats.

Similique est iste incidunt labore sit. Sit reprehenderit qui qui consectetur deserunt autem. Rerum in eum consequatur placeat reiciendis. Deleniti laboriosam rem aut voluptas omnis repellat dolor inventore. Sed quaerat consequatur consequatur quas illo vel.p Ut ex voluptates non architecto.

Omnis pariatur explicabo aut odit. Eos ea a praesentium culpa nihil doloremque voluptas. Nobis sint autem suscipit vel temporibus maxime. Temporibus sunt officiis eius. Labore odio dolores debitis repellat nihil. Molestias voluptatem qui cupiditate itaque quiap rem id.

Non praesentium aspernatur voluptas ut. Cumque voluptatum eveniet repellat ullam saepe sed sit. Ipsa magni labore expedita ab et voluptatem officiis. Ad deleniti quo natus voluptatem. Quam error nulla ut sed ducimus nihil iure perspiciatis. Necessitatibusp itaque fuga nihil alias distinctio beatae perferendis.

Doloribus officia repudiandae corporis odit aut. Ut adipisci vero ea facilis ipsam et ut. Odio voluptas quia voluptate ea consequatur voluptatem commodi. Non omnis eum numquam distinctio commodi illo.

Step 2: Now add srcset and sizes to the img element

What we want to do is get some idea of what the browsers loads and if in fact various versions of the image are in fact loaded. Also we want to make sure that what we've done so far actually works in this context.

This is something you kind of have to mess around with to get an idea of what's happening. As the List Apart article mentions, it's also not something we want to be too picky about at this point. We're mostly interested in helping the browser understand what version of the image it should go get based on the factors its aware of that we either aren't (bandwidth, supposedly) or shouldn't care about (screen size).

Also worth noting, as noted in the List Apart article re: ems in the sizes calc statement: rem, too, seems to fall back to a browser-standard 16 px, so I wasn't quite seeing the results I was expecting, when I originally plugged in (100vw - 4rem). So I had to scale up my 4rem to match the 20px rem I set in the stylesheet (20px = 16px * 1.25; 4rem * 1.25 = 5rem).

This stage, ultimately, is about asset management, nothing more. We're not into art direction yet.

Here's the HTML code.

<figure class="picture_element_demo__image--float-right">
    <img class=""
         srcset="https://dummyimage.com/900x900?text=Not+Even+Real+(900x900) 900w,
                 https://dummyimage.com/600x600?text=Giant+(600x600) 600w,
                 https://dummyimage.com/450x450?text=Middle+(450x450) 450w,
                 https://dummyimage.com/300x300?text=Small+(300x300) 300w,
                 https://dummyimage.com/150x150?text=Tiny+Tiny+(150x150) 150w"
         sizes="(max-width: 380px) calc(100vw - 5rem),
                 300px"
         src="https://dummyimage.com/300x300"
         alt="">
    <figcaption>Our cool responsive image that sometimes floats and which now includes srcset and sizes attributes, to help the browser download the most sensible version of the image it can.</figcaption>
</figure>
    

And a touch of sass:

.picture_element_demo__image--float-right {
  margin: auto;
  max-width: 300px;

  @media screen and (min-width: 762px) {
    float: right;
    margin: 0 0 1rem 1rem;
  }
}
        

Architecto ex dolorum vel et et porro non. Placeat libero reiciendis consequatur et. Quis illo eos saepe quaerat. Eligendi perferendis itaque cupiditate soluta repellat ut voluptatem qui.

Our cool responsive image that sometimes floats and which now includes srcset and sizes attributes, to help the browser download the most sensible version of the image it can.

Similique est iste incidunt labore sit. Sit reprehenderit qui qui consectetur deserunt autem. Rerum in eum consequatur placeat reiciendis. Deleniti laboriosam rem aut voluptas omnis repellat dolor inventore. Sed quaerat consequatur consequatur quas illo vel.p Ut ex voluptates non architecto.

Omnis pariatur explicabo aut odit. Eos ea a praesentium culpa nihil doloremque voluptas. Nobis sint autem suscipit vel temporibus maxime. Temporibus sunt officiis eius. Labore odio dolores debitis repellat nihil. Molestias voluptatem qui cupiditate itaque quiap rem id.

Non praesentium aspernatur voluptas ut. Cumque voluptatum eveniet repellat ullam saepe sed sit. Ipsa magni labore expedita ab et voluptatem officiis. Ad deleniti quo natus voluptatem. Quam error nulla ut sed ducimus nihil iure perspiciatis. Necessitatibusp itaque fuga nihil alias distinctio beatae perferendis.

Doloribus officia repudiandae corporis odit aut. Ut adipisci vero ea facilis ipsam et ut. Odio voluptas quia voluptate ea consequatur voluptatem commodi. Non omnis eum numquam distinctio commodi illo.

Step 3: Changing it up with art direction

In this case, we (at least for now) dump the srcset stuff in favor of actually changing the image based on screen conditions we're interested in responding to.

In this example we're changing as little as possible: we're keeping a square image, but we'd change the crop of the image. When the image is floated, in this case, we'd have more "surrounding context" in the image. When the image is centered, we'd crop in a bit more tight, onto a specific detail of the image.

To me this actually feels even more straight-forward than the srcset stuff above. I'm being very explicit about what I'm telling the browser to do: if this condition is true, show this image, if this next condition is true, show this other image.

Here's the HTML code.

<figure class="picture_element_demo__image--float-right">
    <picture>
        <source media="(max-width: 761px)"
                srcset="https://dummyimage.com/300x300?text=Detail+Shot">
        <source media="(min-width: 762px)"
                srcset="https://dummyimage.com/300x300?text=Context-heavy">
        <img class=""
             src="https://dummyimage.com/300x300"
             alt="">
    </picture>

    <figcaption>Our cool responsive image that sometimes floats and which now uses a picture wrapper with source elements that dictates actual different images that should be used in specific screen-width scenarios.</figcaption>
</figure>
    

And a touch of sass:

.picture_element_demo__image--float-right {
  margin: auto;
  max-width: 300px;

  @media screen and (min-width: 762px) {
    float: right;
    margin: 0 0 1rem 1rem;
  }
}
        

Architecto ex dolorum vel et et porro non. Placeat libero reiciendis consequatur et. Quis illo eos saepe quaerat. Eligendi perferendis itaque cupiditate soluta repellat ut voluptatem qui.

Our cool responsive image that sometimes floats and which now uses a picture wrapper with source elements that dictates actual different images that should be used in specific screen-width scenarios.

Similique est iste incidunt labore sit. Sit reprehenderit qui qui consectetur deserunt autem. Rerum in eum consequatur placeat reiciendis. Deleniti laboriosam rem aut voluptas omnis repellat dolor inventore. Sed quaerat consequatur consequatur quas illo vel.p Ut ex voluptates non architecto.

Omnis pariatur explicabo aut odit. Eos ea a praesentium culpa nihil doloremque voluptas. Nobis sint autem suscipit vel temporibus maxime. Temporibus sunt officiis eius. Labore odio dolores debitis repellat nihil. Molestias voluptatem qui cupiditate itaque quiap rem id.

Non praesentium aspernatur voluptas ut. Cumque voluptatum eveniet repellat ullam saepe sed sit. Ipsa magni labore expedita ab et voluptatem officiis. Ad deleniti quo natus voluptatem. Quam error nulla ut sed ducimus nihil iure perspiciatis. Necessitatibusp itaque fuga nihil alias distinctio beatae perferendis.

Doloribus officia repudiandae corporis odit aut. Ut adipisci vero ea facilis ipsam et ut. Odio voluptas quia voluptate ea consequatur voluptatem commodi. Non omnis eum numquam distinctio commodi illo.

Step 4: But like actually seriously change it up with art direction, for realsies

That's a bare-bones example. What we really want to do with something like this is more like...

Can we build it? Yes we can:

Here's the HTML code.

<figure class="picture_element_demo__image--dramatic">
    <picture>
        <source media="(max-width: 520px)"
                srcset="https://dummyimage.com/300x300?text=1:1+Detail+Shot">
        <source media="(max-width: 761px)"
                srcset="https://dummyimage.com/400x300?text=4:3+Landscape+With+Context">
        <source media="(min-width: 762px)"
                srcset="https://dummyimage.com/300x533?text=16:9+Weird+Portrait+Crop">
        <img class=""
             src="https://dummyimage.com/300x300"
             alt="">
    </picture>

    <figcaption>Our cool responsive image that sometimes floats and which now uses a picture wrapper with source elements that dictates actual different images that should be used in specific screen-width scenarios.</figcaption>
</figure>
    

And a touch of sass:

.picture_element_demo__image--dramatic {
  margin: auto;

  @media screen and (min-width: 762px) {
    float: right;
    margin: 0 0 1rem 1rem;
    max-width: 300px;
  }
}
        

Architecto ex dolorum vel et et porro non. Placeat libero reiciendis consequatur et. Quis illo eos saepe quaerat. Eligendi perferendis itaque cupiditate soluta repellat ut voluptatem qui.

Our cool responsive image that sometimes floats and which now uses a picture wrapper with source elements that dictates actual different images that should be used in specific screen-width scenarios.

Similique est iste incidunt labore sit. Sit reprehenderit qui qui consectetur deserunt autem. Rerum in eum consequatur placeat reiciendis. Deleniti laboriosam rem aut voluptas omnis repellat dolor inventore. Sed quaerat consequatur consequatur quas illo vel.p Ut ex voluptates non architecto.

Omnis pariatur explicabo aut odit. Eos ea a praesentium culpa nihil doloremque voluptas. Nobis sint autem suscipit vel temporibus maxime. Temporibus sunt officiis eius. Labore odio dolores debitis repellat nihil. Molestias voluptatem qui cupiditate itaque quiap rem id.

Non praesentium aspernatur voluptas ut. Cumque voluptatum eveniet repellat ullam saepe sed sit. Ipsa magni labore expedita ab et voluptatem officiis. Ad deleniti quo natus voluptatem. Quam error nulla ut sed ducimus nihil iure perspiciatis. Necessitatibusp itaque fuga nihil alias distinctio beatae perferendis.

Doloribus officia repudiandae corporis odit aut. Ut adipisci vero ea facilis ipsam et ut. Odio voluptas quia voluptate ea consequatur voluptatem commodi. Non omnis eum numquam distinctio commodi illo.

Step 5: And now...combine!

Can we mash up the complex example from step 4 with the srcset'y goodness of step 2? Sure! Why not!*

We're actually already on the way, as the source element is using a srcset attribute. We just need to add some more resolutions of each image, and toss in some sizes detail, and away we go.

* - Probably because it gets wacky complex, thinking through the various options and having to come up with all the crops and multiresolutioned copies of the crops. Maybe this isn't something you'd want to do in an entire photo gallery kind of scenario. Or inside a CMS. But for that one striking image you want to have pop just so...

Here's the HTML code.

<figure class="picture_element_demo__image--dramatic">
    <picture>
        <source media="(max-width: 520px)"
                srcset="https://dummyimage.com/900x900?text=1:1+Detail+Shot+(900x900) 900w,
                        https://dummyimage.com/600x600?text=1:1+Detail+Shot+(600x600) 600w,
                        https://dummyimage.com/450x450?text=1:1+Detail+Shot+(450x450) 450w,
                        https://dummyimage.com/300x300?text=1:1+Detail+Shot+(300x300) 300w,
                        https://dummyimage.com/150x150?text=1:1+Detail+Shot+(150x150) 150w"
                sizes="calc(100vw - 5rem)">
        <source media="(max-width: 761px)"
                srcset="https://dummyimage.com/200x150?text=Landscape-ish+(200x150) 200w,
                        https://dummyimage.com/1200x900?text=Landscape-ish+(1200x900) 1200w,
                        https://dummyimage.com/800x600?text=Landscape-ish+(800x600) 800w,
                        https://dummyimage.com/400x300?text=Landscape-ish+(400x300) 400w"
                sizes="calc(100vw - 5rem)">
        <source media="(min-width: 762px)"
                srcset="https://dummyimage.com/300x533?text=16:9+(300x533) 300w,
                        https://dummyimage.com/600x1066?text=16:9+(600x1066) 600w,
                        https://dummyimage.com/900x1599?text=16:9+(900x1599) 900w,
                        https://dummyimage.com/150x266?text=16:9+(150x266) 150w"
                sizes="300px">
        <img class=""
             src="https://dummyimage.com/300x300"
             alt="">
    </picture>

    <figcaption>Our cool responsive image that (blah blah blah).</figcaption>
</figure>
    

And a touch of sass:

.picture_element_demo__image--dramatic {
  margin: auto;

  @media screen and (min-width: 762px) {
    float: right;
    margin: 0 0 1rem 1rem;
    max-width: 300px;
  }
}
        

Architecto ex dolorum vel et et porro non. Placeat libero reiciendis consequatur et. Quis illo eos saepe quaerat. Eligendi perferendis itaque cupiditate soluta repellat ut voluptatem qui.

Our cool responsive image that sometimes floats and which now uses a picture wrapper with source elements that dictates actual different images that should be used in specific screen-width scenarios. It also expands to use srcset and sizes to offer resolutions of each image to match what the browser thinks it should download. Fun.

Similique est iste incidunt labore sit. Sit reprehenderit qui qui consectetur deserunt autem. Rerum in eum consequatur placeat reiciendis. Deleniti laboriosam rem aut voluptas omnis repellat dolor inventore. Sed quaerat consequatur consequatur quas illo vel.p Ut ex voluptates non architecto.

Omnis pariatur explicabo aut odit. Eos ea a praesentium culpa nihil doloremque voluptas. Nobis sint autem suscipit vel temporibus maxime. Temporibus sunt officiis eius. Labore odio dolores debitis repellat nihil. Molestias voluptatem qui cupiditate itaque quiap rem id.

Non praesentium aspernatur voluptas ut. Cumque voluptatum eveniet repellat ullam saepe sed sit. Ipsa magni labore expedita ab et voluptatem officiis. Ad deleniti quo natus voluptatem. Quam error nulla ut sed ducimus nihil iure perspiciatis. Necessitatibusp itaque fuga nihil alias distinctio beatae perferendis.

Doloribus officia repudiandae corporis odit aut. Ut adipisci vero ea facilis ipsam et ut. Odio voluptas quia voluptate ea consequatur voluptatem commodi. Non omnis eum numquam distinctio commodi illo.

Reiciendis culpa eligendi vero. Asperiores aut et nihil aspernatur nemo et enim distinctio. Sed culpa maiores in. Voluptate voluptas suscipit unde et praesentium. Consequatur necessitatibus ex consectetur nam neque aut modi.

Voluptatem est illum tempora illo. Excepturi quibusdam nemo sint nobis aut animi vero. Quis sit rerum libero.

Nisi facilis officia quae. Excepturi velit et magnam iusto quis. Assumenda inventore rerum et cum cupiditate voluptas et. Nihil inventore rerum similique quibusdam. Sit dolorum omnis odio minus quaerat et veritatis.

Step 6: To come: using aspect ratio media queries to make your wildest layout fantasies come true

If we want to get very funky, we can use aspect ratios in our media queries, to better lay out our content (and serve up properly formatted images) based on whether the user is looking at a page in landscape or portrait mode.

I'm going to come back to this one later, because I know that thinking it through can cause low-grade headaches. The good news is once you do figure it out and do the original think-through, I think it gets easier to duplicate the technique on demand. Maybe. I'm not sure. I haven't had as much demand for it as I'd have originall thought or liked...