csswg-drafts
csswg-drafts copied to clipboard
[css-cascade] Allow declarations directly in @scope?
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.
But would the rule still be present in CSSOM? Or are you proposing that the CSSScopeRule should be able to directly contain declarations?
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.
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.
@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?
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.
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).
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 */ }
}
}
Agenda+ to discuss together with #10431 and #9621
The CSS Working Group just discussed [css-cascade] Allow declarations directly in @scope?, and agreed to the following:
RESOLVED: allow bare declarations in a top level scope rule
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