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

Teleport + CSS v-bind does not work with shadow target #12287

Open
Mefinst opened this issue Oct 28, 2024 · 2 comments · May be fixed by #12299
Open

Teleport + CSS v-bind does not work with shadow target #12287

Mefinst opened this issue Oct 28, 2024 · 2 comments · May be fixed by #12299

Comments

@Mefinst
Copy link

Mefinst commented Oct 28, 2024

Vue version

3.4.15, 3.5.12

Link to minimal reproduction

https://stackblitz.com/edit/vitejs-vite-qg9sjb?file=src%2Fcomponents%2FHelloWorld.vue

Steps to reproduce

  1. Mount vue app inside shadow root (manually or using custom elements feature of vue).
  2. Setup element with a class and put it to teleport (teleport target should be outside current component tree, but inside shadow tree)
  3. Set some css properties of the class to v-bind values in SFC of component containing teleport

In the linked example I set an element with class v-bind-fail to have red background using v-bind. But it is white.

What is expected?

v-bind styles are applied to teleported dom element.

What is actually happening?

v-bind styles are not applied to teleported dom element.

System Info

No response

Any additional comments?

v-bind is implemented using var(--some-hash) custom properties. Values for those provided by inline style attributes. When some part of a component is inside teleport tag those style attributes duplicated there. At least normally so. When teleport target is inside shadow dom styles aren't duplicated.

From my perspective v-bind implementation expects teleport to be used with selectors only, but it can be used with HTMLElement variable which can point to shadow tree element. It seems v-bind implementation uses something similar to document.querySelector to apply variables to teleported parts of the tree. And it fails to locate elements in the shadow tree.

@edison1105 edison1105 changed the title Teleport + CSS v-bind does not work Teleport + CSS v-bind does not work with with shadow target Oct 29, 2024
@edison1105 edison1105 changed the title Teleport + CSS v-bind does not work with with shadow target Teleport + CSS v-bind does not work with shadow target Oct 29, 2024
@KamilOcean
Copy link

Hi, @Mefinst !

May be I get something wrong, but I think the problem is that you are trying to apply CSS classes outside of incapsulated shadowDOM to that shadowDOM element. But as I know it doesn't work by the nature of native elements' incapsulation concept.

There are special techniques for this case. I've changed a little bit your example in order to make it work. I've used ::part(inside-teleport):

template:

  <teleport :to="teleTarget">
    <div part="inside-teleport" class="v-bind-fail">Failure</div>
  </teleport>

<style>

<style>
div::part(inside-teleport) {
  color: red;
  background-color: yellow;
}
</style>

Also, please, make sure your style tag doesn't have a scoped attribute. In this case class names will be transformed

1730326173058

The full example (a fork from your example) here: https://stackblitz.com/edit/vitejs-vite-xjxwcw?file=src%2Fcomponents%2FHelloWorld.vue

Also, there are other techniques how you can apply global styles to shadowed component: https://jordanbrennan.hashnode.dev/8-ways-to-style-the-shadow-dom

I hope it will help you. If yes, it's not Vue-related issue.

Thanks a lot.

@Mefinst
Copy link
Author

Mefinst commented Oct 31, 2024

Excuse me, I made a little mistake in the example. We bundle our app as a single JS file for microfrontends which applies all styles as adoptedStylesheets to the shadow root.

There is updated example, where I copy all styles from style tags and link[rel="stylesheet"] tags into the shadow tree as we do during development:
https://stackblitz.com/edit/vitejs-vite-tktaso?file=src%2Fmain.js

You can see that color: green is applied, but v-bind(background) is not.

image

Also there is our rendered Popover component outside shadow tree. You can see that there is a style attribute on both .Popover and .Popover__content elements equal to --479fb184: 328px; --b365c6da: 425.25px; --2352ac89: 569px;.

image

The same Popover inside shadow dom. .Popover has style attribute, but .Popover__content does not.

image

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

Successfully merging a pull request may close this issue.

3 participants