Srcset in liquid loop

How do I tell the browser about the srcset images I have when they are pulled from a .yml file loop?
where do I put the srcset tag? … I don’t understand :slight_smile: thank you for any pointers.

Let’s start with what a no Jekyll srcset approach looks like.

<img
 srcset="
  url size,
  url size,
  url size
 "
 src="default url"
>

e.g.

<img
 srcset="
  /wp-content/uploads/flamingo4x.jpg 4025w,
  /wp-content/uploads/flamingo3x.jpg 3019w,
  /wp-content/uploads/flamingo2x.jpg 2013w,
  /wp-content/uploads/flamingo1x.jpg 1006w
 "
 src="/wp-content/uploads/flamingo-fallback.jpg"
>
1 Like

You already know how to do this.

src="{{item.image | relative_url }}" 

So do the same for srcset.

Hint: for a given image of multiple sizes, the for loop goes inside the img tag, not outside it.

You’ll still keep your outer for loop to iterate over completely different images.

1 Like

yes, I don’t understand that - I don’t know how to write the html srcset into the yaml file. the image url is in that yaml file … I don’t get it :slight_smile:

Okay thanks. I thought your question was on just the loop, not how to write YAML.

Well what you want is an array of images. Where each image has multiple fields. ie a hash.
One field as a string for URL and one field as another array for srcset.

I am going to assume relative URLs here on the same domain.

images:
  - full: "assets/dog.jpeg" # src
    resized:            # srcset
      - "assets/dog300.jpeg 300w"
      - "assets/dog800.jpeg 800w"

  - full: "assets/cat.jpeg" # src
    resized:            # srcset
      - "assets/cat300.jpeg 300w"
      - "assets/cat800.jpeg 800w"

I would highly recommend not writing such low level code yourself.

It is hard to maintain. It does not scale well and is error prone. If you want to add 10 images you have to add 10 blocks of say 5 lines each to your YAML file and they must match up exactly with the images in your assets including the resized ones.
Also please don’t resize manually. It will get forgotten or a mistake will happen eventually.

Rather use automation.

The Jekyll picture tag plugin will resize images for you at build time, given the full size image.

Plus it will build the srcset value for you :slight_smile:

Example from that page:

  1. Install
  2. Write this: {% picture test.jpg %}
  3. Get this:
<!-- Formatted for readability -->

<img src="/generated/test-800-195f7d.jpg"
  srcset="
    /generated/test-400-195f7d.jpg   400w,
    /generated/test-600-195f7d.jpg   600w,
    /generated/test-800-195f7d.jpg   800w,
    /generated/test-1000-195f7d.jpg 1000w
    ">
1 Like

If you need to provide say 3 resized images to handle small mobile, big mobile and tablet, then use srcset and gem above.

If you only need to take a full size image and make a web friendly version (like not wider than 1000px) and/or want to make a thumbnail of 200px, then I have a plugin you can use it. It is has fewer features but it much simpler to use and how it is made. It’s a Ruby script of 41 lines.

I link to a demo where I used it for a image gallery hosted on Netlify

1 Like

Absolutely, I’ll just write them into one html page and forget about the yaml file loop. Since its 30 items and only 1 or 2 added per year that will do and jekyll produced the html so I can use that for the gallery page and just add the srcset. The plugin looks good. I do the same - I have a bash script that calls imagemagick and cwebp creating a full set of responsive images from all images in a folder. Generating the srcset entries should be easy too once I have settled on the breakpoint widths.
I am starting to think there is a balance to how much liquid is reasonable :slight_smile:

Thank you for all the input - I am learning.

1 Like

Okay good to hear.

If you programmatically always generate say 300px and 800px and 1000px images, you can avoid hard coding that as YAML.

Given image name “dog.jpeg”
And split by dot into “dog” and “.jpeg”
And config file with

sizes:
  - "300"
  - "800"
  - "1000"

Your img tag can use liquid to generate srcset like this.

<img src="{{ title }}.jpeg"
  srcset="
    {% for size in site.sizes %}
    /assets/img/resized/{{ title }}_{{ size }}.jpeg {{ size }}W,
    {% endfor %}
   "/>

You’ll need to use unless or if so you only insert the , where the for loop index is not the last. There’s an index variable built into for loops like forloop.index or similar.

Or you can iterate over your YAML images list. Then your YAML only needs to be:

- "dog.jpeg"
- "cat.jpeg"

Or even just “dog” to avoid having to use split.

You can use link Liquid tag against src value so Jekyll will validate that the path exists on disk. To avoid YAML and actual files going out of sync

You can avoid even putting your images in YAML at all, like this.

You could have an assets directory where you standard images are. These can be in version control.

/assets/img/full

And your unversioned resized images in

/assets/img/resize

Then with Jekyll you can iterate over all images in the “full” directory, No YAML data to lookup.

Something like this. To filter assets to images only and then to get the name or filename of each. Not sure I got the syntax right for each bit but this pattern will serve you

{% assign full_image_names = site.static_files 
     | where_expr: "item", "item.dir == "assets/img/full" 
     | map: "name" 
%}

Maybe you filter by "item.ext" == "jpeg" instead. Check the Jekyll docs. Static files have different attributes such as extension which site.pages items don’t have

1 Like