w3c / csswg-drafts

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

[css-cascade] Allow declarations directly in @scope? #10389

Open andruud opened 1 month ago

andruud commented 1 month ago

Currently, @scope only accepts rules in its body. If you want to apply something to the scoping root itself, you need to use a :scope rule:

@scope (div) {
  :scope {
    color: green;
  }
}

However, ever since relaxed nesting was introduced (where we first try to parse something as a declaration, and otherwise try it as a nested rule), we should be unblocked if we wanted to support direct declarations in the rule.

Loirooriol commented 1 month ago

But would the rule still be present in CSSOM? Or are you proposing that the CSSScopeRule should be able to directly contain declarations?

andruud commented 1 month ago

But would the rule still be present in CSSOM?

Yeah, we do roughly the same thing as what came out of https://github.com/w3c/csswg-drafts/issues/8738 / https://github.com/w3c/csswg-drafts/issues/10234, where we wrap each block of declarations in a rule, probably a :scope{} rule in this case.

mirisuzanne commented 4 weeks ago

I think the main source of confusion here would be determining the specificity. Currently these have different specificities:

@scope (#foo) {
  p { /* 0,0,1 */ }
  :scope p { /* 0,1,1 */ }
  & p { /* 1,0,1 */ }
}

That's already somewhat confusing, since :scope p and p have identical behavior. When you remove the nested p and consider :scope vs bare declarations (with implied-:scope), it should likely have the same specificity implications? 0,1,0 vs 0,0,0?

I don't know if that causes round-trip issues when captured in CSSOM.

andruud commented 3 weeks ago

@mirisuzanne Yeah, true. We already have this problem when the @scope is a nested group rule, though:

div {
  @scope (#foo) {
    color: green; /* Specificity=? */
  }
}

(To be clear, the above is already valid today).

it should likely have the same specificity implications? 0,1,0 vs 0,0,0?

So you're expecting 0,0,0 here, right?

mirisuzanne commented 3 weeks ago

So you're expecting 0,0,0 here, right?

That's both my expectation, and a somewhat surprising result.

color: green; / Specificity=? /

This would be 0,0,1 - a bit less surprising to me.

andruud commented 3 weeks ago

This would be 0,0,1 - a bit less surprising to me.

No, keep in mind that the <scope-start> selector acts as the parent rule for &here. So per spec this is 1,0,1. (Warning: not what Blink actually does).

mirisuzanne commented 3 weeks ago

Sorry, some confusion here in the back-and-forth. I think we've landed on an answer in the attached issue. The implicit prefix when nesting in @scope is similar to :where(:scope) - so the resulting specificity is:


div { /* the div is merged into <scope-start> as though `& #foo` */
  @scope (#foo) {
    color: blue; /* 0,0,0 */

    p { /* 0,0,1 */ }
    :scope p { /* 0,1,1 */ }
    & p { /* 1,0,1 */ }
  }
}
mirisuzanne commented 3 weeks ago

Agenda+ to discuss together with #10431 and #9621

css-meeting-bot commented 3 days ago

The CSS Working Group just discussed [css-cascade] Allow declarations directly in @scope?, and agreed to the following:

The full IRC log of that discussion <khush> miriam: we just said that when scope is nested, we can put bare decls inside of it. scope is a bit different from other at-rules in that it changes the selector somewhat and has own selector built-in.
<khush> so we could allow bar declarations at any level it doesn't need to nested
<khush> so we could say this is also allowed when its not nested
<khush> matthieud: allowing declarations inside of scoped rule which are top level?
<khush> miriam: yup
<khush> i don't feel strongly about it but feels consistent if we allow in nested situations. so why not root?
<khush> andruud: agreed would be weird
<khush> also part of the reason to not do initially was we din't jhave relaxed nesting. so couldn't distinguish between selectors starting with tag names
<khush> astearns: +1
<khush> astearns: anyone needs time before resolving?
<khush> proposed resolution: allow bare declarations in a top level scope rule.
<khush> matthieud: in the cssom the declarations will be represented by a rule in a CSSNestedRule object?
<khush> andruud: yes
<khush> astearns: objections?
<khush> RESOLVED: allow bare declarations in a top level scope rule
<khush> miriam: if someone screams, we can revisit
<khush> matthieud: happy to discuss the other issue you mentioned