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

[css-scoping] scoped attribute on style element removed from HTML #137

Closed
prlbr opened this issue May 26, 2016 · 15 comments
Closed

[css-scoping] scoped attribute on style element removed from HTML #137

prlbr opened this issue May 26, 2016 · 15 comments
Assignees
Labels
css-scoping-1 Current Work

Comments

@prlbr
Copy link

prlbr commented May 26, 2016

https://drafts.csswg.org/css-scoping/#scoping-markup names the scoped attribute on HTML’s <style> element as example for scoping markup and references the WHATWG HTML spec, but the attribute has been removed from HTML in both WHATWG’s and W3C’s version.

whatwg/html#552
w3c/html#231

On a side note, is there hope that the very useful @scope CSS rule will be implemented by browsers or is scoping completely dead?

@tabatkins
Copy link
Member

It's likely to be dead; I suspect that we should remove it from the Scoping draft. It looks like, at least for now, browsers are settling on shadow DOM as the sole scoping mechanism. (While being somewhat more complex to use, it is much more powerful and feature-ful; <style scoped> is basically equivalent to just putting an ID on the container and using that in every rule.)

@prlbr
Copy link
Author

prlbr commented May 27, 2016

Thanks for the information, though it is sad to hear.

Shadow DOM may be more powerful, but requires JavaScript, which makes it less reliable or unusable in some contexts. Shadow DOM encapsulates code in two directions, i.e. styles in the shadow tree don’t affect outside markup and outside styles don’t affect shadow markup.

@scope would be different: It is about nesting. It would prevent inside styles from affecting outside markup, but allow outside styles to affect scoped markup. I understand that there are ways to pierce through shadow DOM’s shadow boundary from outside, but that has to be made explicit while it would automatically work for @scope.

I understand that @scope {…} would basically be equivalent to putting an ID on a container and using that in every rule, but sometimes we only have limited control over part of the rules and it would be very helpful to be able to encapsulate them against influencing anything outside a container easily. In my case, the alternative is to write/use a whole server-side CSS parser in order to be able to inject IDs at all the right and no wrong places automatically.

Compared to using a container ID in every rule, @scope would reduce redundancy (→ less typing, less bandwidth, less work/errors when changing code) which all users could benefit from, even if they have total control over their styles.

Nesting is a headline feature of CSS pre-processors like Less [1] and Sass [2] and CSS-Crush [3]. I think that shows that nesting capabilities are a desired and useful feature which @scope would provide.

[1] http://lesscss.org/features/#features-overview-feature-nested-rules
[2] http://sass-lang.com/guide#topic-3
[3] http://the-echoplex.net/csscrush/#core--nesting

@tabatkins
Copy link
Member

CSS Nesting (that preprocessors do) has nothing to do with @scope.

I recognize the benefits of scoping; they're minor but real. But browsers have not considered them worthwhile in the form of <style scoped>, and changing the syntax to @scope isn't going to change their minds, so removing it from the spec as a dead feature is the most accurate thing to do.

@prlbr
Copy link
Author

prlbr commented May 27, 2016

Yes, I fully agree that removing things from the spec that aren’t going to be implemented is the right thing to do. I didn’t mean to suggest anything else.

I have difficulties to understand why @scope has nothing to do with nesting as done by CSS pre-proccessors though. To me all these have the same effect:

Less:

#header {
  color: black;
  .navigation {
    font-size: 12px;
  }
  .logo {
    width: 300px;
  }
}

Scoped CSS:

#header {
  color:black;
}
@scope #header {
  .navigation {
    font-size: 12px;
  }
  .logo {
    width: 300px;
  }
}

CSS:

#header {
  color: black;
}
#header .navigation {
  font-size: 12px;
}
#header .logo {
  width: 300px;
}

Now that you’ve said it, I have found the css-nesting draft which does offer some useful features. Using it, the same code as above would look like this, if I’m not mistaken:

Nested CSS:

#header {
  color: black;
  & .navigation {
    font-size: 12px;
  }
  & .logo {
    width: 300px;
  }
}

It looks quite similar to the Less code, maybe even more so than the scoped code, but due to the & in every rule, nested CSS can’t do what both Less nesting and @scope achieve: Take some CSS code, say

h2 {color: red}
p {color: green}

and encapsulate the whole code without modifications by nesting/scoping it with a container element’s ID.

Less:

#container {
h2 {color: red}
p {color: green}
}

Scoped CSS:

@scope #container {
h2 {color: red}
p {color: green}    
}

So, in this case, I’d say that the pre-processor’s nesting has more to do with css-scoping than with css-nesting. I may be wrong though.

@astearns astearns removed the Agenda+ label Jun 4, 2016
@keithjgrant
Copy link
Contributor

keithjgrant commented Jun 7, 2016

I'm sad to see this discussion. I've been excited by this spec, and it does seem to have progressed since I last checked about a year ago (no more dependence on the HTML attribute, for one).

I disagree that @scope is akin to just adding an id. Because of the way scope works in the cascade, nested scopes can do so much more than just ids. With normal id selectors, you would have to write every possible permutation to make them target correctly when nested, whereas styles from the innermost scope will inherently apply over the outer scope.

This would be hugely valuable in highly-modular webapps. It seems to me this is the most direct answer to Christopher Chedeaux and all the CSS-in-JS discussion.

@keithjgrant
Copy link
Contributor

keithjgrant commented Jun 7, 2016

To really drive home the point, consider three selectors inside of three scopes:

@scope #one {
  .foo {}
  .bar {}
  .baz {}
}
@scope #two {
  .foo {}
  .bar {}
  .baz {}
}
@scope #three {
  .foo {}
  .bar {}
  .baz {}
}

To get equivalent cascading behavior out of IDs, you need to take every permutation of every scope's id, and add that to every selector in that scope. Here is the equivalent of just scope #one:

#one .foo,
#two #one .foo,
#three #one .foo,
#two #three #one .foo,
#three #two #one .foo {}

#one .bar,
#two #one .bar,
#three #one .bar,
#two #three #one .bar,
#three #two #one .bar {}

#one .baz,
#two #one .baz,
#three #one .baz,
#two #three #one .baz,
#three #two #one .baz {}

Then repeat ALL of that again for each of the other two scopes. Every time you add a selector to a scope, or add a new scope to the stylesheet, you exponentially increase the number of selectors you need everywhere.

@scope takes all of this complexity away.

@tabatkins
Copy link
Member

Yes, I understand the benefits of scoped styles over just using an ID. But that doesn't change the calculus; browsers didn't end up accepting scoped styles in the form of <style scoped>, so there's no reason to believe they'll accept them in the form of @scope.

@tabatkins tabatkins self-assigned this Jun 22, 2016
@tabatkins tabatkins removed the ready label Jun 22, 2016
@ionas
Copy link

ionas commented Jul 5, 2016

It's likely to be dead; I suspect that we should remove it from the Scoping draft. It looks like, at least for now, browsers are settling on shadow DOM as the sole scoping mechanism. (While being somewhat more complex to use, it is much more powerful and feature-ful; <style scoped> is basically equivalent to just putting an ID on the container and using that in every rule.)

This is really going past the demand. People are using Wordpress and non-wellformed-non-valid div-soup day to day. ShadowDOM is really great but a solution that works for regular DOM/HTML without a preprocessor and not only ShadowDOM is the way to go. ReactJS' and Elms adoption is also picking up. Unless you want another dead 'standard' as going for only ShadowDOM won't be adopted by masses.

Also see: #270

@inoas
Copy link

inoas commented Sep 16, 2016

This seems to be related, also: https://github.com/css-modules/css-modules

@unilobo
Copy link

unilobo commented Aug 16, 2017

If scope is being removed, is there another way to include styles as part of your module(s) that is nested in the body tag without breaking w3c standards?

@prlbr
Copy link
Author

prlbr commented Aug 16, 2017

@unilobo
Yes, the W3C HTML version allows style in body.
https://w3c.github.io/html/document-metadata.html#the-style-element

@unilobo
Copy link

unilobo commented Aug 16, 2017

ok, just when validating I get the following error:

Error: Element style not allowed as child of element div in this context. (Suppressing further errors from this subtree.)

>↩</div>↩↩<style>↩↩@med

But as you say the latest spec states that it can be used In the body, where flow content is expected.

i.e. most html tags

@prlbr
Copy link
Author

prlbr commented Aug 16, 2017

I think you could file a bug at https://github.com/validator/validator/issues . Not sure if they are going to fix this as long as WHATWG's version of HTML forbids style in body. See the related issue there: whatwg/html#1605

@o-t-w
Copy link

o-t-w commented Jan 27, 2019

@tabatkins I had some thoughts about this here:
#3547

@ctjlewis
Copy link

ctjlewis commented Sep 9, 2020

My only goal is to export a <style> tag that I can guarantee will not conflict with global styles in the wild, and it is admittedly frustrating that this was in the spec for years and got removed.

I guess it is possible to accomplish this with flat HTML, with large amounts of data redundancy; namely, generating a sufficiently long hash to put in the root element's id field, and prefixing all styles with #id [your-style-here].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-scoping-1 Current Work
10 participants