w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.51k stars 671 forks source link

[css-scoping] Support for CSS namespaces #270

Open ionas opened 8 years ago

ionas commented 8 years ago

I have been reading into https://drafts.csswg.org/css-scoping/ and into <style scoped>.

I am looking for client side namespace/module support for CSS.

CSS Files can be loaded in the head, in the body (defacto) and at the bottom of the body (deferred). In future multiple CSS files may get loaded by one request through HTTP2.

I think preprocessing is just an intermediate step and I'd love to see some support by clients themselves.

Correct me if I am wrong but csswg-css-scoping seems to be mostly about ShadowDOMs and scoped seems to be mostly about inline <style>-Tags. The issue with inline tags is that while @import can be used it will fire off another request. If you bundle requests in the head or at the very bottom of an HTML document the browser may be able to fetch all of these at once through HTTP2, thus saving request-operations.

While I do support ShadowDOMs there should also be ways to have namepaces/modules for DOM parts of your page (modules you could say) especially in the wake of ReactJS and Elm.

Take it with a huge grain of salt but this is what I came up with:

In some CSS file that is being loaded where you desire (eager loaded in the head, late loaded at end of the body, lazy loaded near to some DOM module) you should be able to do this:

@namespace('alphanumerical-dash-underscore-dot-namespace') {
    /* your regular CSS declarations here */
    h1 {
        font-weight: bold;
    }
}

Then where-ever you consider it to be right you should be able to say:

<style namespace="alphanumerical-dash-underscore-dot-namespace">
    <h1>This would be bold</h1>
</style>

There should also be an optional way to enforce that a namespace can only come from one CSS file (or style block):

@namespace('alphanumerical-dash-underscore-dot-namespace', final) {
   /* your regular CSS declarations here */
    h1 {
        font-weight: bold;
    }
}

This would mean that any declaration that comes along later would not take effect at all but instead browser vendors should be advised to throw an error similar to JS throwing errors.

Thus instead of going from ShadowDOM as an day to day application (and I like Shadow-DOM!) why not go from the common cases and issues people have every day. E.g. it would help the web - drive forward HTML5 vs non-accessible vendor specific apps. It could also be very well combined with browser side includes that the Google/Chrome team was working on (not a fan of Chrome but a fan of that idea).

ionas commented 8 years ago

instead of <style namespace="alphanumerical-dash-underscore-dot-namespace"> there could also be <div styleNamespace="alphanumerical-dash-underscore-dot-namespace">.

ionas commented 8 years ago

Doing something like @namespace('alphanumerical-dash-underscore-dot-namespace', extends(:root, 'some-other-namespace') {... would be nice as well.

tabatkins commented 8 years ago

Scoped styles (and things very similar to them) are dead for now. We'll see what we still need in a few years, when web components has been more widely adopted.

htstudios commented 8 years ago

That is really an elitist approach that does not take the current state pf web developers and code based with it. Seems its time for yet another WG spin-off/fork in case vendors can agree upon it. Sad.

svgeesus commented 8 years ago

A CSS property walks into a bar. In another bar in a different city, a stool falls over

Over the last month I have been at three CSS conferences, talked with developers whose companies are doing substantial CSS development. A consistent complaint about CSS that I am hearing again and again is how difficult it is to avoid leakage and side effects. The solutions proposed vary but the problem developers face is real.

Looks like this issue was closed prematurely and would merit CSS WG discussion.

LeaVerou commented 8 years ago

That is really an elitist approach that does not take the current state of web developers and code based with it.

Indeed. I cannot count in how many conferences lately I've been asked about scoped styles and components, and, quite embarrassingly, I had nothing to tell these authors. I can't even promise them anything that is coming in the future or that at least that the issue is being discussed. The response is always met with bewilderment: why wouldn't we be doing anything to address what seems to be a very pressing author need?

We don't need to wait for web component adoption to figure out what authors need. There are component frameworks (e.g. React) that authors are already using, and we can study their use cases from there.

ionas commented 8 years ago

Thanks for considering the issue at hand that is being faced by any bigger CSS application, e.g. by thousands of developers day to day.

It is not about the suggested implementation or concrete syntax: I'd like to purpose this abstract list of priorities, and discuss their contents and priority:

  1. Simplicity: The feature should be as minimal and simple as possible to make browser vendors want to implement it and common end users want to use it.
  2. Extensility: The feature should be extensible in future iterations of CSS.
  3. Compatibility: The feature should not render at all in browsers not supporting it. The feature should allow to be used with ShadowDOM/webcomponents as well as SVGs and abitrary XML not just every-day CSS or ReactJS/Elm.
  4. Encapsulation: The feature should enable: A way to declare a block of CSS declarations to be applied after global declarations (e.g. with higher specificity) only to certain parts of the DOM by specifying an encapsulating style tag or an attribute applied to an element. That given element would already be considered part of the sub-tree. E.g. both, a section of CSS and a section of the DOM should be encapsulated and linked.
  5. Independency: This linking (see 4.) should happen independend of where/how the CSS ressources are being loaded. E.g. requests could be bundled via HTTP2 or via combining multiple namespaces in one CSS document/ressource or loaded lazily whereever required.
  6. Cascading: There should be a way to cascade namespaces by extending one by another, e.g. the css declarations would sit next to each other.
  7. Control: There should be a way to final a namespace. However this might become difficult due to the order of loading of CSS ressources now being relevant over specificity.

Is this a good approach for you guys? Do you feel anything is missing? Do you feel anything does not belong here? Would you see other priorities?

Notes

Edit

ionas commented 8 years ago

Hacks like these get promoted: https://medium.com/@jviereck/modularise-css-the-react-way-1e817b317b04#.y6dbnmjgm because of the lack of encapsulation/side-effect-mess.

tabatkins commented 8 years ago

Scoped styles only protected against leaks in one direction (prevented the styles from escaping to the rest of the page). That's nice, but the other direction (preventing the rest of the page from accidentally styling the component) is also vitally important for the use-case of "a composable component that Just Works no matter where I put it in the page". That's what web components are giving us right now. Cases that only need the single-direction protection seem to be much rarer.

You cannot easily mod scoped styles into doing both types of protection without getting into most of the complexity of web components, so it doesn't seem worthwhile to duplicate effort. There's obviously an unfilled niche of declarative web components when you only need some of the simpler parts of the tech, like style boundaries, that currently isn't being filled, but "scoped styles" are not the way to do that, nor is this spec the right place to explore these things. The correct thing to do is wait for web components to settle down a bit and become well-implemented, so we can figure out what the best way to extend them to address our use-cases is.

Regardless, implementations have explicitly stated that they're not implementing scoped styles, and their reasoning applies equally to anything adjacent to scoped styles. We already resolved on this in a previous meeting, and there's no indication that attitudes have changed in the intervening weeks, so further discussion won't change anything.

ionas commented 8 years ago

unfilled niche of declarative web components when you only need some of the simpler parts of the tech, like style boundaries, that currently isn't being filled,

This hits it on the nail. You said it yourself.

The correct thing to do is wait for web components to settle down a bit and become well-implemented, so we can figure out what the best way to extend them to address our use-cases is.

I propose going the other way. Making scoping work in either or both ways. That is the correct way that helps the HTML platform become better, less error prone, more efficient, easier to use even for every-day-html-'hackers'.

A - maybe - naive thought: See you could (optionally, mind you!) put <html> in a namespace and you could say whenever you put something in a namespace it will not by default leak its definitions downwards, and a namespace will never leak them upwards. So you can say <html stylespace="canvas"> and later on in your code <footer stylespace="footer-component">... and styles defined within @stylespace ('canvas') would not leak down UNLESS @stylespace('footer-component') extends upon 'canvas'.

I am just hoping that further discussions will make implementors wake up.

It would be great if solutions are being prepped sooner than later, at least in theory. And if the feature is simple and extensible and there is a lot of social pressure - maybe implementors will agree that its a good way to go forward carrying with them the majority of the webs current state (like: wordpress, bootstrap, angular, reactjs (and with the exception of reactjs I despise those techs but ALL of them would benefit greatly from having easy tools to stop leaking from outer scope and to outer scope)).

Edit Edited a bit. Sorry.

prlbr commented 8 years ago

@tabatkins, in https://github.com/w3c/csswg-drafts/issues/137#issuecomment-222031438 you said scoped styles would be “basically equivalent to just putting an ID on the container and using that in every rule”. That may not be really true as discussed further down in that thread, but if a simpler version of scoped styles would actually be equivalent to just that, than this would be a huge help with real use cases already and I don’t see why “just putting an ID on the container and using that in every rule” should be too much code complexity for browsers.

Let’s just define

@prepend foo {
    bar, baz {
        …
    }
    @prepend qux {
        dang {
            …
        }
    }
}

to be equivalent to

foo bar, foo baz {
    …
}
foo qux dang {
    …
}

To me, this seems to be just about syntactic sugar in CSS – but really, really sweet one that solves real problems. It doesn’t need more than that to prevent leaks in one direction, if foo is a unique ID. You don’t have to change anything about how CSS works in the background, you don’t need to touch specifity. Just treat the former code as if it were the latter.

For preventing leaks in both directions, you can require JavaScript and have all the complexity of shadow DOM for styles to work as desired, if that’s what many other developers want. I don’t bother.

kevinSuttle commented 8 years ago

It seems to me that trying to shoehorn namespaces is a fool's errand. Some think making styles local by default is a good idea, but I believe we'll always need globals.

Perhaps a less radical solution is to implement :global/:local or @global/@local flags?

ionas commented 8 years ago

I think global/local is too simple of a dichotomy. Extending upon closed scopes would be cool as you could still cascade style declarations very well.

fantasai commented 8 years ago

@svgeesus, I'm having trouble understanding why this request is different from/better than https://www.w3.org/TR/2014/WD-css-scoping-1-20140403/#scope-atrule

As for blocking styles from leaking in,

  @scope whatever {
      * { all: revert; }
  }

should work, right?

svgeesus commented 8 years ago

Tab said on today's call that scoped styles were removed from the implementations.

We decided a wiki page summarizing experience to date would be the best way to engage the community rather than have a github issue as this is not really a single issue. Tab had the action to start such a page. Leaving issue open for now until that page exists.

fantasai commented 8 years ago

That doesn't answer my question. Also @scope is quite different from what was implemented, which was <style scoped> and requires the CSS to be in the markup itself.

LeaVerou commented 8 years ago

As for blocking styles from leaking in,

@scope whatever { * { all: revert; } }

should work, right?

Yes. I was happy to see that scoped rules override rules from the outside regardless of specificity. This is awesome. Sadly, it seems to be dropped from the ED. Also, the syntax is a bit clunky. Why not Tab's & idea, which also matched preprocessor syntax more closely?

fantasai commented 8 years ago

It was dropped for lack of interest. Nobody was advocating it: not implementers, not authors, not anyone in the CSSWG.

The & proposal, IIRC, was just about concactenating selectors (as is done currently in preprocessors). This introduces a scoping level, which also affects the cascade. I'm not sure you always want to do that.

ionas commented 8 years ago

@svgeesus So if this is not a single issue (the issue being: no leaks from outside, no leaks to outside, explicit extensions) - what are the multiple facets?

For now I am looking forward to the wiki @tabatkins

LeaVerou commented 8 years ago

It was dropped for lack of interest. Nobody was advocating it: not implementers, not authors, not anyone in the CSSWG.

How can authors express interest when most of them don't read specs and had never heard of this? Authors keep requesting nesting & scoping, just because they are not advocating this particular solution doesn't mean it's not a big problem for them.

This introduces a scoping level, which also affects the cascade. I'm not sure you always want to do that.

Intuitively this seems true, but can you think of any use cases where you don't want to do that? Theming is the only one I can think of…

ionas commented 8 years ago

Why not Tab's & idea, which also matched preprocessor syntax more closely?

  • Where can I read about this idea?
  • Having support for how pre-processors do it is not nearly sufficient. Pre-processors can only do so much, namely whatever can be trans-piled to CSS. There should be exclusive namespaces that don't clash with IDs and classes. Else I can't see why you can assume that specificy will stop working as the sole instrument of determining which declaration block of properties gets applied to which selector.

Out of the proposed interface above, for example:

this combination would be default browser styles + whatever is declared within the namespace

<section namespace="foo-namespace">
    <p>Hello World</p>
</section>
@namespace('foo-namespace') {
    section {
        padding: 1rem;
    }
    section p {
        line-height: 200%;
    }
}

whereas this would explicitly inherit rules (and then go by selector specificity) from a base namespace

<html namespace="base-namespace">
...
<section namespace="foo-namespace">
    <p>Hello World</p>
</section>
...
</html>
@namespace('base-namespace') {
    html {
        font-family: 'Liberation Sans'
    }
}
@namespace('foo-namespace' inherits: ('base-namespace')) {
    section {
        padding: 1rem;
    }
    section p {
        line-height: 200%;
    }
}

This would inherit one after another

<html namespace="base-namespace">
...
<header namespace="header-namespace">
    <form namespace="login-component-namespace">
         <label>Username</label>
    </form
</header>
...
</html>
@namespace('login-component-namespace' inherits: ('base-namespace', 'header-namespace')) {
    /* ... */
}

Here the question would be if inheritance works 'recursive' up the tree or not, e.g. if it would be sufficient to inherit 'header-namespace' if that one again inherited 'base-namespace'.

What I am trying to get to is a way to declare certain blocks to not take leakage from the parent DOM and not leak to the DOM.

Because of that there is also the idea to final certain declarations. This would make components, once loaded, save from other css declarations being loaded afterwards to not mess with them (be discarded).

Example

@namespace('login-component-namespace' inherits: ('base-namespace', 'header-namespace') final) {
    /* some declarations here that will be applied */
}
@namespace('login-component-namespace' inherits: ('base-namespace', 'header-namespace')) {
    /* these won't be applied no matter what */
}

A DOM (sub)tree should be able to take multiple namespaces. When doing so things don't need to be nested through the DOM and CSS specificity is merged among the 2+ namespaces. Like

Example

<html>
...
<header namespace="header-namespace, flat-corporate-identity-namespace">
    <form namespace="login-component-namespace, flat-corporate-identity-namespace">
         <label>Username</label>
    </form
</header>
...
</html>

Open issues

This seems to solve:

  1. Developers can disable leaking of outside to inside: Declare a namespace, don't inherit from parent namespace.
  2. Developers don't accidentially leak declarations from the inside to the outside: While css selector specificy is intact within a namespace, its declarations only affect elements where the namespace is declared to (including its declaring parent, e.g. section in <section namespace="foo-namespace">.
  3. There is both models supported: logical inheritance and logical aspects. E.g. you can give certain dom (sub) trees certain aspects or you use inheritance.

I am happy to discuss things like this on Freenode IRC (#css or whatever your prefer) and/or a wiki or in some other forms. I am also happy to learn about pitfalls. Please let me know how to get in touch.

I think there is a real need to be able to have css modules/scopes etc, that don't take leakage nor leak themselves but can be made to if desired.

A feature similar to this HERE would help every-day developers and it would help the web platform to mature even more and become more strict (if desired) and less error-prone, e.g. more reliable, better to maintain and extend.

ionas commented 8 years ago

How can authors express interest when most of them don't read specs

The issue with specs is that they used to be stable. While I love what WHATWG has done, it seems there are ton of specs that are dead or early-alpha and there is little being done to get in feedback of day-to-day real-world "average-joe" authors, developers, designers (just think about the wordpress ecosystem mess...)

prlbr commented 8 years ago

<style scoped> was ditched by Google because it was to complex for Google to implement besides shadow DOM. It's a pity, but it's also reality right now. Do you guys think that similar, equally or more complex features will have better chances to be implemented right now? If complexity is the problem, aiming for a simpler feature without that complexity, but which still covers part of the use cases seems more sensible to me.

@ionas

Why not Tab's & idea, which also matched preprocessor syntax more closely?

Where can I read about this idea?

I think Lea refers to this: https://tabatkins.github.io/specs/css-nesting/

I see some benefits of the & idea, but having to edit & into every nested rule is a significant disadvantage too. These are different concepts with only some overlapping and different use cases, really.

ionas commented 8 years ago

About simple: In regatds to @prepend: Could you explain how leakage from outside is stopped in that proposal? Would you care to elaborate? Ref: https://github.com/w3c/csswg-drafts/issues/270#issuecomment-231999279


One of the core issues I was trying to solve is that the basic identifiers are just tags, classes and ids. Aside ids these identifiers can be re-used. For every use, the selectors matching apply their property declarations. Now the custom attribute I am suggesting tries to work around that:

How do you propose @pretend solves these issues?

In terms of simplicity: The proposal I setup above could be separated into 3 implementation levels to keep it simple. Level 1 would be basic namespaces, Level 2 would allow explicit inheriting, Level 3 would allow finalization (e.g. marking a namespace to be read-only from then on).


I read through @tabatkins css-nesting - thanks for linking. I don't - however - see why it would not leak - so it is a different concept, but none that fixes separation of concerns / leakage. Did I miss something?


I took a look at https://drafts.csswg.org/css-scoping/:

"Why is the shadow host so weird?"

Maybe this should be solved instead of worked around with :host-context?

It would not be very good if a component used a particular class name internally in a shadow tree stylesheet, and the page author using the component accidentally also used the the same class name and put it on the shadow host. Such a situation would result in accidental styling that is impossible for the component author to predict, and confusing for the page author to debug.

In my proposal above, as soon as you declare a namespace attribute that element and all its children are part of that namespace. It is both, the host and the root of the shadow-tree. Why is that so bad?

And then two more questions:

prlbr commented 8 years ago

About simple: In regatds to @prepend: Could you explain how leakage from outside is stopped in that proposal?

It's not. It stops leaking in one direction only.

kevinSuttle commented 8 years ago

Let's clarify: "nesting", "scoping", and "namespacing" are not interchangeable. All 3 different.

ionas commented 8 years ago

What would make the difference between scope and namespace?

kevinSuttle commented 8 years ago

Two separate style rulesets can each be scoped, which will not share with each other, or the rest of the document for that matter. It's like an unnamed namespace, if that makes any sense.

If they're under the same namespace, they're specific to that declaration, and are intended to be shared, but only within definitions. Yes, very confusing, but an important differentiation.

fantasai commented 8 years ago

Nobody has yet replied to me why @scope is insufficient or badly-designed and we need some more complex thing like “namespaces”. As for my opinion on “namespaces”, I'm opposed to any solution that requires specialized CSS-specific markup as is being proposed here.

@LeaVerou If you have a better idea on how to get author feedback on early-stage drafts, other than posting to the CSSWG blog which we're doing already, I'm sure the WG would love to hear it. However, that is off-topic for this particular thread, please open a new one. :)

LeaVerou commented 8 years ago

Personally, I like @scope and I think it covers all the style isolation use cases. It doesn't cover the use cases where nesting is just a way to DRY-up CSS though, so I believe we need both. I know I'm only one data point, but now that we have variables, I basically only use Sass for nesting.

As to author feedback, we don't need feedback, we need user (author) testing. One of the tenets of usability is that users don't really know what they need and asking them will produce bad designs. Of course user testing is hard and costly, but in this case we can see what they already do via preprocessors and frameworks.

inoas commented 8 years ago

@LeaVerou like this? Not that I propose it is the best solution: https://github.com/css-modules/css-modules ?

kevinSuttle commented 8 years ago

@ionas See http://kevinsuttle.com/posts/css-modules-a-review

kevinSuttle commented 8 years ago

Theming is the real thread here, right? Namespaces are just a means to an end, correct?

The spec has never really had a good answer for UI theming. Right now, it either ends up as multiple class patterns, data-*, attributes or BEM/SUIT/some other naming convention.

inoas commented 8 years ago

I can only speak for myself: No. The primary concern is having components, not necessarily shadow-dom based, but just html components (think Elm, ReactJS, PHP server-side compilation, etc) that should be able to inherit different aspects and/or just render totally isolated. Depending on use cases.

inoas commented 7 years ago

A declarative way to create a Shadow-DOM root seems to be one way: Ref: https://github.com/whatwg/html/issues/552#issuecomment-266542678

Kinematics commented 7 years ago

After various considerations of ways this might be implemented, I came up with an idea that seems quite simple, with minimal additional complexity for the browser.

The main goal of a namespace is rule isolation. That is, the child space should not leak into the parent, and the parent space should (optionally) not leak into the child. We have most of the tools to handle that already. A secondary goal would be to avoid anything that touches the HTML markup, but instead keep the implementation entirely within CSS.

So, the additional tools:

1) Add a new function that's usable with the @when block conditional (issue #112), called defined(). defined() accepts a property, and returns true or false depending on whether the property is defined. Or, more generally, applies that condition check for every single rule selector within the block it's a part of. For standard browser properties, this would always be true, and thus not interesting. However the real value is using it in conjunction with custom properties.

<html>
    <section id="one">
        <p>Stuff</p>
    </section>
    <section id="two">
        <p>Stuff</p>
    </section>
</html>

#one {
    --my-namespace: exists;
}

@when defined(--my-namespace) {
    p { color: red; }
}

You have the full flexibility of normal selections in order to assign the custom property (eg: an attribute selector on an ID or data- attribute in order to identify where the element is being put in the HTML), rather than being fixed in place in the HTML using a namespace attribute or whatever. This also means it can apply to various nodes all at the same time without having to edit each one directly (as with the earlier suggestion of the explicit namespace attribute).

Custom properties are already set up to dynamically handle DOM scoping. In the above example, the paragraph in section #one would be red, but section #two would not be. It's using a custom property to control an entire set of rules, rather than one property value at a time.

Given that scoping is already handled for custom properties, this means that the @when block implicitly prevents the child scope rules from leaking into the parent scope. For every rule inside the @when block, selectors are only valid when the custom property is defined, which neatly isolates the rule applications.

We can also (if we wish) prevent the parent scope rules from leaking into the child scope with another already existing property: all: unset.

p {
    background-color: black;
}

@when defined(--my-namespace) {
    * { all: unset; }
    p { color: red; }
}

The * selector would only select elements for which --my-namespace was defined. That prevents anything from the parent scope from affecting the child (such as the black background-color) — except for propagating any other custom properties (which aren't affected by unset). That means that the child scope can accept custom properties as configuration parameters while still being shielded from parent leakage. For reusable widgets, you'd probably want standardized naming conventions to avoid collisions (eg: --company-product-parameter-name), but that's outside the scope of the rules.

2) One additional component that I think would be necessary would be some way to address the 'root' element of a given custom property. That is, elements which have the custom property defined, but which do not have an ancestor element with the custom property defined. This would be repurposing the :root of the document, but since the document :root would not be valid within this block (and thus meaningless in its original sense) unless it had the custom property defined within it (in which case this becomes entirely redundant), it seemed appropriate to allow the :root within this block to mean something analagous. There's no guarantee of a single root node, though (eg: a widget might be inserted multiple times in a single page), so there might be a preference for a different term instead.

Whether it's called :root or something else, though, there should be a way to reference the highest-level node(s) for which the custom property is defined.

That seems to be all that should be necessary to implement namespaces, while keeping things clean and flexible enough to use the feature for more general purposes. Codewise, most of the work is already done, given custom properties. There should be no issue with multiple defined() blocks overlapping, which opens up additional use cases. And everything should work pretty normally with javascript, so no extra fanciness needed there.

If you need to add rules that 'penetrate' the boundary (without modifying the original file) as suggested with the >>> in the original scoping proposal, you can just put them into another @when defined() {} block for the same custom property, and the normal cascade takes care of things from there.

The only possible tricky bit is how this gets applied with the @when block structure, since they're likely to treat conditions as a one-time case, rather than applying to everything within the block. I would actually consider this as a suggestion that @when and @if could be considered two separate ideas. @if is a one-time condition check that just separates out parts of the CSS, and @when is a condition that has to apply to everything within the block. I know there was a question of which word should be used, and this could be a reason to treat them separately, depending on how the rules want to approach things.

htstudios commented 7 years ago

:origin or :mixin instead of :root could work.

zlamma commented 6 years ago

I wholeheartedly support the idea of scopes that don't leak rules to the outside, but allow to change the appearance by rules specified on the outside.

Thoughts on implementation:

Regarding two comments

@fantasai's https://github.com/w3c/csswg-drafts/issues/270#issuecomment-236974330 As for my opinion on “namespaces”, I'm opposed to any solution that requires specialized CSS-specific markup... @Kinematics https://github.com/w3c/csswg-drafts/issues/270#issuecomment-290969197 A secondary goal would be to avoid anything that touches the HTML markup, but instead keep the implementation entirely within CSS and:

I would like to respectfully disagree that declaring the scopes in the CSS is a desired feature, at least in the proposed form where the scope is added in the same file that contains the rules to be scope.

While it might be desired for some app architectures to have CSS concerns defined in the same CSS files, I feel the community could benefit if there was a way to achieve outwards-leak prevention 'without touching the same CSS files' (both ways could exist, I think no one would mind - in fact Shadow DOM's good part, the leaking-outside-prevention has that good feature already - your component CSS does not need to know it's being scoped).
This would allow interoperability with content of others, including all of the historic one. E.g. it would make it very simple to quote someone with all the richness of they way he presented it using CSS stylesheets without modification of that content that [isn't being/hasn't been originally] authored with scoping in mind. It's only obvious that all of the current content hasn't been authored with scoping, since the technology isn't there yet, but even when it arrives, scoping will not be used by authors for their own content, so being able to add it outside is essential if [quoting/information dissemination] is to be easy in WWW.

As such, I would welcome being able to just [paste/dynamically load] a valid HTML content authored by anyone in the past into a specially crafted tag and sleep easy that I haven't lost control over the appearance of the rest of my document. To borrow the tag & attribute idea from the mentioned comment:

<article>
... what the PoliticianXYZ published on his website:

<div style-scope-mode='let-all-styles-in-but-none-out'>
    <-- Some pasted historical HTML:-->
    <style>h1 { animation: blinker; }</style>
    I have never ...
</div>

... is simply contradicting to what he claimed in the past:
<div style-scope...

Coincidentally, this exact subject is being discussed in this comment on the 'declarative Shadow DOM through a tag' proposal which, I would argue, also suggests 'touching HTML' to achieve CSS concerns (granted, there are others, like id attribute scopes, but the CSS impact I'd argue is the most important).


Few thoughts on motivation for the feature: I would like to be wrong, but I fear that this feature has so little interest because of poor Internet health in terms of decentralization, where independent HTML authors are all but extinct and the use-cases debated by the consortium are dominated by 'web apps' for proprietary commercial use, with little sharing of free-form content and minimum trust between parties.
For example, for the big web companies like Google, most important use case for web components is "being able to have proprietary components that people are able to use on their websites, but are not able to tamper with, e.g. the branding", hence so much interest in shielding from the outside in their push for web components.

While I agree that 'secure by default' must be always be applied, I feel that not leaving even an option (!) for openness to easily reuse with unfettered modification, leaves out the needs of communities that thrive on trust, openness and invitation to use existent work and take it further. Many usages of hypertext are limited to 'thoughts exchange', where the security concerns of web applications are completely acceptable! So far, I always thought that these communities' interests were always well taken care of by all W3C standards (e.g. JavaScript being open and malleable, HTML being open and linkable and CSS's being pretty much always overrideable through cascading, RDF being infinitely extensible), but the recent removal of scoped CSS feels like the first exception to the rule. I really hope I am only being paranoid to think that it has something to do with the fact that all but one browser are run by commercial companies.

bkardell commented 6 years ago

@zlamma I don't work for Google or any browser for that matter, but yes I think you're being paranoid about that. I don't think that your statement about Google's most important use cases or motivations is supported at all by the actual history of all of this.

zlamma commented 6 years ago

@bkardell well, good to hear.

Ignoring that attempt of mine at a literary hyperbole, I would welcome feedback on how the use case I gave is important to the consortium and the community.

inoas commented 6 years ago

@zlamma What I know for sure is that some google employees do not want declarative shadow-dom implementations which makes JS mandatory even if you want to disable it for security/privacy reasons.

Now the last time CSS features (here creating CSS root nodes) were bundled was in Netscape 4: If you disabled JS CSS1 would be disabled as well.

Not having declarative shadow doms is kind if similar.

There is clear demand by authors and a declarative shadow dom approach would save vendors from duplicate implementations of similar features (scoped styles), allow server side prerendering, http2 push/preload integration and help end users with privacy and perfect performance (in case authors care for that, they then can deliver).

zlamma commented 6 years ago

@ionas Thanks for your thoughts. It's certainly good to know there is a demand, and declarative Shadow DOM, even as it is offered by the browsers now, is certainly a step forward.

I'm still concerned about the final goal though - being able to allow external rules to pass through. From the response to the comment I linked to, the 'declarative shadow DOM' is (rightly) not trying to solve the problem of browsers not offering it currently.
I hope this issue is more appropriate to solve it. And while the proposals here suggest solutions different to it (namespacing and @​where ), I feel that, if declarative Shadow DOM gets implemented, piggybacking onto that element with something like a mode= attribute is quite a nice solution. After all, both intentions relate to preventing CSS leaks.

zlamma commented 6 years ago

I would like to risk a theory that the reason why it's so hard to see how much exactly there is support for this feature is because HTML & CSS is so easy to understand, that the vast majority of people who care about it are not really technical, let alone ever thought of engaging with standard-setting bodies. And as soon as someone becomes more technical, he is concerned much more with the advancement of state of the webApps development which, as everyone knows, has its own pressure for badly needed features.

Yet another reason has been put nicely in:

https://github.com/whatwg/html/issues/552#issuecomment-249038746 I understand the decision is unchangeable, but I still want to express my disappointment. We developers never have chance to experiment scoped style feature broadly

Last reason, I feel, is that it's simply hard to tell where the official place to contribute convincing arguments on this subject - many are being closed and opinions unwelcome - so the initiative dies of fear for any engagement being a reputation tarnish or at least a waste of time. After a few closed tickets (including this one at one point) a wiki has been promised. I would really like to suggest - do whatever you like, but please 🙏 be wary that every time a such a move is proposed, or a thread is closed without directing to the right place for arguments, community get a signal that whatever energy they spent on the subject was a waste of time, and whatever arguments they produced are as good as in the bin.

Having that in mind, I allowed myself to try to consolidate particularly clear signs of user's community support for the feature that I found recently, which also seem to be backing the theory.

  1. Just have a look at the number of 👍s on https://github.com/whatwg/html/issues/552#issuecomment-249038746

  2. https://github.com/w3c/csswg-drafts/issues/270#issuecomment-234105549: How can authors express interest when most of them don't read specs and had never heard of this?

  3. https://github.com/w3c/csswg-drafts/issues/270#issuecomment-231579064: I cannot count in how many conferences lately I've been asked about scoped styles and components, and, quite embarrassingly, I had nothing to tell these authors.

  4. https://github.com/w3c/csswg-drafts/issues/270#issuecomment-231578840 Over the last month I have been at three CSS conferences, talked with developers whose companies are doing substantial CSS development. A consistent complaint about CSS that I am hearing again and again is how difficult it is to avoid leakage...

  5. https://github.com/JSFoundation/standards/issues/47#issuecomment-234357802: We have received many requests over time to make it MORE EASY to override our base styles. ... I don't think we have ever had complaints about wanting the css to be more protecting from outside fiddling only less.

  6. (same author - response to using CSS vars as a solution) - https://github.com/JSFoundation/standards/issues/47#issuecomment-234375188: ... We have never had any type of request for or attempt to shield our selves from outside css nor do we have any desire to do this its quite the opposite of what our users have expressed they wanted. Our concerns are completely about restricting our own scope to allow multiple themes or multiple frameworks that might use the same class.

bkardell commented 6 years ago

@zlamma I do appreciate the problems you are articulating, believe me. I've written a bunch about just about all aspects you are describing over the years. Is there a good way (besides chatting in github issues) to reach you to discuss this a little more? My own contact information is available in my github profile and the website linked there. I ask simply because I feel like lots of 'bits' of this discussion and followup may be slightly off-topic for any of these specific issues and I hate to spam people with lots of cross-issue stuff. Perhaps we could discuss a bit and then rejoin an issue?

zlamma commented 6 years ago

@bkardell I actually feel I have finished sharing those of my thoughts that I felt weren't heard yet, so you shouldn't fear more 'spamming'. Although, on that note, I would like to think that I am doing my best to also to keep the issues focused (https://github.com/w3c/csswg-drafts/issues/270#issuecomment-364688245).
But this isn't easy for anyone precisely because the whole subject is being so scattered. You say that you've 'written about almost all of the aspects I am describing', so, I understand, somewhere before you acknowledged the benefits I listed... which is great, but doesn't the fact, that I haven't managed to find out about this after reading what seem to be the best github issues for the subject, show even more emphatically how the community is in need of a single place to learn about all that relates to this prospective feature?

So, while I will gladly write you directly to establish a direct contact, I feel that switching to direct communication is actually just going to keep the 'cross-issue spam' situation going. IMHO, much better in preventing it would be an attempt to curate an unduplicated list of all of the good and bad consequences of the said feature, where it is easy to discover existent points already made, and every attempt at adding to the list is welcome. Perhaps it's time for that wiki then?

bkardell commented 6 years ago

To be clear, I'm not suggesting that you are spamming or doing something wrong. I'm simply suggesting that a few times now I've had comments and questions that are more conversational in nature than directly 'helpful' to the issue itself, and I'm always hesitant to add these to issues as I've seen this to people getting overwhelmed and disengaging with the thread. In the old days, you'd simply reply offlist, get that stuff sorted out and rejoin with the necessary details.. if there are any. If you have contact info, this is pretty easy and common today too - in fact, I just did it earlier today and that has already caused the thread to be updated. Sadly I wasn't able to find yours, which is the reason I asked.

SebastianZ commented 6 years ago

@svgeesus said:

We decided a wiki page summarizing experience to date would be the best way to engage the community rather than have a github issue as this is not really a single issue. Tab had the action to start such a page. Leaving issue open for now until that page exists.

@zlamma said:

Perhaps it's time for that wiki then?

I guess a good place for this would be https://wiki.csswg.org/ideas. @tabatkins, according to @svgeesus you were in charge of setting up a page. Could you please start it?

Sebastian

zlamma commented 5 years ago

3 years passed, but still no promised wiki where community could be helped to waste less time yet*). But on a relevant note, there's now yet another GitHub issue about this.

Interestingly, it's main suggestion brought an idea that seems very much like the @scope spec dropped from the CSS**).

Even more interestingly, it's current latest suggestion allows to add a lower boundary to the @scope rule, which seems interesting.

Still, as said previously, I'd like to suggest that the working group also considers making it possible to apply scope to the rules outside of the very stylesheet where these rules live, e.g. somewhere in a parent (coincidentally, Shadow DOM has this feature). Also, as I said there, both ways could co-exist.

In the light of the new issue and its new proposals, I attempted to compose an example of how all the features could co-exist in this comment to the new GitHub issue.


*) As said before, it would help to curate an unduplicated list of all of the good and bad consequences of the said feature can, and it would be easy to discover existent points already made, and every attempt at adding to the list is welcome...

**) About which I learned in the hereby thread, in this comment. By the way, I agree with @fantasai about this one - the @scope proposal seems equivalent to this namespaces proposal as namespaces can be represented by special class names. The @scope one seems to be even more powerful though, as it leaves more freedom to the users in that they don't need to be classes, and it doesn't require the HTML content to have any styling concern added - the effect can be applied through selectors with a semantic approach.

gnat commented 1 year ago

This project is living in the future: https://github.com/gnat/css-scope-inline

Keep the syntax simple and short, friends. I want to see <style scoped> return too, but let's try our best to cut down the excess verbosity.