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

Styles bleed through #78

Open
simplesmiler opened this issue Jun 28, 2016 · 2 comments
Open

Styles bleed through #78

simplesmiler opened this issue Jun 28, 2016 · 2 comments
Labels

Comments

@simplesmiler
Copy link

simplesmiler commented Jun 28, 2016

Example:

/* comment.css */
:host .header {
  color: blue;
}
/* article.css */
:host .header {
  color: red;
}
<article class="_article-hash">
  <h1 class="header">Article title</h1>
  <section class="comments">
    <article class="_comment-hash">
      <h2 class="header">Comment title</h2>
    </article>
  <section>
</article>

Comment header will be either red or blue, depending on the order of file inclusion. You can guard with > selectors, but this makes your CSS dependent on the exact DOM structure.

Shadow DOM naturally does not suffer from this.
BEM does not suffer from this, due to using unique names.
CSS Modules does not suffer from this, due to rewriting all class names.
Vue implementation of scoped styles does not suffer from this, due to rewriting HTML too and using different prefixing technique (<div class="header" _article-hash> and .header[_article-hash]).

@yoshuawuyts
Copy link
Contributor

Oops, yeah - good point, thanks for finding this and reporting it. Bit swamped with work right now, so don't quite have time to fix this. What do you propose the solution is to this?

@simplesmiler
Copy link
Author

simplesmiler commented Jun 28, 2016

The simplest solution I can think of is following the Vue approach with a slight change:

:host -> ._hash
.compound > .selector => .compound._hash > .selector._hash.

<article class="${articleHash}">
  <h1 class="${articleHash} header">Article title</h1>
  <section class="${articleHash} comments">
    <article class="${commentHash}">
      <h2 class="${commentHash} header">Comment title</h2>
    </article>
  <section>
</article>

This way whenever you reference a "local" class, you need to add the hash. But to do this manually is still cumbersome and error-prone.


Another solution is following the CSS Modules approach and rewriting classes:

:host -> ._host-hash
.compound > .selector => ._compound-hash > ._selector-hash.

<article class="${article.$host}">
  <h1 class="${article.header}">Article title</h1>
  <section class="${article.comments}">
    <article class="${comment.$host}">
      <h2 class="${comment.header}">Comment title</h2>
    </article>
  <section>
</article>

With this approach the library needs to worry about case, because JavaScript does not support the - in the names of variables. So the library either:

  • Needs to promote using camelCase classes, like CSS Modules does (otherwise developer would have to write something like class="${comment['snake-case']}", which is far from being nice),
  • Needs to promote snake-case and convert to camelCase internally.

@dy dy mentioned this issue Jun 29, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants