Hugo: imageConfig with SVG images

Created on 14 Jul 2017  Â·  20Comments  Â·  Source: gohugoio/hugo

Hi.

I'd like to ask if it's possible to add support for SVG images in imageConfig. I know SVG are vectors but there are cases SVGs still use width and height along with viewBox. Not sure if Go allows this or not, just thinking out loud.

Thanks!

Enhancement Stale

Most helpful comment

I'm curious as to the use case where these values would be returned.

height and width attributes in img tags so the browser doesn't have to start downloading the images to know how space they'll take up. It's a page-layout-speed optimization.

All 20 comments

Do you have any references saying that this is relevant for SVG?

What do you mean by "relevant"? Width and height apply to SVG too.

Maybe this helps? https://css-tricks.com/scale-svg/#article-header-id-2

FWIW, you can do this in a pretty clever way using dict. I learned this from @budparr. You could also use a shortcode for content since you're not technically resizing the svg the way you are with png/jpg/etc. _Optimizing_ svgs is another story. But here's an example of what I mean:

https://github.com/gohugoio/gohugoioTheme/blob/master/layouts/partials/home-page-sections/installation.html#L26

That is for inlined SVG :) I'm talking about using SVG with an img tag.

That is for inlined SVG

Right. 1 less HTTP request. Even better.

Here's not the place or the time to discuss the pros and cons of inlining stuff. Hint: http/2.

What do you mean by "relevant"? Width and height apply to SVG too.

I mean:

  • For a JPG image Width and Height in imageConfig returns the actual pixel count.
  • The above has nothing to do with scaling.
  • In my head, an SVG image does not have any of those properties until it gets rasterized.

So by relevant I mean this: Am I right or wrong in the last bullet point above?

  • In my head, an SVG image does not have [width or height] until it gets rasterized.

SVG elements can and do declare intrinsic widths and heights. I make images like this in a text editor.

Here's not the place or the time to discuss the pros and cons of inlining stuff. Hint: http/2.

I think with your "hint," you just did.

Please stop polluting the issue with useless comments.

@XhmikosR I'm curious as to the use case where these values would be returned. Icon list? Image library?

I'm curious as to the use case where these values would be returned.

height and width attributes in img tags so the browser doesn't have to start downloading the images to know how space they'll take up. It's a page-layout-speed optimization.

Yup, exactly this. Since HTML is the first thing being parsed, if each
image has width and height attributes you avoid useless reflows.

My use case is a gallery with variable dimensions so I definitely need this
feature. Currently I have to specify the dimensions in a data file which
isn't as automatic as it could be.

On Jul 15, 2017 19:13, "adiabatic" notifications@github.com wrote:

I'm curious as to the use case where these values would be returned.

height and width attributes in image tags so the browser doesn't have to
start downloading the images to know how space they'll take up. It's a
page-layout-speed optimization.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/gohugoio/hugo/issues/3700#issuecomment-315544542, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAVVtTjFdNZ4WhChv7GtE8ez1nYpYZOnks5sOOU4gaJpZM4OYS7W
.

Ah, I see. Thanks you to you both. I knew about other formats being affected (i.e., jpg and png), but I had no idea this affected SVG since it's just XML at the end of the day. Seems I am always learning something new about SVGs :smile: I had red the Bellamy-Royds article above and have always followed its advice to avoid these attributes altogether.

So, any news about this, guys?

This issue has been automatically marked as stale because it has not had recent activity. The resources of the Hugo team are limited, and so we are asking for your help.
If this is a bug and you can still reproduce this error on the master branch, please reply with all of the information you have about it in order to keep the issue open.
If this is a feature request, and you feel that it is still relevant and valuable, please tell us why.
This issue will automatically be closed in the near future if no further activity occurs. Thank you for all your contributions.

I'd still like to see this added, if it's not a lot of work.

height and width attributes in img tags so the browser doesn't have to start downloading the images to know how space they'll take up. It's a page-layout-speed optimization.

This became even more relevant with the recent introduction of browser support for the HTML-native lazy loading attribute I think.

When we use Markdown Render Hooks to add the loading="lazy" attribute together with width and height attributes auto-calculated by imageConfig as described in this fine blog post (to allow the browser to calculate proper page layout _before_ loading the images, thus avoiding page repaints), we then cannot include SVG images using Markdown anymore. If we try it anyway, Hugo throws an error like the following (imageConfig: image: unknown format):

execute of template failed: template: _default/_markup/render-image.html:4:146: executing "_default/_markup/render-image.html" at <imageConfig (add "static/" .Destination)>: error calling imageConfig: image: unknown format

Since Go template code is always entirely evaluated regardless of conditional statements, I don't know of any easy workaround to still support SVG images.

I think SVG is the _only_ image format supported by the HTML <img> tag that lacks imageConfig support.

I also wouldn't mind seeing this for the exact reasons mentioned, lazyloading SVG and minimizing reflow. Is there some other function like readFile that could be used to parse an SVG for its width and height attributes?

@jcackowski
I use lazyload for all images. I wanted to prevent layout reflow so I needed image ratio.
As a workaround to read image size and ratio of any kind of image, I created a partial image-size.html:

{{ $width := 1 }}
{{ $height := 1 }}
{{ if strings.HasSuffix . ".svg"}}
    {{ $svgContent := (resources.Get .).Content }}
    {{ $viewBoxSizes := split (index (split (index (split $svgContent `viewBox=`) 1) `"`) 1) ` ` }}
    {{ $width = float (index $viewBoxSizes 2) }}
    {{ $height = float (index $viewBoxSizes 3) }}
{{ else }}
    {{ $image := (resources.Get .) }}
    {{ $width = float $image.Width }}
    {{ $height = float $image.Height }}
{{ end }}

{{ return (dict "width" $width "height" $height "hRatio" (div $height $width) "wRatio" (div $width $height)) }}

Then I created another partial as responsive-image.html:

{{ $image := resources.Get .image }}
{{ $size := partial "image-size.html" .image}}
{{ $style := print "padding-top: " (mul $size.hRatio 100) "%;"}}
<div class="aspect-ratio-box" style="{{$style | safeCSS}}">
    <img class="aspect-ratio-box-inside lazyload" data-src="{{ ($image | fingerprint).RelPermalink }}" alt="{{ .alt }}">
</div>

I can use it in a shortcode like this:

{{ partial "responsive-image.html" (dict "image" (.Get "image") "alt" (.Get "imageAlt") )}}

Please note that this relies on images stored in the assets folder. Plus it only uses the viewBox of the SVG, not the actual width and height.
You can tweak it to support more cases. For me, it was enough. I hope it helps.
(For CSS see CSS-TRICKS and for JS see npm lazyload)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nikolas picture nikolas  Â·  3Comments

geddski picture geddski  Â·  3Comments

MunifTanjim picture MunifTanjim  Â·  3Comments

chrissparksnj picture chrissparksnj  Â·  3Comments

vielmetti picture vielmetti  Â·  3Comments