sveltejs/svelte

Add a :component selector for easier scoped styling.

Closed this issue · 1 comments

Describe the problem

Hey everyone,

Sometimes you need to modify the (S)CSS of an existing component without editing its source file. To do that, you typically use the :global selector, which allows you to apply styles to class names that are outside the scope of the current component or page.

However, I find that approach inconvenient. If you like keeping things clean and don’t want to use inline styles or, for example, need to use @media queries you’d have to wrap the component in a div and write something like:

<script>
  import MyComponent from "./Component.svelte"
</script>

<div class="sample">
  <MyComponent class="sample-component"/>
</div>

<style lang="scss">
  .sample {
    display: contents;

    :global(.sample-component) {
      /* styles */

      @media (max-width: 1000px) {
        /* styles */
      }
    }
  }
</style>

That ends up being unnecessary boilerplate code.

Describe the proposed solution

My suggestion is to add a :component selector, which would allow you to do the following:

<script>
  import MyComponent from "./Component.svelte"
</script>

<MyComponent />

<style lang="scss">
  :component(MyComponent) {
    /* styles */

    @media (max-width: 1000px) {
      /* styles */
    }
  }
</style>

Importance

would make my life easier

This has come up a number of times, recently in e.g. #16918. There's no good way to have a portion of a selector matching a component because there's no guaranteed root element for that component. Wrapping the component in another element that you can select for is the recommended approach.