Responsive images and cropping

I’m following the responsive image cookbook Responsive images | Kirby CMS

I have the following code in the config.php file

<?php
return [
	'debug' => true,


	'thumbs' => [
		'srcsets' => [
			'heroimage' => [
				'900w'  => ['width' => 900, 'height' => 600, 'crop' => 'center', 'quality' => 80],
				'1650w'  => ['width' => 1650, 'height' => 1100, 'crop' => 'center', 'quality' => 80],
				'2400w'  => ['width' => 2400, 'height' => 1600, 'crop' => 'center', 'quality' => 80]
			]
			// more srcsets as needed
		]
	]
];

And then in my template:

<div class="hero-image">
	<?php if($image = $page->hero_image()->toFile()): ?>
		<img
			alt="<?= $image->alt() ?>"
			src="<?= $image->crop(2400, 1600)->url() ?>"
			srcset="<?= $image->srcset('heroimage') ?>"
			sizes="100vw"
			width="<?= $image->resize(2400)->width() ?>" // what does this do? //
			height="<?= $image->resize(2400)->height() ?>" // what does this do? //
		>
	<?php endif ?>
</div>

My question is, what do these two lines of code do?

width="<?= $image->resize(2400)->width() ?>" // what does this do? //
height="<?= $image->resize(2400)->height() ?>" // what does this do? //

I can delete them and everything still displays as it should. Also, I don’t want the image to be “resized” (and presumably maintain the aspect ratio of the original image) – I want the images to be “cropped”. So I’m hesitate about the word “resize” in these lines of code.

UPDATE
From another post:

I think it doesn’t really matter that much. The purpose of adding width and height is to prevent CLS by providing the correct aspect ratio: Optimize Cumulative Layout Shift | Articles | web.dev

I still don’t understand those two lines of code. The height is never going to be 2400px. Should I change this to?

width="<?= $image->resize(2400)->width() ?>"
height="<?= $image->resize(1600)->height() ?>"

or?

width="<?= $image->crop(2400)->width() ?>"
height="<?= $image->crop(1600)->height() ?>"

UPDATE 2

Hang on, am I correct in thinking those lines of code are not manipulating or changing the size of the images, but simply calculating and telling the browser the width of the image (when the image is 2400px wide??) and the height of the image when the image is 2400px wide? To prevent CLS by providing the correct aspect ratio? In which case I can use:

width="<?= $image->resize(2400)->width() ?>"
height="<?= $image->resize(2400)->height() ?>"

The ratio you create with this should be the same as your cropped image, it doesn’t make sense to crop the image 3:2, but give a width/height ration of 1:1.

Exactly.

I know this is dim, but I can’t read these lines of code:

width=<?= $image->resize(2400)->width() ?>
height=<?= $image->resize(1600)->height() ?>

Is the first line taking the image, resizing it to 2400px width, and then calculating the width (to provide this info to the browser)?

Is the second line taking the image, resizing it to 1600px high, and then calculating the height (to provide this info to the browser)?

But, both those dimensions will be exactly the same as the dimensions I’ve hardcoded? Could I simply write:

width=2400
height=1600

or, given this is just to inform the browser of the aspect ratio (to prevent Cumulative Layout Shift) we could even write:

width=3
height=2

I presume these two lines of code are more useful when the image is not being cropped, and I don’t know the height, or aspect ratio. And Kirby is calculating this for us? Like the following?

		<img
			alt="<?= $image->alt() ?>"
			src="<?= $image->resize(1600)->url() ?>"
			srcset="<?= $image->srcset('news-images') ?>"
			sizes="(min-width: 800px) 800px,
					100vw"
			width="<?= $image->resize(1600)->width() ?>"
			height="<?= $image->resize(1600)->height() ?>"
		>

So here the width of the image is being calculate, when the image is 1600px wide = 1600px. And the height is being calculated when the image is 1600px wide?

I’d suggest you look at the results of all that in your browser dev tools, then you will see if the results make sense or not.

Because this would not make any sense if your image is resized to 2400 in the src attribute, but you use the result of another image for the height. The same applies for crop, then your need to use the result of the cropped image, not a resized image.

When I’m resizing images, I know the width, but I don’t know the height, or the aspect ratio, so what would I put here?

width="<?= $image->resize(1600)->width() ?>"
height="<?= $image->resize(???)->height() ?>"

I’ve tried 100000 and in the browser dev tools, the image tag is saying
width=“1600” height=“1600”. Which is wrong because this particular image is 3:2 aspect ratio

Then I tried 10 and get:
width=“1600” height=“7”

I then tried putting the width 1600 (even though the image is not square) and get:
width=“1600” height=“1067”. This is correct.

So is this line of code taking the image->resizing it to the width (1600)->calculating the height based on this width and then injecting the answer into the image tag? So the resize number should be the width for both lines of code?

Using the width figure also works when cropping images:

<?php if($image = $page->hero_image()->toFile()): ?>
	<img
		alt="<?= $image->alt() ?>"
		src="<?= $image->crop(2400, 1600)->url() ?>"
		srcset="<?= $image->srcset('hero-image') ?>"
		sizes="100vw"
		width="<?= $image->resize(2400)->width() ?>"
		height="<?= $image->resize(2400)->height() ?>"
	>
<?php endif ?>

width=“2400” height=“1600”

Please do the following in a template of a page that has as least one image that is larger than the target size and not square in its original state, then you will see what happens:

<?php echo $page->images()->first()->crop(100, 100)->width(); ?><br>
<?php echo $page->images()->first()->crop(100, 100)->height(); ?><br>
<?php echo $page->images()->first()->resize(100)->width(); ?><br>
<?php echo $page->images()->first()->resize(100)->height(); ?></br>

Keep in mind that Kirby does not resize images that are smaller than the target size (unless you crop to another ratio).

You might want to reread the reference about resize vs. crop to understand the difference.

Tried that, but no images displayed in the browser. The template / page has images (using files fields), I don’t know if that makes any difference.

Also tried the following, but all four images display the same size and using the dev tools all four are the same file.

<?php echo $page->hero_image()->crop(100, 100)->width()->toFile(); ?><br>
<?php echo $page->hero_image()->crop(100, 100)->height()->toFile(); ?><br>
<?php echo $page->hero_image()->resize(100)->width()->toFile(); ?><br>
<?php echo $page->hero_image()->resize(100)->height()->toFile(); ?></br>

I don’t think I’ve explained this very well.

All I’m unsure about is what dimension to put in the height code, when I don’t know what the height of the images will be.

<?php if($image = $block->news_article_image()->toFile()): ?>
	<img
		alt="<?= $image->alt() ?>"
		src="<?= $image->resize(1600)->url() ?>"
		srcset="<?= $image->srcset('news-images') ?>"
		sizes="(min-width: 800px) 800px,
				100vw"
		width="<?= $image->resize(1600)->width() ?>"
		height="<?= $image->resize(xxx)->height() ?>"
	>
<?php endif ?>

Do I put the width dimension and from that Kirby works out the height, based on the aspect ratio of the image?

I’m assuming that the following two lines of code calculate the width and height of the image, in the img tag?

width=<?= $image->resize(1600)->width() ?>
height=<?= $image->resize(xxx)->height() ?>

having different ratios within the same srcset might yield to unexpected results as the browser might not pick the image purely on set viewport width. consider using a picture element if you need different ratios at certain breakpoints.

I don’t want different ratios. All I want to know is –

If images are being resized - in this case to a width of 1600px - and I don’t know the aspect ratio of the images the client will upload, what number do I put in the height code?

width=<?= $image->resize(1600)->width() ?>
height=<?= $image->resize(????)->height() ?>

Do I put in the width - 1600 - and Kirby will calculate the height from the aspect ratio of the image?

It seems that to calculate the height of the image, the width needs to be provided. So if an image is being resized, the resized width dimension needs to be given:

width=<?= $image->resize(2400)->width() ?>
height=<?= $image->resize(2400)->height() ?>

In effect the same number needs to be used on both lines of code. Then from this, Kirby will calculate the width and height of the image, adding the dimensions to the image tag. For example:

<img src="img_girl.jpg" alt="Girl in a jacket" width="2400" height="1200">

For cropped images, where we know the cropped dimensions, the width and height can presumably be hardcoded in:

<img
	alt="<?= $image->alt() ?>"
	src="<?= $image->crop(2400, 1600)->url() ?>"
	srcset="<?= $image->srcset() ?>"
	sizes="<?= $sizes ?>"
	width="2400"
	height="1600"
>
1 Like