Responsive Images – $file->srcset()

To optimize loading times, I want Kirby to deliver different image sizes, depending on the user’s screen size. How do I achieve this? The reference suggests the following exemplary code for the template:

<img src="<?= $image->url() ?>" srcset="<?= $image->srcset([300, 800, 1024]) ?>" />

Furthermore, the reference suggests a definition:

$image->srcset([
  800  => '1x',
  1600 => '1.5x'
]);

I do not understand where to include this definition and what 1x or 1.5x means; how to make the preset work:

return [
  'thumbs' => [
    'srcsets' => [
      'default' => [
        '800w' => ['width' => 800, 'quality' => 80],
        '1024w' => ['width' => 1024, 'quality' => 80],
        '1440w' => ['width' => 1440, 'quality' => 80],
        '2048w' => ['width' => 2048, 'quality' => 80]
      ]
  ]
  ]
];

Is it possible to include a preset and simply call it in the template? Do thumbs generally mean images here oder especially thumbnails?

You can either create a preset in your config.php, or use the data array directly, like in your first examples.

To understand the srcset settings better, maybe check out this guide: Responsive images - Learn web development | MDN

1 Like

Well, I edited my config.php and added the srcsets hoping that thumbs means images:

<?php

return [
  'routes' => [
    [
      'pattern' => 'sitemap.xml',
      'action'  => function() {
        $pages = site()->pages()->index();
        $ignore = kirby()->option('sitemap.ignore', ['error', 'resume', 'works', 'shows', 'contact', 'privacy', 'legal-notes']);
        $resume = page('resume')->children()->pluck('id', ',');
		$ignore = array_merge($ignore, $resume);
		$shows = page('shows')->children()->pluck('id', ',');
		$ignore = array_merge($ignore, $shows);
        $content = snippet('sitemap', compact('pages', 'ignore'), true);
        return new Kirby\Cms\Response($content, 'application/xml');
      }
    ],
    [
      'pattern' => 'sitemap',
      'action'  => function() {
        return go('sitemap.xml', 302);
      }
    ],
    [
      'pattern' => '/',
      'action'  => function() {
        return page('shows')->children()->listed()->shuffle()->first();
      }
    ]
  ],
  'debug'  => true,
  'languages' => true,
  'thumbs' => [
    'srcsets' => [
      'default' => [
        '800w' => ['width' => 800, 'quality' => 80],
        '1024w' => ['width' => 1024, 'quality' => 80],
        '1440w' => ['width' => 1440, 'quality' => 80],
        '2048w' => ['width' => 2048, 'quality' => 80]
      ]
  ]
  ]
];

In my template, I replaced

<?= $painting->image()->resize(1920, 1920)->url() ?>

with

<?= $painting->image()->url() srcset="<?= $painting->srcset([300, 800, 1024]) ?>" ?>

Please see:

  <!-- Paintings -->
  <section>
    <h5><?= page('works')->blueprint()->section('paintings')->headline() ?></h5>
    <figure class="gallery">
      <?php foreach (page('works')->children()->filterBy('template', 'painting') as $painting): ?>
      <figure id="<?= preg_replace('/.*\//', '', $painting->url()) ?>" class="<?= $painting->size() ?>">
        <a href="<?= $painting->url() ?>" target="_self"><img src="<?= $painting->image()->url() srcset="<?= $painting->srcset([300, 800, 1024]) ?>" ?>"
            alt="<?= $painting->title() ?>"></a>
      </figure>
      <?php endforeach ?>
    </figure>
  </section>
  <?php endif ?>

Now, I get an error:

ParseError thrown with message “syntax error, unexpected identifier “srcset”, expecting “,” or “;””

What is wrong?

Theres a closing PHP tag and quote missing between the two attributes and you have to call srcset on the image, not the page:

<img src="<?= $painting->image()->url() ?>" srcset="<?= $painting->image()->srcset([300, 800, 1024]) ?>"
            alt="<?= $painting->title() ?>">

Additionally, before calling methods like url() or srcset() you have to make sure you actually have an object:

<?php if($image = $painting->image()): ?>
<img src="<?= $image->url() ?>" srcset="<?= $image->srcset([300, 800, 1024]) ?>"
            alt="<?= $painting->title() ?>">
<?php endif ?>

Also, if you pass attributes to srcset(), the default defined in your config will not be used.

2 Likes

Thanks @moonwalk! I missed the formatting errors. Now, it works smoothly:

  <!-- Paintings -->
  <section>
    <h5><?= page('works')->blueprint()->section('paintings')->headline() ?></h5>
    <figure class="gallery">
      <?php foreach (page('works')->children()->filterBy('template', 'painting') as $painting): ?>
      <figure id="<?= preg_replace('/.*\//', '', $painting->url()) ?>" class="<?= $painting->size() ?>">
        <a href="<?= $painting->url() ?>" target="_self"><img src="<?= $painting->image()->url() ?>" srcset="<?= $painting->image()->srcset() ?>" alt="<?= $painting->title() ?>"></a>
      </figure>
      <?php endforeach ?>
    </figure>
  </section>
  <?php endif ?>