Simple SVG markup


#1

Simple SVG markup

The <svg> markup required to display an external source is too verbose.

<svg viewBox="0 0 512 512"><use xlink:href="path/to/image.svg#sprite"></use></svg>

It should be simple.

<svg src="image.svg#sprite"></svg>

Right now, developers must append a <use> element with an xlink:href attribute to an <svg> element to pull from an external source, be it a hash on the page or an external file.

<use xlink:href="path/to/image.svg">
<use xlink:href="path/to/image.svg#sprite">
<use xlink:href="#sprite">

I suggest the spec be updated so that developers may alternatively use a src attribute on the <svg> element to pull from an external source.

<svg src="path/to/image.svg"></svg>
<svg src="path/to/image.svg#sprite"></svg>
<svg src="#sprite"></svg>

Secondly, right now, developers must specify the viewBox attribute when pulling from an external source that already has it.

<svg viewBox="0 0 512 512"><use xlink:href="path/to/image.svg#sprite"></svg>

This requires developers know the viewBox value for each SVG and add it to every <svg> element on the page. Typically, this means the attribute is found in the external source and then duplicated several times across the page.

I suggest the spec be updated so that an <svg> element with a src attribute and no viewBox attribute inherit the viewBox value from its external source.

<svg src="path/to/image.svg#group"></svg>

#2

Can’t you use <img src="image.svg"> today? And <picture> is coming/already here which will provide an easy mechanism for non-svg fallbacks.


#3

Great question. Right now, we can’t link to an individual #sprite or style SVGs added with <img> (or <picture>).

I thought this was intentional and that <img> (and <picture>) are rastered-like, iframe-like ways of displaying images.

Do you think it should work differently? For instance, should we be able to <img src="path/to/image.svg#sprite"> and style it with fill: blue?


#4

It would be nice to have <img> work in this way, for sure, but developer convenience probably isn’t the most pressing thing preventing this.

Right now, we can’t link to an individual #sprite

My intuition would expect that linking to an individual #sprite should work. If you can link to a parent document, why not an element inside of it? Just like an iframe src can have an anchor url. Styling, however, is a different matter entirely.

I thought this was intentional and that <img> (and ) are rastered-like, iframe-like ways of displaying images.

I wouldn’t describe <img> or <picture> as limited to raster images.

I guess I’m surprised to learn that SVG <use> works with external files. I filed this ticket awhile back because SVG <image> wasn’t reliable cross browser and a WebKit dev closed it as intentional: https://bugs.webkit.org/show_bug.cgi?id=63548 Now I suspect that <use> only works with inline SVG.

Thanks for answering my questions! Yes, it sounds like an addition to the <svg> syntax would be a welcome one.


#5

Great ideas! How about a polyfil to demo how you want it to get done?


#6

Replacing xlink:href with a simpler non-namespaced attributes is a no brainer and IMHO clearly an improvement.

I wouldn’t add that to <svg> though. I would keep it on <use>. But in order to avoid having to have an <svg> wrapper, I’d love to see a solution that would enable most if not all SVG elements to appear without a root context, using some default, sensible viewport.


#7

See http://dahlström.net/svg/structure/svgstack-usage.html (shows that you can reference individual “sprites” from a single svg file). You can also use <iframe> and <object> for something where you can properly interact with the contents, see http://dahlström.net/svg/structure/svgstack-usage-iframe.html and http://dahlström.net/svg/structure/svgstack-usage-object.html.

For the second part, that you can’t style such images, it’s true that you can’t style the contents of an <img> that references an svg. This seems to be asking for <iframe seamless> or similar.

Update: The examples should work fine in IE11, Chrome 36, Firefox 32, Opera 12 (Presto) and Opera 23+. Support goes back further than that in some browsers.


#8

Firefox doesn’t seem to like your lovely internationalised domain for some reason. This works: http://www.dahlström.net/svg/structure/svgstack-usage.html


#9

Thanks, I updated the link.


#10

Having <svg> react similar to <script> is a somewhat interesting approach. I still wouldn’t follow that road:

  1. With xlink:href -> href the boilerplate code becomes much leaner.
  2. <img src=""> is already possible and serves a similar use case (apart from fine-tuning viewBox, …)
  3. There are other areas where SVG sprites are needed, like CSS. A solution needs to be cross-language usable, and the control of display should lie within the targeted SVG and be governed by the request URL.

The <svg src=""> syntax has no advantage then*, and is less powerful w/ regard to <picture>.

* in HTML context, that is. Modifying viewBox in HTML docs is less useful than inside SVG graphics, since many such “fill whole area” use cases can be met with width:100%; height:auto or similar.


#11

Yes! If nothing else, normalizing this property would be beneficial to developers.

Also, apart from honoring styles defined by the surrounding elements — e.g. the fill property. More on this, shortly.

With font glyphs, a vector sprite is often colored differently depending on its surrounding component, e.g. a dark background colors a light glyph, or a light background colors a dark glyph (using the color property), and all the colorized combinations in between. In these instances, the gylph’s styling is controlled by its surrounding elements rather than by the sprite itself. This is intuitive to me. It is also what the fill property does for us in CSS, currently. When we stick SVGs in an <img>, we lose the ability to use the fill property.

Similar to my earlier question; do you find the above usage of fill to be intuitive? If you do, would you expect <img> to respond to it as well?


#12

On a SVG Open 2010 panel discussion Doug Schepers (et al.) mentioned the WG’s idea of parametrized SVG: Basically, the SVG image can, without scripting, access info from the URL (query params, iirc) and modify its appearance. Especially targeted at colors, that method could provide a middle ground. I have no idea, however, what’s the status of that proposal.


#13

I wonder if the “inside” of a <img src="thing.svg"> could be reified as a shadow DOM of some sort? That seems very ambitious, but has a certain appeal. Implementer comments welcome.

Failing that, perhaps a ::shadow- or /deep/-esque pseudo-element or combinator could be introduced, purely at the CSS level, to allow such styling to cascade when explicitly desired to do so?


#14

You’re trying to invent a hack (with a number or exceptions for a typical behaviour) instead of insisting on implementation of SVG stacks mentioned by Eric.

You can always style your icon using external styles:

<?xml-stylesheet type="text/css" href="style.css"?>
<svg xmlns="http://www.w3.org/2000/svg">
    <circle cx="40" cy="40" r="24"/>
</svg>

#15

Frankly, I don’t see how treating SVG in an img as anything other than a shadow DOM makes any sense :slight_smile:


#16

I dislike that idea, because that is already implemented and working using the img tag. (As described and illustrated above.)

If you really need to access the source of an SVG inside a website, you may still include it with a few characters more. Which didn’t even means more typing, as most people either use some sort of shortcut to generate markup (e.g. Emmet) or let it generate via some specialized software (e.g. Inkscape)

On the other hand I never saw a useful real-world example of editing SVG in the browser (by the means of CSS or JS) while simultaneously having the requirement to not have the SVG markup inside the main document. In most cases you will select a specific shape/layer via its ID or change the overall appearance of the whole graphic (for example rotating or color-shifting an icon).

SVG was already trimmed down to be used in HTML and you probably


#17

I never saw a useful real-world example of editing SVG in the browser (by the means of CSS or JS) while simultaneously having the requirement to not have the SVG markup inside the main document

Real world: medium-sized website with a single SVG sprite for icons. That sprite is more than 100kb (we might brink it down to roughly 70kb with systematic use of SVGO). We could inline that sprite after the <body> in every single page, losing the (arguably conditional) benefits of the browser cache.

Following your argument, why keep CSS and JS outside of the HTML document? We can always inline it and send users 1-2 MB documents for each page. Why keep raster images separated from the document? Base64 all the things. And so on and so forth. :wink:

For the record, we’re using a SVG sprite with <svg><use xlink:href="sprite.svg#symbol-id"></use></svg>, and a tiny JS polyfill for IE/Edge support. We’re able to style the main color, achieving feature-parity (on the HTML side) with icon fonts.


#18

There’s a solution for your second problem, if it helps.

Secondly, right now, developers must specify the viewBox attribute when pulling from an external source that already has it.

If the referenced source is declared inside of a <symbol> element, the viewBox on the <symbol> is preserved and doesn’t need to be redeclared. More info in this CSS-Tricks article.


#19

For the record, I support the suggestion of a shorter syntax for <svg><use xlink:href="…"></use></svg> that would do exactly the same thing but with markup that is less arcane for authors.

And I do mean having the exact same thing. Suggestions to use <img> instead don’t take into account that we are using <svg><use xlink:href="…"></use></svg> instead of <img src="…"> because it brings a different feature set.

Would be an improvement:

<svg><use href="…"></use></svg>

Would be really cool:

<svg use="…"></svg>