Art Directed Responsive Images with Craft

What’s the point?

Sorry, images get cropped centre-centre automatically.

Responsive images.

<picture>
<source srcset="big-image.jpg" media="(min-width: 1041px)">
<source srcset="medium-image.jpg" media="(min-width: 801px)">
<source srcset="small-image.jpg" media="(min-width: 301px)"></picture>

Define your transforms.

{
"default" : {
"quality" : 82,
"position" : "center-center",
"mode" : "crop"
},
"example-transform" : {
"default" : {
"format" : "png"
},
"large" : {
"width" : 1440
},
"medium" : {
"width" : 800
},
"small" : {
"width" : 400
}
}
}
craft.JsonTransforms.getTransform("example-transform", "small")
{
"quality" : 82,
"position" : "center-center",
"mode" : "crop",
"format" : "png",
"width" : 400
}
{% macro getTransform(image, baseTransform, size) %}    {% set thisTransform = craft.JsonTransforms.getTransform("example-transform", "small") %}    {{ image.getUrl(thisTransform) }}{% endmacro %}
<picture>
<source srcset="{{ macros.getTransform(image, "example-transform", "large") }}" media="(min-width: 1041px)">
<source srcset="{{ macros.getTransform(image, "example-transform", "medium") }}" media="(min-width: 801px)">
<source srcset="{{ macros.getTransform(image, "example-transform", "small") }}" media="(min-width: 301px)">
</picture>

Adding in some direction

Over to the CMS.

Back to the code.

  1. We’re working desktop first. So we’re thinking large-medium-small, not small-medium-large.
  2. If we define an alternative image, we want to use that one from now on unless specified otherwise. For example, we define a new medium image, so we want to use that image on our small size as well, unless we also specify an alternative small image.
{% set breakpoints = [{'large':'1440px', 'medium':'800px', 'small':'400px'}] %}
{% set imageMap = [] %}
{% set currentImage = image %}
{% set altImages = image['alternativeImages'] ?? [] %}
{% for key,value in breakpoints %}
{% for altImage in altImages %}
{% if altImage.context.value == key %}
{% set currentImage = altImage.image.first() ?? currentImage %}
{% endif %}
{% endfor %}
{% set map = {(''~key) : currentImage} %}
{% set imageMap = imageMap|merge(map) %}
{% endfor %}
[
'large' => 'bear.jpg',
'medium' => 'bear.jpg',
'small' => 'small-bear.jpg'
]
<picture>
{% for key,value in breakpoints %}
{% set image = imageMap[key] ?? image %}
<source srcset="{{ core.getTransform(image, baseTransform, key) }}" media="(min-width: {{ value }})"> {% endfor %}</picture>

So yeah.

--

--

--

Lead Developer at Honcho (https://honcho.agency)

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Michael Westwood

Michael Westwood

Lead Developer at Honcho (https://honcho.agency)

More from Medium

How to use Tailwindcss 3 with plain html

Final product

< Lets Git to it >_

Installation — Electron from zero to hero

Top 10 reasons to use bootstrap framework