Materialdesign: Single SVG using <symbol>

Created on 14 Jun 2019  ·  14Comments  ·  Source: Templarian/MaterialDesign

I somehow expected MaterialDesign-SVG to include a single SVG file containing all icons, but, via #3516, I found mdi.svg in MaterialDesign-Angular-Material instead. However, that file currently looks like this:

svg <svg> <defs> <svg id="{MDI name}" viewBox="0 0 24 24"><path d="{path data}"/></svg> ... </defs> </svg>

I expected something more akin to this:

svg <?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <defs> <symbol id="{MDI name}" viewBox="0 0 24 24"><path d="{path data}"/></symbol> <!-- or --> <symbol id="{MDI name}" width="24" height="24"><path d="{path data}"/></symbol> <!-- or even --> <symbol id="{MDI name}" width="24" height="24" viewBox="0 0 24 24"><path d="{path data}"/></symbol> ... </defs> </svg>

or, since the symbols are uniform, simply

svg <?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24" width="24" height="24"> <defs> <symbol id="{MDI name}"><path d="{path data}"/></symbol> ... </defs> </svg>

Could this be changed or should such a file be added separately?

Question

Most helpful comment

@Templarian An iconfont plugin that I use with Sketch (https://github.com/keremciu/sketch-iconfont) requires the SVG sprite to install the font. Could you please add it back?

Thanks

All 14 comments

Assuming you're using some kind of build tool that detects use tags and extracts just the icons you're using. If we put all 3.7k icons into a single file it would be rather large in size.

Is this to support a specific tool/framework?

By the way we highly recommend using @mdi/js for javascript developers as you get tree shaking for free.

I think it would be nice if we had a .mdi file that had an array of icon names that could be used with a Webpack plugin to generate an SVG with the symbols and place it at the start of the body tag in the index.html file.

.mdi

{
  "icons": [
    "account"
    ...
    "zodiac-scorpio"
  ]
}

index.html

...
<body>
  <!-- injected here via Webpack -->
  <svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" display="none" aria-hidden="true" width="0" height="0" hidden>
    <defs>
      <symbol id="mdi-sprite-account" viewBox="0 0 24 24">
        <path d="..."/>
      </symbol>
      <symbol id="mdi-zodiac-scorpio" viewBox="0 0 24 24">
        <path d="..."/>
      </symbol>
    </defs>
  </svg>
  ...
</body>

And then when using the SVG later in the page

...
<svg width="24" height="24"><use href="#mdi-sprite-account></use></svg>
...

This could be simplified by creating a component with Angular or React that generates the using SVG by just passing the icon property with the name of the icon like this:

<mdi-svg icon="account></mdi-svg>

If you're using a webpack plugin at that point you can just replace the <use href="#mdi-sprite-account></use> and assume a peerDependency of @mdi/svg and inject the icons into the <svg> tags. Pretty easy plugin to write.

My problem with this is one should use more framework friendly methods to consume the icons like @mdi/js. I agree if you're building a static website we could provide a quick webpack plugin.

The only problem with that is bloat. If I'm using account throughout my application, a single reference is more performant.

Does anyone know how use statements work with shadow dom? Are there any gotchas that come with this? Like I assume if it's in index.html it won't see it right?

From what I understand it wouldn't work. That is the only caveat to using the use statement. It would be a clone of a clone.

Lets go in with the assumption anyone using any of our tooling is working with Shadow Dom.

If one is using the @mdi/js package it reference in a way that doesn't duplicate. So keep that in mind.

Here is a StackBlitz example of an SVG inside of a cloned custom element. Unless I'm doing things wrong, it doesn't work. The SVG use statement creates a closed clone as opposed to an open clone. Idk if this can be changed.

Font Awesome offers such SVG “sprite sheets”, so some people apparently have a use for them.

@Crissov Unfortunately that approach encourages people to load all the icons. That would not be ideal as we reach 4k icons. I'm fine documenting an approach for this and generating an SVG file, but would not add it to the @mdi/ org namespace.

Webfont has the same issue and we are constantly trying discourage usage of it in the docs.

Well, mdi.svg does already exist for Angular. Itʼs certainly not something authors should expose to users in production, but a single file can be helpful in design and development.

PS: The original Google distribution also provides spritesheets for icon categories, using <symbol>.

@Templarian An iconfont plugin that I use with Sketch (https://github.com/keremciu/sketch-iconfont) requires the SVG sprite to install the font. Could you please add it back?

Thanks

@Templarian An iconfont plugin that I use with Sketch (https://github.com/keremciu/sketch-iconfont) requires the SVG sprite to install the font. Could you please add it back?

Thanks

I am the same as @112358z, I can upgrade to the latest version in Sketch since this plugin only supports the sprite.

@Crissov Unfortunately that approach encourages people to load all the icons. That would not be ideal as we reach 4k icons. I'm fine documenting an approach for this and generating an SVG file, but would not add it to the @mdi/ org namespace.

Webfont has the same issue and we are constantly trying discourage usage of it in the docs.

Could it be resolved by this https://github.com/JetBrains/svg-sprite-loader?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

buutqn picture buutqn  ·  3Comments

jonnyborg picture jonnyborg  ·  3Comments

puytr picture puytr  ·  3Comments

giooliveira picture giooliveira  ·  3Comments

xaviergonz picture xaviergonz  ·  3Comments