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

Scoped style behavior with teleport & fragment #2669

Open
07akioni opened this issue Nov 25, 2020 · 8 comments
Open

Scoped style behavior with teleport & fragment #2669

07akioni opened this issue Nov 25, 2020 · 8 comments

Comments

@07akioni
Copy link
Contributor

Version

3.0.2

Reproduction link

https://codesandbox.io/s/aged-butterfly-4ryvl?file=/src/components/CompB.vue

Steps to reproduce

follow the link

What is expected?

as my expected, at least the binded element should have proper data-xxx attr to make scoped style works well

What is actually happening?

not applied in any circumstance

@posva
Copy link
Member

posva commented Nov 25, 2020

Note $attrs doesn't contain the data-v-.... It would be inconvenient:

Parent component:

<template>
  <input >
  <CustomInput />
</template>

<style scoped>
input {
 color: red;
}

CustomInput.vue:

<template>
  <div>
    <label>...</label>
    <input v-bind="$attrs">
  <div>
</template>

The custom input will accidentally inherit the color: red.

We could however maybe apply the data-v to all root elements in a fragment

@07akioni
Copy link
Contributor Author

07akioni commented Nov 26, 2020

Not only fragment-rooted component has no data-v, but also teleport-rooted component doesn't.

https://codesandbox.io/s/laughing-gagarin-4mlln?file=/src/components/CompB.vue

Since Teleport & Fragment can be nested for many levels. I think there should be a traversal to make sure the real outer-most html element is applied with data-v.

Nor we may need a mechanism to let user specify which part should be applied with scoped style from parent.


For example I have a component wrapped with HOC. Hoc1 and Hoc2 may be composed with Fragment & Teleport.

<!-- Comp.vue -->
<hoc-1>
  <hoc-2>
    <div class="x" />
  </hoc-2>
<hoc-1>

Suppose it will be rendered as just a <div class="x" />. It's expected that the outer scoped style is applied to the component.

@LinusBorg
Copy link
Member

I'm torn about what to do here.

In Vue 2, all components had root nodes, and we always applied the data-v property to child components' root element.

That actually was a caveat, as styles from the parent could accidentally bleed into the child if the child root contained a class of the same name (unintentionally), but at the same time, it gave authors an escape hatch to style the root of a child.

The behavior in Vue 3 now, is emulating what happened in Vue 2 for root nodes while skipping the behavior for fragments, which is in line with attribute inheritance in general, were we skip inheritance for fragments. As we have now reached a stable 3.0 release for a while, that can't be reversed without a breaking change, technically.

Could we find workarounds with :slotted() or :-deep() pseudoselectors?

@HcySunYang HcySunYang changed the title Scoped style not applied to fragment-rooted component (even it has binded $attrs) Scoped style behavior with teleport & fragment Mar 31, 2021
@tuan-lm97
Copy link

This still not have been fixed yet ?
Just run into this problem today. Spent a good 30m to understand why.
I think the very least thing we can do is issue this problem in the doc about fragment. Because it is expected that everything have bound to an element, it should behave like the root of the child component

@danielroe
Copy link
Member

I would add that Vue does seem to add the data attribute to fragments on SSR, but not on client-side, as can be seen in this CodeSandbox - see linked issue.

@tangjinzhou
Copy link
Contributor

maybe we can use getCurrentInstance().vnode.scopeId ?

@madebyfabian
Copy link

Is this still relevant?

@CernyMatej
Copy link

@yyx990803 Sorry for the ping but would it be okay to use the internal API for this use case?
getCurrentInstance()?.vnode.scopeId

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

8 participants