SVG without width and height

I have an SVG which has a viewBox but doesn’t specify width and height or if it does, they are set to 100% because we want it to be scalable. Now if I render this SVG on the canvas inside a Picture it renders in a weird way.

In this gif:

  • The top one is an SVG which has a width and height specified
  • The bottom one does NOT have width and height

gojs_svg_icon

Here’s my template:

const nodeTemplate = new go.Node(go.Panel.Vertical, {
  background: 'whitesmoke',
})
  .add(
    new go.Picture({
      source: 'icon_dim.svg',
      desiredSize: new go.Size(24, 24),
      width: 24,
      height: 24,
    })
  )
  .add(
    new go.Picture({
      source: 'icon_no_dim.svg',
      desiredSize: new go.Size(24, 24),
      width: 24,
      height: 24,
    })
  );

And here are my SVGs:

<!-- WITH W and H -->
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#1867cd" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" >
  <path stroke="none" d="M0 0h24v24H0z" fill="none" />
  <path d="M12.5 21h-7.5a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v7.5" />
  <path d="M3 10h18" />
  <path d="M10 3v18" />
  <path d="M16 19h6" />
  <path d="M19 16v6" />
</svg>

<!-- WITHOUT W and H -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#1867cd" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z" fill="none" />
  <path d="M12.5 21h-7.5a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v7.5" />
  <path d="M3 10h18" />
  <path d="M10 3v18" />
  <path d="M16 19h6" />
  <path d="M19 16v6" />
</svg>

<!-- WITH W and H SET TO 100% -->
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 24 24" fill="none" stroke="#1867cd" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path stroke="none" d="M0 0h24v24H0z" fill="none" />
  <path d="M12.5 21h-7.5a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v7.5" />
  <path d="M3 10h18" />
  <path d="M10 3v18" />
  <path d="M16 19h6" />
  <path d="M19 16v6" />
</svg>

Is there any way I can make the SVG fill its Picture container without having to specify the width and height? We need this because these SVGs are used elsewhere in the app and we don’t wanna hardcode the dimensions.

Here’s the full code on StackBlitz.

Did you notice the differences between Firefox and Chrome? I haven’t tried other browsers.

Sorry, but the SVG really needs to specify a width and a height if you want it to work everywhere. You can alter or constrain the width or height of the Picture.

Firefox doesn’t even render anything but why doesn’t 100% work?

Well, to me “100%” isn’t reliable because what would it be measured relative to? The parent element isn’t clearly defined.

Are you saying if I have a panel with fixed dimensions as parent of this picture, then we should expect 100% to work? I’m assuming that would clearly define the parent then.

The HTMLImageElement used to load and render the SVG file isn’t in the DOM – it has no parent node.

HTMLImageElement can easily set the width and height of its SVG src even if the SVG doesn’t have them:

<img 
  src="an_svg_without_width_height.svg" 
  style="width: 24px; height: 24px" 
/>

I don’t know how you render svg on the canvas and the code is not open that I can read, but I’m thinking you can pass the width and height specified in the Picture to the HTMLImageElement as inline style?

I don’t know just throwing an idea.

You can do that – it’s the Picture.element.

But using a percentage unit doesn’t help there.

That didn’t work either and rendered the SVG much bigger. I have a workaround for my own use case so this thread can be concluded.