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

SVG use element can't reference an element within the same shadow tree #772

Open
rniwa opened this issue Nov 14, 2018 · 11 comments
Open

SVG use element can't reference an element within the same shadow tree #772

rniwa opened this issue Nov 14, 2018 · 11 comments

Comments

@rniwa
Copy link
Collaborator

rniwa commented Nov 14, 2018

Because SVG's use element uses href to reference another element, its reference is always resolved against the base URI as an URL. Because there is no way to reference an element inside a shadow tree using an URL, use element can't reference an element inside a shadow tree.

This issue was split out of #179.

@rniwa rniwa changed the title SVG use element can SVG use element can't reference an element within the same shadow tree Nov 14, 2018
@rniwa
Copy link
Collaborator Author

rniwa commented Nov 14, 2018

The rough consensus at TPAC is that URLs in SVG href content attribute should use CSS's rules, where fragment-only URLs are specially treated as always-local, and thus act like fragment IDs and be scoped to the shadow tree.

@rniwa
Copy link
Collaborator Author

rniwa commented Nov 14, 2018

Also see w3c/csswg-drafts#2715

@rniwa
Copy link
Collaborator Author

rniwa commented Nov 14, 2018

Looks like the CSS Values and Units Module Level 4 doesn't quite specify what we want. Filed w3c/csswg-drafts#3320 to track that issue in the CSS WG.

@yGuy
Copy link

yGuy commented Jan 15, 2019

To make this more search engine friendly and clear for the reader:

  • SVG won't work inside the shadow DOM if they contain local "use" elements
  • Shadow DOM breaks SVGs with "use" elements
  • You can either use Shadow DOM or use non-trivial SVG files, but both will not work
  • it feels like there is a bug and SVGs don't work as everyone (except the spec leads) would expect it, but this is actually by spec-design

There is no efficient workaround or polyfill for this. The only options you are left with is to either ditch browser compatibility and hope that everybody uses a working version of Chrome or Firefox or shadow DOM, or SVG.

Personal recommendation: Don't use Shadow DOM until this is fixed in the spec and in all browsers. Don't hold your breath, though; the original issue was opened almost four years ago and affects users in the real world for more than a year, now. Not using SVG or not supporting all major browsers is not a good alternative.

@caridy
Copy link

caridy commented Feb 23, 2019

@yGuy my understanding of the rough consensus this is that your example (from another issue) will work fine:

<template>
    <p>You should see a black and a red circle.</p>
    <svg xmlns="http://www.w3.org/2000/svg" width="100px" height="100px" viewport="0 0 100 100">
        <defs>
           <circle id="myBlackCircle"      r="10" cx="10" cy="10" fill="black"></circle>
           <circle id="myRedCircle"         r="10" cx="14" cy="14" fill="red"></circle>
        </defs>
       <use href="#myBlackCircle"></use>
       <use xlink:href="#myRedCircle"></use>
    </svg>
</template>

It certainly works fine in Chrome and FF as far AFAIK. @rniwa we should add this topic to the agenda for the next F2F meeting to see if we can consolidate that consensus.

@aderaaij
Copy link

aderaaij commented Feb 25, 2019

@caridy This example will not work in Safari / iOS. Example: https://jsfiddle.net/wqfbkju7/

I'm not sure if that's a browser bug or if there's still lack of consensus on how to handle fragment identifiers in general.

@yGuy
Copy link

yGuy commented Feb 25, 2019

@aderaaij - It's the latter - everyone basically agrees that this should work, but no one seems to understand the importance this has for a potential success of webcomponents and they don't seem to be interested in actually fixing it: See #179 for the complete history of the issue - it all started 4 years ago....

@rniwa
Copy link
Collaborator Author

rniwa commented Feb 25, 2019

This should be working on iOS 12.2 and macOS 10.14.4 betas now. Given all major browser engines support this, the only remaining work is to update the spec accordingly.

@aderaaij
Copy link

@rniwa that is great news, thank you! I just found this WebKit bug report: https://bugs.webkit.org/show_bug.cgi?id=174977 so I'm guessing you're partially responsible for squashing this one. Thanks. On another note, do you have any idea if there is an actual consensus reached at W3C at this point, or did browser vendors just went ahead and implemented this one way or the other?

@rniwa
Copy link
Collaborator Author

rniwa commented Mar 10, 2019

@aderaaij : I think there was a rough consensus in the last TPAC about making SVG use element's reference work as well as other kinds of in-tree referencing in SVG work. So I've implemented that far but there doesn't seem to be much effort trying to update the standards so it's hard to tell to what extent we all agree.

@devingfx
Copy link

devingfx commented Apr 21, 2023

I can see that this question is not resolved for years...

To me, this whole decision to make shadow DOM too much cutted from outside world leads to more problems than solutions...

Why not just let it go? And make the shadow DOM features opt-in/out able ?

elem.attachShadow({
    events: 'traverse' | 'hybrid' | 'boundary'',
    baseURI: 'parent' | 'none' | 'https://...',
    css: 'traverse' | 'confine' | 'only shared' | 'only --var',
    mode: 'close' | 'open',
})
// actual elem.attachShadow would be something like 
elem.attachShadow({
    events: 'boundary'',
    baseURI: 'none',
    css: 'only --var',
    mode: 'open',
})
// and complete open DOM like if .append() would add clear DOM
const shadow = elem.attachShadow({
    events: 'traverse',
    baseURI: 'parent',
    css: 'traverse',
    mode: 'close',
})

// Defaults would be as it's defined right now for backward compatibility

Note the vocabulary here is not a spec ^^; but just to get the idea...

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

No branches or pull requests

6 participants