Problem/Motivation
Many SVG files get exported without width and height attributes. This module will then apply a default value of 64 for both attributes.
As setting these attributes on the <img> tag gets more and more important these days, we should make another attempt to retrieve width and height through the viewBox attribute.
Proposed resolution
In svg_image_get_image_file_dimensions(), try to read width and height from the viewBox attribute if the first attempt is not successful.
| Comment | File | Size | Author |
|---|---|---|---|
| #9 | svg_image-viewbox-width-height-3227734-9.patch | 761 bytes | bronismateusz |
| #4 | interdiff_2-3.txt | 558 bytes | mrshowerman |
| #4 | svg_image-viewbox-width-height-3227734-3.patch | 1.07 KB | mrshowerman |
Issue fork svg_image-3227734
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
mrshowermanHere's a first patch.
Comment #3
mrshowermanComment #4
mrshowermanComment #5
qazema commentedWe applied the patch on a Drupal 9.4.5 installation and it works well.
Comment #7
FalkNisius commentedSorry, that I react late. Thanks for the work.
My team runs in the issue with missing width and height, and the approach should be changed.
The actual code prefers the width and height attribute from the svg-tag. Most exporters write 100% to that attributes, and it results to a width and height of 100 pixel, because the code strips the % sign.
The viewBox attribute is more usual and should be preferred if it exists.
The code depends on the letter case of the attributes, that is not always given, that viewBox is written as camel case.
The first two values of viewBox should not be ignored, they can have positive and negative values. The values in the viewBox can be float. We have to build a difference between the right and left corner values. At least the absolute values of the difference should be used.
Comment #8
bronismateusz commentedI tested patch #4 and it only works when the image style uses crop or scale and crop. Then the values for width and height are actually passed on correctly. If these filters are not applied, then these attributes are missing, for the img field.
In addition, I also see that the rotate or desaturate filter does not work either.
Comment #9
bronismateusz commentedI have prepared a patch that fixes the addition of width and height attributes for the other filters in the image style.
Comment #12
mrshowermanLeft a few notes on the MR.
Comment #13
jennypanighetti commentedMR#32 as a patch worked great for me!
Comment #14
firewaller commentedThe MR#32 changes work for us as well!
Comment #17
jennypanighetti commentedMR#32 fails to apply on the latest version drop, 3.2.3. Needs to be rebased.Nevermind, @krystianbrzoza already did this in https://git.drupalcode.org/project/svg_image/-/merge_requests/58 :)
Comment #18
anybodyThis is not major and it should have tests.
Comment #20
amangrover90 commentedI'm using
drupal/svg_imagein a Drupal distribution and hit the layout-shift problem this issue addresses. I applied MR 58's viewBox extraction patch and validated it works, but noticed a remaining gap: even with correct dimensions extracted, the front-end<img>on a rendered Drupal page still ships nowidth/heightattributes.The reason: the image field item's
width/heightproperties are populated by the image toolkit on save, which can't parse SVG — so$item->widthand$item->heightare always empty, and that's whatImageThemeHooks::preprocessImageFormatter()maps onto the rendered<img>. The dimensions fromsvg_image_get_image_file_dimensions()are consumed by the widget preview andrenderAsImg()'ssvg_attributes, but never reach the<img>attributes on a standard page render.To close that gap I added a
hook_preprocess_imageimplementation that setsattributes['width']/['height']directly for SVG files when they aren't already set. The core theme's own preprocess (which maps$variables['width']/['height']onto attributes) runs before module hooks, so setting$variables['width']in a module hook has no effect —attributesmust be set directly. The guard (!isset($variables['width']) && !isset($variables['attributes']['width'])) makes it a no-op for rasters and for SVGs that already have explicit dimensions from another path.I pushed this as a second commit on the MR 58 branch (
07e5d4e) so it can be reviewed alongside the viewBox extraction. Combined, the two commits:width/heightfromviewBoxwhen explicit attributes are absent (or reject percentage values instead of miscasting them as pixels) — the original MR 58 change.<img>viahook_preprocess_image— the new commit.I validated both cases end-to-end: a viewBox-only SVG (
viewBox="0 0 24 24") now renders<img width="24" height="24">on the media view page, and a percentage-width SVG does not miscast100%to100.Happy to split the second commit into a separate issue/MR if the maintainer prefers to land them independently.