How to get the width and height of a SVG image?
Google Lighthouse complains:
Image elements do not have explicit width and height
Set an explicit width and height on image elements to reduce layout shifts and improve CLS. Learn more
https://web.dev/optimize-cls/?utm_source=lighthouse&utm_medium=devtools#images-without-dimensions
How do I set (or get) width and height for my svg images?
Here is the code that I use:
{{ image }}
<img src="{{ url }}" width="" height="" class="mx-auto lazyload">
{{ /image }}
I know there is a special tag for svg's to inline them, but this is not what I need, and even counterproductive because of the complexity of the SVG image.
And I can not set the height and width to just some values, because then the reserved space has not the correct aspect ratio or size.
All my SVG's have a viewBox attribute, so it should be easy to get the required dimensions from this attribute.
Is there a way to do this with Statamic?
I think the dimensions and/or the aspect ratio should be saved in the meta information of the SVG asset when you upload it, so it can be used with an image tag.
Upload a SVG to your assets folder and output it in a template
Video of the problem
https://www.youtube.com/embed/VDhIxPUoQ8Y
Statamic 3.0.28 Pro
Laravel 8.15.0
PHP 7.4.12
cnj/seotamic 2.0.2
octoper/statamic-inline-assets 4.0.2
rias/statamic-markdown-highlight 1.0.4
spatie/statamic-responsive-images 1.4.0
statamic/ssg 0.2.0
Push!?
Pull!?
Until we're able to implement something, you could consider writing a tag that would read the viewBox from the svg.
I've built out a tag that should help you work around the issue until it's properly supported in Statamic.
Create App\Tags\SvgViewbox.php, with the following contents:
<?php
namespace App\Tags;
use Statamic\Tags\Tags;
class SvgViewbox extends Tags
{
protected $regexPattern = "#viewbox=[\"']\d* \d* (\d*+(\.?+\d*)) (\d*+(\.?+\d*))#i";
// {{ svg_viewbox:width :url="image_url" }}
public function width()
{
$url = $this->params->get('url');
if (! str_contains($url, 'http')) {
$url = config('app.url') . '/' . $url;
}
$svg = file_get_contents($url);
preg_match($this->regexPattern, $svg, $viewBox);
return (float) $viewBox[1];
}
// {{ svg_viewbox:height :url="image_url" }}
public function height()
{
$url = $this->params->get('url');
if (! str_contains($url, 'http')) {
$url = config('app.url') . '/' . $url;
}
$svg = file_get_contents($url);
preg_match($this->regexPattern, $svg, $viewBox);
return (float) $viewBox[3];
}
}
Then in your Antlers templates, you can reference it like this:
width {{ svg_viewbox:width url="/assets/site/scratches.svg" }}
height {{ svg_viewbox:height url="/assets/site/scratches.svg" }}
Just pass in the asset's URL as the url parameter. Hopefully it should work for you.
Thank you @damcclean. It works now. It would be great if this was a core feature, without requiring a special tag. Cheers
This is now available in 3.1 beta.
Most helpful comment
I've built out a tag that should help you work around the issue until it's properly supported in Statamic.
Create
App\Tags\SvgViewbox.php, with the following contents:Then in your Antlers templates, you can reference it like this:
Just pass in the asset's URL as the
urlparameter. Hopefully it should work for you.