<p>Quick comment:</p>

<p>If you are using generated transforms, you are likely not doing any "art direction" with your images. Basically all your images will be the same, their dimensions alone would be different.</p>

<p>If you are not concerned about art direction, a picture element is overkill and you should just look at <code>srcset</code> and <code>sizes</code> attributes on an image tag. <a href="http://dev.opera.com/articles/native-responsive-images/">Yoav Weiss explains it better than I ever could</a>. <a href="http://ericportis.com/posts/2014/srcset-sizes/">Eric Portis also has a comprehensive blog post</a> on <code>srcset</code> and <code>sizes</code>.</p>

<pre><code>&lt;img src="small.jpg"
     srcset="large.jpg 1024w,
             medium.jpg 600w,
             small.jpg 350w"
     sizes="(min-width: 64em) 33.3vw,
            (min-width: 37.5em) 50vw,
            100vw"
     alt="alternate text" /&gt;
</code></pre>

<p>Using this, the browser will figure out which image to serve, depending on the screen size and pixel resolution. Magic.</p>

<p>PS: To make sure all the transforms are generated by Craft with picturefill, use <code>'generateTransformsBeforePageLoad' =&gt; true</code> in your general.php config file.</p>

CC BY-SA 3.0
2014-08-25T16:15:08.497Z
That setting won’t be necessary in 2.2 ;)
Brandon Kelly
CC BY-SA 3.0
2014-08-26T12:35:56.413Z
Great news. I figured as much since you are using Picturefill on buildwithcraft ;o)
Jérôme Coupé
CC BY-SA 3.0
2014-08-25T08:19:35.927Z
2014-08-25T08:19:35.927Z
Jérôme Coupé
<p>There is a great article here which I thoroughly recommend reading. It  goes into this in great detail. </p>

<p>It even includes a twig macro that deals with both retina images as well as responsive images:</p>

<p><a href="https://straightupcraft.com/articles/responsive-images-with-twig-macros">https://straightupcraft.com/articles/responsive-images-with-twig-macros</a></p>

CC BY-SA 3.0
2015-08-13T05:53:27.937Z
2015-08-13T11:29:42.520Z
2015-08-13T11:29:42.520Z
j00lz
<p>You can do this using <a href="http://buildwithcraft.com/docs/image-transforms">image transforms</a>.</p>

<p>There are a couple things you’re going to need to consider though:</p>

<ol>
<li>Not every image will necessarily be high-res (e.g. a computer screenshot taken on a non-retina screen)</li>
<li>You probably don’t want to output images that are larger than their original size</li>
</ol>

<p>For #1, we need some way of identifying images that are 1X vs. 2X. You could do this a couple different ways:</p>

<ul>
<li>Give your assets a Lightswitch field that identifies if it’s a 2X image</li>
<li>Use a consistent naming convention for 2X image filenames, e.g. “filename@2x.ext” (to borrow Retina.js’s convention)</li>
</ul>

<p>I personally prefer the second. (That’s what we do on <a href="http://buildwithcraft.com">buildwithcraft.com</a>, except we use “.2x” instead of “@2x”.)</p>

<p>We can tackle #2 with some logic in the template that only uses a transform when the resulting size is going to be smaller than the original image.</p>

<p>It’s the combination of these two problems where things get interesting: You need to figure out the image’s <a href="http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html">CSS pixel size</a> (based on whether it’s 1X or 2X) <em>before</em> you start determining whether it needs a transform, and how big to make the transform, etc.</p>

<p>Here’s what we came up with for Craft’s documentation (such as the image on the <a href="http://buildwithcraft.com/docs/image-transforms">asset transforms page</a>):</p>

<ol>
<li>Create a <a href="http://twig.sensiolabs.org/doc/tags/macro.html">macro</a> called <code>srcset()</code> which will be responsible for outputting a <code>&lt;source&gt;</code> or <code>&lt;img&gt;</code> tag’s <code>srcset=</code> attribute and value, and optionally the <code>width=</code> and <code>height=</code> attributes as well. It should accept the following arguments:
<ul>
<li><code>image</code> - an <a href="http://buildwithcraft.com/docs/templating/assetfilemodel">AssetFileModel</a></li>
<li><code>maxCssWidth</code> - the maximum “CSS pixel” width that we want to output the image at</li>
<li><code>includeDimensions</code> - whether the macro should also output the <code>width=</code> and <code>height=</code> attributes.</li>
</ul></li>
<li>Create a <code>&lt;picture&gt;</code> element with nested <code>&lt;source&gt;</code> and <code>&lt;img&gt;</code> elements per the Picture spec, using our new <code>srcset()</code> macro to write out the <code>srcset=</code> attributes.</li>
</ol>

<p>Here’s what the macro looks like:</p>

<pre><code>{% macro srcset(image, maxCssWidth, includeDimensions) %}
    {%- spaceless %}
        {# Is this a 2X image? #}
        {% set is2x = image.filename matches '/@2x\\.\\w+$/' %}

        {# Determine the CSS width for the image, if it were output at 100% #}
        {% set cssWidth = (is2x ? round(image.width / 2) : image.width) %}

        {# Determine the image size that 1X screens should get #}
        {% set width = (cssWidth &gt; maxCssWidth ? maxCssWidth : cssWidth) %}

        {# Determine the image size that 2X screens should get #}
        {% set width2x = (width * 2) &gt; image.width ? image.width : (width * 2) %}

        {# Output the srcset= attribute value #}
        srcset="{{ image.getUrl(image.width != width ? { width: width }) }}, {{ image.getUrl(image.width != width2x ? { width: width2x }) }} 2x"

        {#- Output the width= and height= attributes if needed #}
        {%- if includeDimensions %} width="{{ width }}" height="{{ image.getHeight({ width: width }) }}"{% endif %}
    {% endspaceless -%}
{% endmacro %}
</code></pre>

<p>Adjust that <code>{% set is2x = ...</code> line based on however you’re identifying 2X images. For example if you’re going the Lightswitch route instead, it could be as simple as:</p>

<pre><code>{% set is2x = image.is2x %}
</code></pre>

<p>Note that each of the <code>image.getUrl()</code> calls on the {{ output }} line are making sure that the width is different than the actual image width before passing the <code>{ width: X }</code> object into <code>getUrl()</code> - that way we’re not having Craft go through the trouble of generating a transform unless we actually need to.</p>

<p>With that macro in place, now we just need to import it in our template, and start using it.</p>

<pre class="lang-html prettyprint-override"><code>{% from _self import srcset %}

{# ... #}

{% for image in entry.myAssetsField %}
    &lt;picture&gt;
        &lt;!--[if IE 9]&gt;&lt;video style="display: none;"&gt;&lt;![endif]--&gt;
        &lt;source media="(min-width: 1000px)" {{ srcset(image, 1000) }}&gt;
        &lt;source media="(min-width: 800px)" {{ srcset(image, 800) }}&gt;
        &lt;source media="(max-width: 320px)" {{ srcset(image, 320) }}&gt;
        &lt;!--[if IE 9]&gt;&lt;/video&gt;&lt;![endif]--&gt;
        &lt;img {{ srcset(image, 600, true) }} alt="{{ image.title }}"&gt;
    &lt;/picture&gt;
{% endfor %}
</code></pre>

<p>If you placed the macro in a different template, replace <code>_self</code> with the path to that template, e.g. <code>"_macros"</code>.</p>

CC BY-SA 3.0
2014-08-25T08:20:37.983Z
Quick note: I think a picture element is overkill in this use case. `srcset` and `sizes` attributes on an `img` tag would be enough.
Jérôme Coupé
CC BY-SA 3.0
2014-08-28T00:45:19.333Z
Using a `<picture>` tag would sort of indicate art direction or a ratio change. Which is in plugin territory. See http://graphics8.nytimes.com/images/2014/05/22/blogs/imagecrop480.gif for a good demo taken from http://open.blogs.nytimes.com/2014/06/17/scoop-a-glimpse-into-the-nytimes-cms/?_php=true&_type=blogs&_r=0

With responsive design becoming the norm it wouldn't be the worst thing to find out of the box.
jnowland
CC BY-SA 3.0
2014-08-08T14:31:06.807Z
2014-08-14T14:11:34.227Z
2014-08-14T14:11:34.227Z
Brandon Kelly
<p>I want to be able to upload a single high resolution image, and output a <code>&lt;picture&gt;</code> element that outputs it with a few different sizes and resolutions automatically (using <a href="http://scottjehl.github.io/picturefill/">Picturefill</a> to sort out which one actually shows up to the browsers). How can I do that?</p>

<assets><image-transforms><image><responsive-images>
How can I automatically generate responsive images from a single hi-res asset?
# How can I automatically generate responsive images from a single hi-res asset?

(Asked by: username_0 on 2014-08-08)

I want to be able to upload a single high resolution image, and output a  element that outputs it with a few different sizes and resolutions automatically (using [Picturefill](http://scottjehl.github.io/picturefill/) to sort out which one actually shows up to the browsers). How can I do that?

**Tags:** assets, image-transforms, image, responsive-images

---

## 3 answers

### Answer by username_0 on 2014-08-08. Score: 38 | Accepted answer

You can do this using image transforms.
There are a couple things you’re going to need to consider though:

Not every image will necessarily be high-res (e.g. a computer screenshot taken on a non-retina screen)
You probably don’t want to output images that are larger than their original size

For #1, we need some way of identifying images that are 1X vs. 2X. You could do this a couple different ways:

Give your assets a Lightswitch field that identifies if it’s a 2X image
Use a consistent naming convention for 2X image filenames, e.g. “filename@2x.ext” (to borrow Retina.js’s convention)

I personally prefer the second. (That’s what we do on buildwithcraft.com, except we use “.2x” instead of “@2x”.)
We can tackle #2 with some logic in the template that only uses a transform when the resulting size is going to be smaller than the original image.
It’s the combination of these two problems where things get interesting: You need to figure out the image’s CSS pixel size (based on whether it’s 1X or 2X) before you start determining whether it needs a transform, and how big to make the transform, etc.
Here’s what we came up with for Craft’s documentation (such as the image on the asset transforms page):

Create a macro called srcset() which will be responsible for outputting a  or  tag’s srcset= attribute and value, and optionally the width= and height= attributes as well. It should accept the following arguments:

image - an AssetFileModel
maxCssWidth - the maximum “CSS pixel” width that we want to output the image at
includeDimensions - whether the macro should also output the width= and height= attributes.

Create a  element with nested  and  elements per the Picture spec, using our new srcset() macro to write out the srcset= attributes.

Here’s what the macro looks like:
{% macro srcset(image, maxCssWidth, includeDimensions) %}
    {%- spaceless %}
        {# Is this a 2X image? #}
        {% set is2x = image.filename matches '/@2x\\.\\w+$/' %}

        {# Determine the CSS width for the image, if it were output at 100% #}
        {% set cssWidth = (is2x ? round(image.width / 2) : image.width) %}

        {# Determine the image size that 1X screens should get #}
        {% set width = (cssWidth > maxCssWidth ? maxCssWidth : cssWidth) %}

        {# Determine the image size that 2X screens should get #}
        {% set width2x = (width * 2) > image.width ? image.width : (width * 2) %}

        {# Output the srcset= attribute value #}
        srcset="{{ image.getUrl(image.width != width ? { width: width }) }}, {{ image.getUrl(image.width != width2x ? { width: width2x }) }} 2x"

        {#- Output the width= and height= attributes if needed #}
        {%- if includeDimensions %} width="{{ width }}" height="{{ image.getHeight({ width: width }) }}"{% endif %}
    {% endspaceless -%}
{% endmacro %}

Adjust that {% set is2x = ... line based on however you’re identifying 2X images. For example if you’re going the Lightswitch route instead, it could be as simple as:
{% set is2x = image.is2x %}

Note that each of the image.getUrl() calls on the {{ output }} line are making sure that the width is different than the actual image width before passing the { width: X } object into getUrl() - that way we’re not having Craft go through the trouble of generating a transform unless we actually need to.
With that macro in place, now we just need to import it in our template, and start using it.
{% from _self import srcset %}

{# ... #}

{% for image in entry.myAssetsField %}
    
        
        
        
        
        
        
    
{% endfor %}

If you placed the macro in a different template, replace _self with the path to that template, e.g. "_macros".

> **Comments:**
> **username_1**: Quick note: I think a picture element is overkill in this use case. `srcset` and `sizes` attributes on an `img` tag would be enough.  
> **username_3**: Using a `<picture>` tag would sort of indicate art direction or a ratio change. Which is in plugin territory. See http://graphics8.nytimes.com/images/2014/05/22/blogs/imagecrop480.gif for a good demo taken from http://open.blogs.nytimes.com/2014/06/17/scoop-a-glimpse-into-the-nytimes-cms/?_php=true&_type=blogs&_r=0  With responsive design becoming the norm it wouldn't be the worst thing to find out of the box.  

---

### Answer by username_1 on 2014-08-25. Score: 11

Quick comment:
If you are using generated transforms, you are likely not doing any "art direction" with your images. Basically all your images will be the same, their dimensions alone would be different.
If you are not concerned about art direction, a picture element is overkill and you should just look at srcset and sizes attributes on an image tag. Yoav Weiss explains it better than I ever could. Eric Portis also has a comprehensive blog post on srcset and sizes.


Using this, the browser will figure out which image to serve, depending on the screen size and pixel resolution. Magic.
PS: To make sure all the transforms are generated by Craft with picturefill, use 'generateTransformsBeforePageLoad' => true in your general.php config file.

> **Comments:**
> **username_0**: That setting won’t be necessary in 2.2 ;)  
> **username_1**: Great news. I figured as much since you are using Picturefill on buildwithcraft ;o)  

---

### Answer by username_2 on 2015-08-13. Score: 7

There is a great article here which I thoroughly recommend reading. It goes into this in great detail.

It even includes a twig macro that deals with both retina images as well as responsive images:

<https://straightupcraft.com/articles/responsive-images-with-twig-macros>


---

