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

Child elements automatically receive scoping class #5112

Closed
1 task done
pdrbrnd opened this issue Oct 18, 2022 · 3 comments · Fixed by withastro/docs#2115
Closed
1 task done

Child elements automatically receive scoping class #5112

pdrbrnd opened this issue Oct 18, 2022 · 3 comments · Fixed by withastro/docs#2115
Assignees
Labels
- P3: minor bug An edge case that only affects very specific usage (priority)

Comments

@pdrbrnd
Copy link

pdrbrnd commented Oct 18, 2022

What version of astro are you using?

1.4.7

Are you using an SSR adapter? If so, which one?

None

What package manager are you using?

npm

What operating system are you using?

Mac

Describe the Bug

Astro automatically adds a "scoping" class to all child elements whenever a parent contains a <style> tag.
This is probably intended to open up the possibility to style children without using global styles but it potentially breaks scoping.

As an example:

// Button.astro
// Button defined with 10px padding
---
const { class: className, ...attributes } = Astro.props
---

<button class:list={['host', className]} {...attributes}>
  <slot />
</button>

<style>
  .host {
    padding: 10px;
  }
</style>
// SomeComponent.astro
// Button will inherit parent's 50px padding because it's using the same class name
---
import Button from './Button.astro'
---

<div class="host">
  <Button>Hello world</Button>
</div>

<style>
  .host {
    padding: 50px;
  }
</style>

in SomeComponent, astro will automatically add the scoping class astro-XYZ to Button and, as Button is ready to receive and consume external classes, it will inherit the parent's 50px padding.
.host:where(.astro-4SVNLVZL) is true because we used the same class name on both components, which defeats a bit the purpose of having scoped styles.

I have prepared a quick stackblitz repro to better understand what's going on.

I did not find anything in the documentation about this so I'm not sure if this is intended but, IMO, automatically pass the scoping class as a prop seems buggy behavior. I am happy to help and open up a Pull Request if needed.

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-twgta2?file=src/pages/index.astro

Participation

  • I am willing to submit a pull request for this issue.
@matthewp matthewp added the - P3: minor bug An edge case that only affects very specific usage (priority) label Nov 4, 2022
@natemoo-re
Copy link
Member

This is probably intended to open up the possibility to style children without using global styles but it potentially breaks scoping.

Yes, this was the intention behind the feature. If you opt-in to passing down the class attribute, it allows you to pierce the scoping boundary and style children from the parent.

It's a bit unintuitive, but it can be useful in certain situations.

@bluwy
Copy link
Member

bluwy commented Nov 10, 2022

I'm not sure how this can be fixed in a non-breaking way, but fwiw in Svelte scope classes are only added for HTML elements, not components, which I find it nice too, but there are indeed arguments otherwise (sveltejs/svelte#4843).

I also can't think of a middle-ground for this, but open to any ideas. Otherwise we can resort to documenting this edge-case.

@dev-nicolaos
Copy link

dev-nicolaos commented Nov 25, 2022

I also can't think of a middle-ground for this, but open to any ideas. Otherwise we can resort to documenting this edge-case.

If this behavior is intentional it should be documented. Spreading rest props on an element is a pretty common practice in component development and authors may unintentionally affect the scoping of styles by doing so because of this.

---
const { someProp, ...rest } = Astro.props;
// ...
---

<!-- ... -->

<a {...rest}>Hello World</a>

I don't know about all UI libraries, but I know this is different than how React works, so at least some author's won't expect it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
- P3: minor bug An edge case that only affects very specific usage (priority)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants