soxhub/ember-scoped-css

Add <style> tag support *within* each <template>

Opened this issue · 7 comments

Update 3:

  • no scoped (this is default, so to specify is redundant)
  • :deep() for punching under the component boundary (such as when styling an external library)
  • global CSS would not be in components, ideally, but could be left "as is" via global attribute.
const Other = <template>
  <style>
    .button {
      color: red;
    }
  </style>
  <button class='button'>non export</button>
</template>;

<template>
  <style>
    .button {
      color: green;
    }
  </style>
  <Other/>

  <button class='button'>Default export</button>
</template>

Update 2: I don't think it's a good idea to support <style> as a vanilla tag in gjs/gts -- we don't have the bandwidth to implement support for that across the 10+ syntax parsers that the community needs to support.

Example for Update 2

Example, each component's style has its own scope.

const Other = <template>
  <style scoped>
    .button {
      color: red;
    }
  </style>
  <button class='button'>non export</button>
</template>;

<template>
  <style scoped>
    .button {
      color: green;
    }
  </style>
  <Other />
  <button class='button'>Default export</button>
</template>

Update: per discussion below, in-<template> styles now have the scoped attribute.
We'd want to include a lint for folks to enable.

  • forbid-global-style-tag or something like that -- that way folks can still do global styles in a component if they really want to

Removed after update 2 (see above)

Additionally, related to #34
these features should be able to work together:

<style>
  .button {
    color: red;
  }
</style>

const Other = <template>
  <style scoped>
    .button {
      color: blue;
    }
  </style>
  <button class='button'>non export</button>
</template>;

const Another = <template>
  <style scoped>
    .button {
      color: green;
    }
  <button class='button'>non export</button>
</template>;

<template>
  <Other />
  <Another />
  <button class='button'>Default export</button>
</template>

Here, precedence should be that:

  • Other is blue
  • Another is green
  • The button in the default export is red

If we support <style> within a template tag then we should make it clear its scoped. Either via a capital in the invocation (<Style>) or via an additional attribute (<style scoped>). We don't want to prevent the actual use of the style element since it has its uses and is valid html.

I'm i'm 50/50 on whether or not I agree with this, because I agree we shouldn't break the web -- but in practice when would someone want a component to modify the global styles?

When we need to programatically generate styles. It is a very powerful tool when you need it.

sounds good to me. <style scoped> is pretty easy to lint for and against plain <style>, too, if we wanted to "soft-prevent" global style modifications

Updated the examples in the OP

Here is the package that already (kinda) implements this feature (but not with classes): https://github.com/cardstack/glimmer-scoped-css
can use this for the preprocessor logic

Update:

  • no scoped (this is default, so to specify is redundant)
  • :deep() for punching under the component boundary (such as when styling an external library)
  • global CSS would not be in components, ideally, but could be left "as is" via global attribute.