<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Daniel Wentsch</title>
    <description>The latest articles on DEV Community by Daniel Wentsch (@klick).</description>
    <link>https://dev.to/klick</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F158204%2Fb6b25468-8fea-4119-ab92-0ba67dadb526.jpg</url>
      <title>DEV Community: Daniel Wentsch</title>
      <link>https://dev.to/klick</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/klick"/>
    <language>en</language>
    <item>
      <title>Statamic Image Partial</title>
      <dc:creator>Daniel Wentsch</dc:creator>
      <pubDate>Sat, 18 Sep 2021 18:40:51 +0000</pubDate>
      <link>https://dev.to/klick/statamic-image-partial-5amf</link>
      <guid>https://dev.to/klick/statamic-image-partial-5amf</guid>
      <description>&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; Generate multiple image sizes within &lt;code&gt;&amp;lt;source&amp;gt;&lt;/code&gt; tags using provided values for media queries and image dimensions. Serve them as both the original file format and as &lt;code&gt;wepb&lt;/code&gt; for supporting browsers.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Initial situation:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This is a common pattern I use to create an optimal sized and formatted image, that will be cropped around an editor-defined focus point. However it's super annoying having to write this for each and every component with only the numbers changing from one to another:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;picture&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"block w-full"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt;
        &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"(min-width: 1280px)"&lt;/span&gt;
        &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"{{ glide:image width="&lt;/span&gt;&lt;span class="err"&gt;1120"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"1120"&lt;/span&gt; &lt;span class="na"&gt;format=&lt;/span&gt;&lt;span class="s"&gt;"webp"&lt;/span&gt; &lt;span class="na"&gt;fit=&lt;/span&gt;&lt;span class="s"&gt;"crop_focal"&lt;/span&gt; &lt;span class="err"&gt;}}"&lt;/span&gt;
        &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"image/webp"&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt;
        &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"(min-width: 1280px)"&lt;/span&gt;
        &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"{{ glide:image width="&lt;/span&gt;&lt;span class="err"&gt;1120"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"1120"&lt;/span&gt; &lt;span class="na"&gt;fit=&lt;/span&gt;&lt;span class="s"&gt;"crop_focal"&lt;/span&gt; &lt;span class="err"&gt;}}"&lt;/span&gt;
        &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"{{ image.mime_type }}"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt;
        &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"(min-width: 980px)"&lt;/span&gt;
        &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"{{ glide:image width="&lt;/span&gt;&lt;span class="err"&gt;900"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"520"&lt;/span&gt; &lt;span class="na"&gt;format=&lt;/span&gt;&lt;span class="s"&gt;"webp"&lt;/span&gt; &lt;span class="na"&gt;fit=&lt;/span&gt;&lt;span class="s"&gt;"crop_focal"&lt;/span&gt; &lt;span class="err"&gt;}}"&lt;/span&gt;
        &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"image/webp"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt;
        &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"(min-width: 980px)"&lt;/span&gt;        
                &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"{{ glide:image width="&lt;/span&gt;&lt;span class="err"&gt;900"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"520"&lt;/span&gt; &lt;span class="na"&gt;fit=&lt;/span&gt;&lt;span class="s"&gt;"crop_focal"&lt;/span&gt; &lt;span class="err"&gt;}}"&lt;/span&gt;
        &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"{{ image.mime_type }}"&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt;
        &lt;span class="na"&gt;data-srcset=&lt;/span&gt;&lt;span class="s"&gt;"{{ glide:image width="&lt;/span&gt;&lt;span class="err"&gt;450"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"260"&lt;/span&gt; &lt;span class="na"&gt;format=&lt;/span&gt;&lt;span class="s"&gt;"webp"&lt;/span&gt; &lt;span class="na"&gt;fit=&lt;/span&gt;&lt;span class="s"&gt;"crop_focal"&lt;/span&gt; &lt;span class="err"&gt;}}"&lt;/span&gt;
        &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"image/webp"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"block object-cover w-full h-auto lazyload"&lt;/span&gt;
        &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"{{ glide:image width="&lt;/span&gt;&lt;span class="err"&gt;450"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"260"&lt;/span&gt; &lt;span class="na"&gt;fit=&lt;/span&gt;&lt;span class="s"&gt;"crop_focal"&lt;/span&gt; &lt;span class="err"&gt;}}"&lt;/span&gt;
        &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"{{ title }}"&lt;/span&gt;
        &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"520"&lt;/span&gt;
        &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"900"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/picture&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  💡 Idea
&lt;/h2&gt;

&lt;p&gt;A partial could take the following arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{{ picture :viewports="2000['1600', '800'], 2000['800', '600'], DEFAULT['400', '300']" }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creating and passing an array on the fly inside an attribute doesn't work in antlers. It could be passed as a comma separated string and then exploded using the &lt;a href="https://statamic.dev/modifiers/explode" rel="noopener noreferrer"&gt;explode modifier&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But wait, I just recently learned that we can use YAML frontmatter right within antlers templates \o/. &lt;/p&gt;

&lt;p&gt;It seems way cleaner to define viewports with their respective images sizes in Frontmatter, which can then be passed as an array. No need for exploding strings at all:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;viewports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;2000&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;1600&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;800&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;1000&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;800&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;600&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;DEFAULT'&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;400&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;300&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="pi"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;partial&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;components/test&lt;/span&gt; &lt;span class="pi"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;viewports="view&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;viewports"&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can be iterated over with foreach to generate a &lt;code&gt;&amp;lt;source&amp;gt;&lt;/code&gt; tag with the media_query value being used as the value for &lt;code&gt;min-width&lt;/code&gt; and the nested&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{{ foreach:viewports as="media_query|sizes" }}
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Media Query: {{ media_query }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Width: {{ sizes:0 }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Height: {{ sizes:1 }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
{{ /foreach:viewports }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Better Solution
&lt;/h2&gt;

&lt;p&gt;YAML's &lt;em&gt;nested object syntax&lt;/em&gt; makes this look a bit nicer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;viewports:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;'w':&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'h':&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;'w':&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'h':&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;'DEFAULT':&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;'w':&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'h':&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;---&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;image&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;partial:components/picture_cropped&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;:viewports=&lt;/span&gt;&lt;span class="nl"&gt;"view:viewports"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;image=&lt;/span&gt;&lt;span class="s2"&gt;"image"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;lazy=&lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/image&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can be iterated over nicely with &lt;code&gt;{{ foreach:viewports as "media_query|dimensions"}}&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;image&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;picture&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;asset&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;:url=&lt;/span&gt;&lt;span class="s2"&gt;"image"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;extension&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'svg'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;extension&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'gif'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;img&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="err"&gt;class=&lt;/span&gt;&lt;span class="s2"&gt;"{{ class }}"&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="err"&gt;src=&lt;/span&gt;&lt;span class="s2"&gt;"{{ url }}"&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="err"&gt;alt=&lt;/span&gt;&lt;span class="s2"&gt;"{{ alt }}"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="err"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;foreach:viewports&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;as=&lt;/span&gt;&lt;span class="s2"&gt;"media_query|dimensions"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;media_query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'DEFAULT'&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;source&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="err"&gt;media=&lt;/span&gt;&lt;span class="s2"&gt;"(min-width: {{ media_query }}px)"&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="err"&gt;srcset=&lt;/span&gt;&lt;span class="s2"&gt;"{{ glide:image :width="&lt;/span&gt;&lt;span class="err"&gt;dimensions:w&lt;/span&gt;&lt;span class="s2"&gt;" :height="&lt;/span&gt;&lt;span class="err"&gt;dimensions:h&lt;/span&gt;&lt;span class="s2"&gt;" format="&lt;/span&gt;&lt;span class="err"&gt;webp&lt;/span&gt;&lt;span class="s2"&gt;" fit="&lt;/span&gt;&lt;span class="err"&gt;crop_focal&lt;/span&gt;&lt;span class="s2"&gt;" }}"&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="err"&gt;type=&lt;/span&gt;&lt;span class="s2"&gt;"image/webp"&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="err"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;source&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="err"&gt;media=&lt;/span&gt;&lt;span class="s2"&gt;"(min-width: {{ media_query }})px"&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="err"&gt;srcset=&lt;/span&gt;&lt;span class="s2"&gt;"{{ glide:image :width="&lt;/span&gt;&lt;span class="err"&gt;dimensions:w&lt;/span&gt;&lt;span class="s2"&gt;" :height="&lt;/span&gt;&lt;span class="err"&gt;dimensions:h&lt;/span&gt;&lt;span class="s2"&gt;" fit="&lt;/span&gt;&lt;span class="err"&gt;crop_focal&lt;/span&gt;&lt;span class="s2"&gt;" }}"&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="err"&gt;type=&lt;/span&gt;&lt;span class="s2"&gt;"{{ image.mime_type }}"&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="err"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;

                        &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;source&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="err"&gt;srcset=&lt;/span&gt;&lt;span class="s2"&gt;"{{ glide:image :width="&lt;/span&gt;&lt;span class="err"&gt;dimensions:w&lt;/span&gt;&lt;span class="s2"&gt;" :height="&lt;/span&gt;&lt;span class="err"&gt;dimensions:h&lt;/span&gt;&lt;span class="s2"&gt;" format="&lt;/span&gt;&lt;span class="err"&gt;webp&lt;/span&gt;&lt;span class="s2"&gt;" fit="&lt;/span&gt;&lt;span class="err"&gt;crop_focal&lt;/span&gt;&lt;span class="s2"&gt;" }}"&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="err"&gt;type=&lt;/span&gt;&lt;span class="s2"&gt;"image/webp"&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="err"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;img&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="err"&gt;class=&lt;/span&gt;&lt;span class="s2"&gt;"block object-cover w-full h-auto {{ class }}"&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="err"&gt;src=&lt;/span&gt;&lt;span class="s2"&gt;"{{ glide:image :width="&lt;/span&gt;&lt;span class="err"&gt;dimensions:w&lt;/span&gt;&lt;span class="s2"&gt;"   :height="&lt;/span&gt;&lt;span class="err"&gt;dimensions:h&lt;/span&gt;&lt;span class="s2"&gt;" fit="&lt;/span&gt;&lt;span class="err"&gt;crop_focal&lt;/span&gt;&lt;span class="s2"&gt;" }}"&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="err"&gt;alt=&lt;/span&gt;&lt;span class="s2"&gt;"{{ alt }}"&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="err"&gt;height=&lt;/span&gt;&lt;span class="s2"&gt;"{{ dimensions:h }}"&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="err"&gt;width=&lt;/span&gt;&lt;span class="s2"&gt;"{{ dimensions:w }}"&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;lazy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="err"&gt;loading=&lt;/span&gt;&lt;span class="s2"&gt;"lazy"&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="err"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/foreach:viewports&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/asset&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/picture&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Actual result when invoked:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy00jnmmh0b9powimpaeu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy00jnmmh0b9powimpaeu.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>statamic</category>
      <category>frontend</category>
      <category>templating</category>
      <category>performance</category>
    </item>
    <item>
      <title>Add Custom Utilities with TailwindCSS</title>
      <dc:creator>Daniel Wentsch</dc:creator>
      <pubDate>Thu, 31 Dec 2020 12:53:49 +0000</pubDate>
      <link>https://dev.to/klick/add-custom-utilities-with-tailwindcss-240e</link>
      <guid>https://dev.to/klick/add-custom-utilities-with-tailwindcss-240e</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rYKMOwDI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l5ayqgeqql3hoebtfxce.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rYKMOwDI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/l5ayqgeqql3hoebtfxce.png" alt="Screenshot of a custom utility defined with TailwindCSS variants directive"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sometimes I need some CSS that’s not included with Tailwind. CSS filters are a simple example. Instead of coming up with component names, adding and importing partials, we can opt into building atomic utilities that can be composed into any other component that requires such functionality.&lt;/p&gt;

&lt;p&gt;This is the exact use case for Tailwind’s &lt;code&gt;@variants&lt;/code&gt; directive.&lt;/p&gt;

&lt;p&gt;Say we want to desaturate gallery thumbnails using &lt;code&gt;filter: grayscale(100%)&lt;/code&gt; and show the coloured version on hover. Instead of writing the styles only for something highly specific such as  &lt;code&gt;.gallery__thumbnail { … }&lt;/code&gt;  I recommend adding a file called &lt;code&gt;utilities/filters.[s]css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@variants&lt;/span&gt; &lt;span class="n"&gt;hover&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;responsive&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.grayscale&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grayscale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;.filter-reset&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create those utilities together with all the variants we specified. So say we want our grayscale filter on an element but only starting at the &lt;code&gt;md&lt;/code&gt; breakpoint and bring the color back on focus and hover. Oh, and a little transition would be nice, too. We can easily compose this as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"md:grayscale md:hover:filter-reset md:focus:filter-reset transition-all duration-200 ease-in"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://tailwindcss.com/docs/functions-and-directives/#variants"&gt;Documentation of @variants directive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tailwindcss.com/docs/pseudo-class-variants/"&gt;Documentation of all available TailwindCSS variants&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tailwindcss</category>
      <category>utilityfirst</category>
      <category>css</category>
    </item>
  </channel>
</rss>
