Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Xlink:href svg disappear bug in IE11 and below #3195

Closed
tdekoning opened this issue Jun 30, 2016 · 11 comments
Closed

Xlink:href svg disappear bug in IE11 and below #3195

tdekoning opened this issue Jun 30, 2016 · 11 comments

Comments

@tdekoning
Copy link

tdekoning commented Jun 30, 2016

Vue.js version

1.0.26

Reproduction Link

http://vue-xlink-ie-bug.handcraft.com/index.html

Steps to reproduce

Load the page. As soon as vue is activated, the arrow-down svg icon inside the <button> disappears on IE11 and below.

What is Expected?

I expect the icon to remain. This behaviour is correct in browsers such as chrome, edge or firefox.

What is actually happening?

The icon is a xlink:href svg icon that vue is trying te re-render, which for some reason fails.

I know of an ugly workaround, which is:

<use xlink:href="#icon-angle-down" v-bind="{ 'xlink:href': '#icon-angle-down' }"></use>

However, this should not be required to render xlink:href svg's.

Source:

<html>
<head>
        <title>sdffsdfsd</title>
</head>
<body>
  <div id="site">
    <div @click="counter++">
      {{counter}}
    </div>
    <main>
      <button>
         hallo
         <svg><use xlink:href="#icon-angle-down"></use></svg>
      </button>
    </main>
  <div>

    <svg style="display: none;">
      <symbol viewBox="0 0 1792 1792" id="icon-angle-down"><title>angle-down</title><path d="M1395 736q0 13-10 23l-466 466q-10 10-23 10t-23-10L407 759q-10-10-10-23t10-23l50-50q10-10 23-10t23 10l393 393 393-393q10-10 23-10t23 10l50 50q10 10 10 23z"></path></symbol>
    </svg>
  </div>
</div>
<script src="http://cdn.jsdelivr.net/vue/1.0.26/vue.min.js"></script>
<script>
new window.Vue({
  el: '#site',
  data: function() {return {counter: 0};}
})
</script>
<style>
        button {
  position: relative;
  padding-right: 40px;
}
svg {
    height: 18px;
    width: 18px;
    fill: currentColor;
    position: absolute;
    right: 10px;
    top: 50%;
    -webkit-transform: translateY(-50%);
    -ms-transform: translateY(-50%);
    transform: translateY(-50%);
}
</style>
</body>
</html>
@yyx990803
Copy link
Member

Your repro doesn't show the source code.

@tdekoning
Copy link
Author

I've attached the source.

@fergaldoyle
Copy link
Contributor

<use> is very buggy in Internet Explorer. If vue is detaching elements and moving them around in the DOM, all <use> svgs that are children of the moved elements will be lost, see here for example:

http://codepen.io/anon/pen/NAgRVm?editors=1010
An element with an svg icon is simply moved to another, using appendChild. In IE the icon disappears where as in other browsers it remains. This is not something vue could do anything about I'd imagine.

One 'solution' for you it to use a string template or script tag template, but that will only solve your current issue. There's many times, e.g. list rendering, where vue will use appendChild meaning you will face the same issue.

Ideally you would have an <icon name="icon-angle-down"> component which injects the full svg code of a given icon instead of using <use>. This will work much better in IE.

@kazupon
Copy link
Member

kazupon commented Jul 14, 2016

Close (5 days inactivity)

@kazupon kazupon closed this as completed Jul 14, 2016
@letanure
Copy link

If you use symbols instead of groups, will work in IE11, with this polyfill svgxuse

@renatodeleao
Copy link

@fergaldoyle almost 2 years later, one of the greatest wtf IE moments of my dev path.

@spaceemotion
Copy link

We were able to fix this by using the v-pre tag, if it is of any help. Just use it on either the SVG or any of its parent elements.

@nino-vrijman
Copy link

Using href instead of xlink:href did the trick for me.

@JessicaSachs
Copy link

Neither of these worked for me. My icons still disappear. Everything I'm reading online says that if you have a symbol based SVG system, and are referencing nodes that exist on the page (not external), <use> should work fine in IE11. Yet, even with both :xlink:href and :href (I also tried v-pre and v-once) I'm not able to make it work. I'm going to make a demo with and without Vue and see if I can get a reproducible test case together to demonstrate the issue...

@JessicaSachs
Copy link

JessicaSachs commented May 17, 2019

After a riveting day of SVG fun, this isn't a Vue issue.

If you notice any weirdness with your icons, make a test html page and work with that. Embed the svg icon in HTML without Vue to make sure it works fine, then add your loaders and only do it with javascript to see how your loaders change the HTML markup. Only after this should you then finally add your InlineSVG.vue component (or equivalent)

TLDR: Ultimately, what I went with was updating my svgs not to have <use> elements. We simplified them so that they only have one compound path.

I learned about compound paths when giving up and trying to use a font icon building site. They wouldn't convert my icons unless they were in something called a "compound path". So I figured out what that was and figured out how to convert them to svgs that were defined in one path element.

This solution obviously doesn't work if you want to style individual bits of the SVG, but for an icon font, it worked pretty well.

What about styling individual parts of the SVG?
If you want to make some cool SVG, whose parts can be individually styled... then, inline the paths in its own MySpecialSvg.vue component, and make the component do the reusability via :style and :class on the individual paths.

My main caution is: stay away from <use>. If you have masks that depend on <use>, change the icon in Illustrator or sketch.

Tools/Solutions
Inline SVGs, after removing usages of or = vue-svg-loader
*Inline SVGs with <use> and sprite sheets = svg-sprite-loader + svgo-loader + svg4everybody

Other stuff
Honorable mention for if you're trying to get sprite sheets to work with href="sprite.svg#myCoolSprite" or xlink:href="sprites.svg#myCoolSprite" is to use a tool called svg4everybody to allow me to just use :href and :xlink:href. This works magically under the hood. (It uses XHR to request the sprite sheet externally and then creates a document context).

  • I couldn't figure out a way to get around the CORS restrictions of sprite sheets, so I couldn't do this. (We're a plugin on a partner's page, so we get blocked when cross origin requesting sprite sheets in prod 😅)

@spaceemotion
Copy link

+1 for svg4everybody, it's what enabled us the IE11 compat.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants