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-cascade] @scope as a nested grouping rule and CSSNestedDeclarations #10431

Open
andruud opened this issue Jun 12, 2024 · 6 comments
Open

Comments

@andruud
Copy link
Member

andruud commented Jun 12, 2024

This came up when discussing #10389:

It is currently possible to place bare declarations directly in a @scope rule if it's a nested grouping rule:

div {
  @scope (#foo) {
    color: green;
    #bar {
       width: 10px;
    }
    z-index: 42;
  }
}

I think current WPTs (which haven't yet picked up #10234, nor the @nest edit which came before it) require the above to desugar to:

div {
  @scope (#foo) {
    :scope { /* <== The selector and its specificity being the relevant part for this issue */
      color: green;
      z-index: 42;
    }
    #bar {
       width: 10px;
    }
  }
}

(I think per specs that should strictly have been wrapped in a &{} actually, but I apparently forgot to raise an issue for this).

As of #10234, I believe we now intend to desugar to:

div {
  @scope (#foo) {
    /* CSSNestedDeclarations { */
      color: green;
    /* } */
    #bar {
       width: 10px;
    }
    /* CSSNestedDeclarations { */
      z-index: 42;
    /* } */
  }
}

Where the CSSNestedDeclarations rules match whatever #foo matches (but within the scope, obviously), and with ... the same specificity as #foo? It's this specificity part I'm not sure about, as it doesn't seem consistent with how "implied stuff" in @scope is intended to work. For example, the #bar selector effectively gets an implied :where(:scope) selector prepended (#10196), which adds no specificity.

So I wonder if we should specify that CSSNestedDeclarations rules, when the appear directly beneath @scope, should act as :scope {} or :where(:scope) {} rules? (@mirisuzanne)

@mirisuzanne
Copy link
Contributor

Keeping scope consistent, I think we would use :where(:scope) {}, so the resulting specificity is 0,0,1. The only specificity comes from the div.

@andruud
Copy link
Member Author

andruud commented Jun 12, 2024

@mirisuzanne But the innermost rules would get 0,0,0 if we use :where(:scope){}, not 0,0,1. The innermost rules do not "see" the outer div rule. The thing that maintains a connection between div and the innermost rules is the intermediate <scope-start> selector, which gets an implicit & prepended. Inner :scope selectors then match the scoping roots created by that <scope-start>.

@mirisuzanne
Copy link
Contributor

oh, you're right - the result is more like :where(div #foo) rather than div :where(#foo).

Huh, we should likely discuss these two issues together in the group. I think the logic makes good sense at every point along the way, but the zero-specificity result for bare declarations is still a bit surprising. Maybe a fine and reasonable result? But something we should clearly state, and demonstrate in examples.

@mirisuzanne
Copy link
Contributor

Agenda+ to discuss along with #10389 and #9621

@fantasai fantasai changed the title [css-cascade] @scope as a nested grouping rule and CSSNestingDeclarations [css-cascade] @scope as a nested grouping rule and CSSNestedDeclarations Jun 25, 2024
@mirisuzanne
Copy link
Contributor

mirisuzanne commented Jun 25, 2024

The proposal here is to treat directly-nested declarations in a scope rule such that:

  • they apply to the :scope element
  • no specificity is added

That is, as though the declarations are wrapped in :where(:scope) { /* declarations */ }


I would like to resolve all three aspects of this at once if we can:

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-cascade] @scope as a nested grouping rule and CSSNestedDeclarations, and agreed to the following:

  • RESOLVED: bare declarations in a scoped rule apply to the scoped root and add no specificity.
The full IRC log of that discussion <khush> andruud: when a @scope rule is a nested grouping rule we allow bare declarations within its body. Now such declarations should be wrapped in a nested css rule.
<khush> the css nested declarations rule is generally defined to match whatever the parent selector matches
<khush> with same specificity behaviour
<khush> butt this may not make sense for at-scope since it's not how implicit selector stuff works for scope in general
<khush> so we should have nested css declation rule inside nested matches the scoping root with no specificity
<khush> astearns: this matches miriam's proposal?
<matthieud> s/inside nested/inside scope
<khush> miriam: yes. scopes don't add specificicity which matches this. bare declarations in the scope matches the scope root.
<khush> andruud: when it's not nested, it's not allowed. separate open issue
<khush> miriam: this matches previous stamenents. +1
<khush> astearns: from glancing at your last comment, there are other things to resolve on this?
<khush> miriam: they'll fall out so let's be clear.
<khush> one resolution was to serialize the implicit scope but that adds specificity. so we need to change that to work the same way, implicit scope is wrapped in a ware pseudo class which hides the specificity of selectors inside it
<khush> also allow declarations directly inside scope
<khush> astearns: so nested related issues
<khush> miriam: doing all will get consistent behaviour
<khush> astearns: sounds like if we're serializing the bare decls in a scope such that they are wrapped in a ware pseudo?
<khush> andruud: if the ware pseudo is implicitly added it should not be serialized
<khush> astearns: no problem then
<khush> astearns: any other comments?
<matthieud> s/ware/:where
<astearns> :where
<miriam> :where(:scope)
<khush> matthieud: it's not directly related to this issue but in general what's the meaning of something nested in a rule. It's just gonna have specificity of pseudo-class of 1. We need to add specificty of each layer or cascading won'y work
<khush> miriam: it puts the implicit & in the scoped rule. so the scoped root is a nested selector of the parent
<khush> andruud: this is an existing issue?
<khush> matthieud: resolution won't change the behaviour but wanted to bring this up.
<khush> astearns: so should we resolve on what we were first discussing and then go through each implication in turn?
<khush> miriam: not sure how well the resolution is on the issue
<khush> miriam: for this one, where declarations in scope should be treated as a css nested declaration?
<khush> andruud: the where declarations apply to the scoping root with no extra specificity
<khush> astearns: it's not where and bare declarations in the above
<khush> matthieud: do we want specifity of the start or the complete selector which could be more complext
<khush> miriam: scoped root doesn't add specificty, only when you use & or :scope. If you're adding a bare declaration then no specificty added
<khush> astearns: proposed resiltion, bare declarations in a scoped rule apply to the scoped root and add no specificty.
<khush> astearns: objections?
<khush> RESOLVED: bare declarations in a scoped rule apply to the scoped root and add no specificity.
<khush> astearns: other related issues?
<khush> miriam: clarify serialization. we can't serialize it with :scope. Won't do what we just resolved.

mdubet added a commit to mdubet/WebKit that referenced this issue Sep 27, 2024
…where(:scope)

https://bugs.webkit.org/show_bug.cgi?id=280544
rdar://136856371

Reviewed by NOBODY (OOPS!).

w3c/csswg-drafts#10431

* LayoutTests/imported/w3c/web-platform-tests/css/css-nesting/nested-declarations-matching-expected.txt:
* Source/WebCore/style/RuleSetBuilder.cpp:
(WebCore::Style::RuleSetBuilder::addChildRule):
(WebCore::Style::RuleSetBuilder::resolveSelectorListWithNesting):
(WebCore::Style::RuleSetBuilder::addStyleRule):
* Source/WebCore/style/RuleSetBuilder.h:
mdubet added a commit to mdubet/WebKit that referenced this issue Oct 2, 2024
…where(:scope)

https://bugs.webkit.org/show_bug.cgi?id=280544
rdar://136856371

Reviewed by NOBODY (OOPS!).

w3c/csswg-drafts#10431

* LayoutTests/imported/w3c/web-platform-tests/css/css-nesting/nested-declarations-matching-expected.txt:
* Source/WebCore/style/RuleSetBuilder.cpp:
(WebCore::Style::RuleSetBuilder::addChildRule):
(WebCore::Style::RuleSetBuilder::resolveSelectorListWithNesting):
(WebCore::Style::RuleSetBuilder::addStyleRule):
* Source/WebCore/style/RuleSetBuilder.h:
mdubet added a commit to mdubet/WebKit that referenced this issue Oct 2, 2024
…where(:scope)

https://bugs.webkit.org/show_bug.cgi?id=280544
rdar://136856371

Reviewed by NOBODY (OOPS!).

w3c/csswg-drafts#10431

* LayoutTests/imported/w3c/web-platform-tests/css/css-nesting/nested-declarations-matching-expected.txt:
* Source/WebCore/style/RuleSetBuilder.cpp:
(WebCore::Style::RuleSetBuilder::addChildRule):
(WebCore::Style::RuleSetBuilder::resolveSelectorListWithNesting):
(WebCore::Style::RuleSetBuilder::addStyleRule):
* Source/WebCore/style/RuleSetBuilder.h:
mdubet added a commit to mdubet/WebKit that referenced this issue Oct 3, 2024
…where(:scope)

https://bugs.webkit.org/show_bug.cgi?id=280544
rdar://136856371

Reviewed by NOBODY (OOPS!).

w3c/csswg-drafts#10431

This patch maintains a stack during rule set building to be able
to determine whether the closest ancestor rule is a style rule or a scope rule,
and to resolve the nesting parent selector & appropriately (:is(<parent>) or :where(:scope)).

* LayoutTests/imported/w3c/web-platform-tests/css/css-nesting/nested-declarations-matching-expected.txt:
* Source/WebCore/style/RuleSetBuilder.cpp:
(WebCore::Style::RuleSetBuilder::addChildRule):
(WebCore::Style::RuleSetBuilder::resolveSelectorListWithNesting):
(WebCore::Style::RuleSetBuilder::addStyleRule):
* Source/WebCore/style/RuleSetBuilder.h:
webkit-commit-queue pushed a commit to mdubet/WebKit that referenced this issue Oct 3, 2024
…where(:scope)

https://bugs.webkit.org/show_bug.cgi?id=280544
rdar://136856371

Reviewed by Sammy Gill.

w3c/csswg-drafts#10431

This patch maintains a stack during rule set building to be able
to determine whether the closest ancestor rule is a style rule or a scope rule,
and to resolve the nesting parent selector & appropriately (:is(<parent>) or :where(:scope)).

* LayoutTests/imported/w3c/web-platform-tests/css/css-nesting/nested-declarations-matching-expected.txt:
* Source/WebCore/style/RuleSetBuilder.cpp:
(WebCore::Style::RuleSetBuilder::addChildRule):
(WebCore::Style::RuleSetBuilder::resolveSelectorListWithNesting):
(WebCore::Style::RuleSetBuilder::addStyleRule):
* Source/WebCore/style/RuleSetBuilder.h:

Canonical link: https://commits.webkit.org/284635@main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Thursday afternoon
Development

No branches or pull requests

4 participants