- From: CSS Meeting Bot via GitHub <sysbot+gh@w3.org>
- Date: Wed, 17 Apr 2024 17:00:50 +0000
- To: public-css-archive@w3.org
The CSS Working Group just discussed `[css-cascade] [css-nesting] Figure out whether we're fine with "shifting up" bare declarations after rules`, and agreed to the following: * `RESOLVED: Tab specs @nest, with a note about user-facing stuff being something we might want to get rid of` <details><summary>The full IRC log of that discussion</summary> <emilio> TabAtkins: So, background... current spec for nesting allows you to interleave declarations with rules<br> <emilio> ... the way it's handled in the syntax spec is that all the declarations get collected together<br> <emilio> ... losing the order information relative to the rules<br> <emilio> ... this appears to cause author confusion<br> <emilio> ... particularly if you repeat the same declaration a few times between things<br> <emilio> ... it also means that whenever we introduce mixins, the ability to make it work with nesting doesn't work well<br> <emilio> ... so thought was, can we instead interpret declarations in between rules as if they were wrapped in another rule<br> <emilio> ... it interacts nicely with cssRules etc<br> <emilio> ... andruud added use counters and it seems it can probably be made<br> <lea> q?<br> <lea> q+<br> <emilio> ... I proposed the change in the comment from the agenda<br> <kbabbitt> q+<br> <lea> q-<br> <lea> q+<br> <emilio> ... basically collect declarations into a new type of atrule (tentative name `@nest`)<br> <emilio> ... `@nest` doesn't do anything other than grouping the declarations<br> <emilio> ... This is slightly different to wrapping the parent selector<br> <emilio> ... So it improves our behavior when nesting declarations inside media queries<br> <emilio> q+<br> <emilio> ... everyone seemed happy with it, only q was about serialization which we'd move to a different issue<br> <emilio> ... authors can write it but it's not particularly useful for them to do so<br> <emilio> astearns: before going to the queue, wanna say that we only need to resolve on the approach<br> <astearns> ack kbabbitt<br> <emilio> kbabbitt: a little uncertain about how this interact with the OM<br> <kbabbitt> .rule1 { font-family: serif; color: blue; }<br> <emilio> ... was playing with an example<br> <kbabbitt> .rule2 { font-family: serif; @media (...) { ... } color: blue; }<br> <emilio> ... if I do setProperty("color", "red")<br> <emilio> ... does it know how to dig inside @nest?<br> <emilio> ... or ends up not having an effect<br> <emilio> TabAtkins: the later<br> <emilio> kbabbitt: that's a bit concerning<br> <emilio> ... in this world setProperty I added an @media and suddenly that doesn't work anymore<br> <emilio> TabAtkins: I agree you can run into potentially confusing situations with this<br> <emilio> ... but it's not incompatible with current usage<br> <matthieud> q+<br> <astearns> ack lea<br> <TabAtkins> scribe+ TabAtkins<br> <TabAtkins> emilio: It is unfortunate that that woudl stop working, but it's also a tradeoff that seems hard to avoid<br> <TabAtkins> emilio: In the ame example, if you set color in both locations, and you wanted to *keep* both color declarations (which is what needs to happen here), it becomes..<br> <TabAtkins> emilio: Like, maybe you can discard the previous somehow. But if you want to keep the altter decl you need a place to store it.<br> <TabAtkins> emilio: So it seems hard to avoid unless we do even more invasive changes to the OM, like letting you represent both declarations and rules directly<br> <TabAtkins> emilio: Not convinced that's worth it<br> <TabAtkins> emilio: I also think we generally discourage mutations in CSSOM when they affect stylesheets.<br> <TabAtkins> emilio: Doing so has pretty bad perf implications, it dedups shared/cached stylesheets.<br> <TabAtkins> emilio: So not sure it's worth rejiggering to "fix" this case<br> <TabAtkins> emilio: If you wrapped the decl in a *different* rule, it would also not be changed by setProperty()<br> <TabAtkins> kevin: to be clear, in my example the decl isn't in the @media<br> <TabAtkins> emilio: Right, just saying that it's in an @nest, and if it were any other rule it woudlnt' be surprising<br> <TabAtkins> kevin: just concerned that adding an @media in the middle of a rule causes the beahvior to change<br> <TabAtkins> matthieud: In the issue we discussed using cssstyledeclaration, and that woudl avoid the issue<br> <TabAtkins> emilio: That wouldn't fix this, you'd need the exact same logic to find the "correct" cssstyledeclaration to mutate<br> <TabAtkins> lea: what if we have the proeprty there but it's not enumerable<br> <TabAtkins> lea: Like a property that gives you all the decls, and a non-enumerable getter that gives you non-interleaved properties<br> <TabAtkins> lea: So normally you'd get the first set, but if you want to read a specific proeprty you'd just all of them from @nests<br> <TabAtkins> emilio: What if you have multiple?<br> <TabAtkins> emilio: I agree that this setProperty() breakage is somewhat surprising/unfortunate. I don't see a great way of avoiding it.<br> <TabAtkins> lea: I think we could design it to minimize the surprise<br> <TabAtkins> q+<br> <TabAtkins> lea: but we can't do this during the call<br> <dbaron> Is the behavior either with or without this change bad enough that CSS style guides will generally say not to use the interleaving feature (i.e., say to put all the declarations first)?<br> <TabAtkins> lea: reading properties should work, and there's an unambiguous value for each property, reading them shoudl give you correct<br> <TabAtkins> That's gonna be what I'm gonna say when I get to my q entry<br> <TabAtkins> emilio: I don't think it's worth complicating the OM substantially. The implicit rule is already magic, I don't want more.<br> <TabAtkins> emilio: This is pretty fundamental to what we're dsicussing. If we want the latter rules to act liek rules...<br> <lea> +1 for the proposed solution in general. Even though I do feel pretty strongly about the serialization issue, I think it's far better than the current situation _regardless_ of how serialization ends up working, so I think we should try to implement it asap before the current behavior starts being depended on. Far easier to change the serialization than how interleaved rules and declarations behave.<br> <dbaron> s/+1 for/lea: +1 for/<br> <lea> To summarize the serialization issue, these rules are added magically to author code, so I think when serialized they should also be removed magically, so that author code can roundtrip better. This would mean somewhat surprising behavior in the extremely rare cases where authors actually wrote an @nest rule, but far less surprising in the huge majority of cases where authors did not actually write it.<br> <lea> But perhaps more fundamental to the design of this feature, if authors have no reason to write it, should they even be able to? If not, that entirely solves the serialization issue, since we never need to handle it and it becomes a CSS OM detail rather than an actual CSS syntax feature.<br> <lea> We may also want to consider adding a new CSS OM property to get *all* declarations, including the interleaved ones.<br> <emilio> s/But/lea: But<br> <emilio> q+<br> <lea> dbaron: I don't think so, especially if we design the CSS OM so that it works in the largest possible set of cases<br> <dbaron> s/dbaron:/dbaron,/<br> <emilio> emilio: You'd still need to come up with something to return from CSSNestRule.cssText or what not<br> <astearns> ack emilio<br> <emilio> ... I think I'd rather avoid trying to hide the fact that we implicitly add this rule<br> <emilio> ... otherwise this kind of complexity proliferates and causes tons of edge cases everywhere that are bad for both authors end browser developers<br> <astearns> ack matthieud<br> <emilio> matthieud: In general I don't think we need @nest<br> <emilio> ... because we don't want authors to actually use it<br> <emilio> ... it's just an implementation detail<br> <emilio> ... all these serialization questions would go away if we didn't put it on the spec<br> <emilio> ... one solution would be to be able to use multiple CSSStyleDeclarations<br> <emilio> ... I think modifying CSSOM is a better solution<br> <emilio> q+<br> <lea> q+<br> <emilio> ... adding a new at-rule that we don't want authors to be using is a good solution<br> <emilio> ... I think it's pretty fundamental to this approach<br> <emilio> ... I think the question is do we add a new atrule or not<br> <emilio> ... the setProperty issue is less of an issue<br> <dholbert> emilio: [missed scribing]<br> <dholbert> scribe+ dholbert<br> <dholbert> emilio: I think the at-rule is the most obvious path forward to fix this<br> <dholbert> ... I think it's weird but it's the most obvious weirdness that we don't have to propagate to everywhere else<br> <dholbert> ... I don't see how a different approach fixes the annoyances it'd introduce, without massive redesign work<br> <lea> emilio you said an @rule can be implemented quickly. Would a CSS OM rule type that doesn't correspond to an actual syntactic rule take longer to implement?<br> <emilio> s/[missed scribing]/Multiple CSSStyleDeclarations don't fix any of the weirdness that @nest introduces<br> <lea> q?<br> <emilio> ack emilio<br> <astearns> ack TabAtkins<br> <emilio> lea: somewhat? I don't think we have a precedent for anything like that<br> <emilio> TabAtkins: what's being brought up is about what's more convenient or predictable when reading and modifying the OM<br> <emilio> ... when is that done, compared to writing CSS<br> <emilio> ... tool writers do<br> <lea> qq+ to reply to Tab<br> <emilio> ... but for anything that's not doing that specific thing, the most I've seen anybody do is copying stylesheets around<br> <matthieud> q+<br> <emilio> ... so actually modifying the OM is really rare<br> <emilio> ... so any complexity we introduce there needs to be weighted against the relatively small audience<br> <emilio> ... also, when I do this kind of thing I value more consistency / predictability<br> <dbaron> (does writing of polyfills tend to touch the OM, or just reparse everything from scratch?)<br> <emilio> ... vs. convenient APIs<br> <lea> dbaron, depends on the polyfill and how closely it tries to follow the actual syntax<br> <emilio> ... I think the @nest proposal keeps consistency for CSSOM<br> <emilio> ... anyways, let's resolve on keeping styles where they are<br> <emilio> ... I need to write _something_<br> <emilio> ... can't go "do this in an unspecified way"<br> <emilio> ... unless anybody has a strong objection right now my plan is to put the proposal on the spec, open to change<br> <emilio> ack lea<br> <Zakim> lea, you wanted to react to TabAtkins to reply to Tab<br> <astearns> ack lea<br> <lea> Lea: Tab, it's true that tool writers are a tiny minority of authors, but breaking tools has huge impact on authors, since a lot more authors _use_ tools than _write_ tools.<br> <lea> Lea: To reply to Emilio’s earlier point, I think there is an underlying design principles issue. I don't think avoiding magic at all costs should be a goal; the right magic can make a huge usability difference, at the cost of implementation complexity. Magic becomes a problem when it's unpredictable for users, and/or when users cannot opt-out of it. Neither seems to be the case here (at least if we design this right).<br> <lea> Lea: There one thing that is crucial to understand, emilio you said an @rule can be implemented quickly. Would a CSS OM rule type that doesn't correspond to an actual syntactic rule take longer to implement? Cause I agree we should contain the weirdness, not making this part of CSS syntax is a way to do that. Cause if authors _can_ write it, they will.<br> <dholbert> emilio: replying directly to that... then, you need to figure out all the APIs that are on CSSRule that... people expect to be able to call Stylesheet.insertRule, rule.cssText<br> <dholbert> emilio: if that rule can't be written by authors, what does that do?<br> <dholbert> lea: what is the reason to do insertRule in that case?<br> <dholbert> emilio: if you're writing a tool that wants to move rules around. that's the consistency argument that TabAtkins was talking about<br> <TabAtkins> Yup, having *one* object that acts differently from everything else inside of .cssRules is generally bad (and needs a fairly significatn justification to break)<br> <dholbert> emilio: if I want to filter the set of rules on a stylesheet and put them on another stylesheet, it seems reasonable that you'd be able to call insertRule with the cssText of every stylesheet you care about, but that doesn't work<br> <dholbert> lea: why does that need @nest { ...declarations...}?<br> <dholbert> emilio: that's not a rule<br> <dholbert> TabAtkins: that today would fail to parse. Would be a potential compat impact if we were to make that suddenly valid<br> <dholbert> matthieud: why would we use insertRule to insert declarations anyway?<br> <dholbert> emilio: you'd use it to insert a nested rule<br> <astearns> ack matthieud<br> <dholbert> lea: we do want to be able to use CSSOM to insert interleaved rules, so that does seem like a problem<br> <emilio> matthieud: I agree CSSOM is a very small audience<br> <emilio> ... we should not introduce new complexity in the CSS spec<br> <emilio> ... for that<br> <emilio> ... only modifying CSSOM is less invasive<br> <astearns> ack fantasai<br> <emilio> ... if you create new @-rules, then we need to explain it to all authors<br> <emilio> fantasai: wondering if it'd make sense to use the nesting at-rule concept in CSSOM but only in the OM, and stripping it out for serialization, and also have the first rule be represented in the same manner?<br> <lea> To summarize my position: 1. Ideally, @nest should only exist in the CSS OM, and insertRule() should accept raw decls 2. If that's not possible, then serialization should strip @nest 3. But even if @nest has to be serialized, that's still better than hoisting.<br> <emilio> ... so it'd be in .style and .cssRules[0].style<br> <emilio> TabAtkins: duplicating them would be inconsistent<br> <emilio> TabAtkins: @page does have declarations and rules<br> <emilio> matthieud: font-feature-values could take various at-rules and then a nested declaration<br> <emilio> q+<br> <astearns> ack emilio<br> <dholbert> emilio: the other option, a bit less weird perhaps, is:<br> <dholbert> emilio: so right now, we're using this trick of a style rule with the & selector<br> <dholbert> emilio: the idea behind @nest or whatever the name ends up being, would effectively be wrapping it in a style rule with a magic selector that represents the parent<br> <lea> q+<br> <dholbert> emilio: @nest is conceptually a style rule with a magic selector that doesn't get wrapped<br> <dholbert> emilio: we could define such magic selector somehow<br> <dholbert> emilio: would that make people less worried about the OM shenanigans?<br> <dholbert> TabAtkins: that wouldn't fix the problems that were brought up<br> <kbabbitt> q=<br> <kbabbitt> q+<br> <dholbert> emilio: it would behave like @nest, and like bare declarations in @media. So less breaking change than what we've been discussing<br> <dholbert> TabAtkins: every issue discussed has been from being in a rule of *any* kind<br> <dholbert> emilio: it doesn't happen if it's a style rule... I guess we need to explain the new selector<br> <dholbert> TabAtkins: that sounds even more magical<br> <dholbert> emilio: just wondering if it would be more amenable. But I think @nest is the best solution, given the constraints. Just curious if people would prefer putting the magic in the selector list rather than the at-rule. But I don't mind either way<br> <astearns> ack lea<br> <lea> Lea: Do note that this does not need to be set in stone, we can implement it as a hidden CSS OM rule type to minimize API surface and fix the immediate problem, and figure out how things like insertRule() would work later — and if we can't, we just promote it to a regular rule. But it's much harder to go the other way<br> <astearns> +1 to start with the least user-facing change<br> <emilio> kbabbitt: I do agree that we need some kind of a solution, and I think @nest is better than the status quo<br> <emilio> kbabbitt: IIUC what emilio was proposing was making @nest explicitly with some sort of selector, it feels less magical<br> <emilio> ... it doesn't solve the setProperty issue but it makes it so that if you have to confront that it becomes obvious<br> <fantasai> +1 to lea<br> <lea> +1 to astearns<br> <ydaniv> +1 to both<br> <emilio> astearns: does it sound reasonable to make @nest {} as a magic thing that authors can't write?<br> <emilio> lea: wasn't it what matthieud proposed?<br> <emilio> matthieud: I was proposing using CSSStyleDeclaration<br> <lea> s/astearns: does it sound reasonable to make @nest {} as a magic thing that authors can't write?/astearns: does it sound reasonable to make @nest {} as a magic thing that authors can't write for now?/<br> <emilio> ... but this sounds a bit in the middle<br> <emilio> TabAtkins: if we make @nest parse invalid we can't round-trip<br> <emilio> ... anything we do here has significant complexity that makes corners of stuff behave weirdly<br> <emilio> astearns: your point was that this wasn't affecting authors much<br> <lea> Yes, the idea was there would be no @nest in serialization for now<br> <emilio> TabAtkins: it does because we need to define @nest to not serialize<br> <emilio> lea: the idea is to make @nest not serialize<br> <dholbert> emilio: I agree with TabAtkins for what it's worth<br> <emilio> ... if we settle on @nest then we switch to serialize it<br> <lea> straw poll?<br> <oriol> +1 to Tab and emilio<br> <dholbert> emilio: doing this in two steps that can break code seems unnecessary<br> <emilio> TabAtkins: really strongly against extra magic other than in parsing<br> <emilio> ... unless there's a great argument for that, but I haven't heard one<br> <emilio> ... the more changes we make here the more potential there is for compat risk<br> <kbabbitt> ack kbabbitt<br> <emilio> TabAtkins: I'm close to objecting to things that put lots of magic in the CSSOM<br> <emilio> ... the less magic is CSSStyleDeclaration<br> <emilio> lea: I think it's great, we have that object already<br> <dholbert> emilio: I disagree. how can you make CSS Rules return something that isn't a CSS Rule?<br> <dholbert> lea: cssstyledeclaration is the least surprising option. it already exists and fits this perfectly<br> <dholbert> emilio: I disagree. Every time we introduce an @ rule, it causes things that [...]<br> <dholbert> lea: can we resolve that TabAtkins can scribe whatever makes him happy, and we see if we can resolve on it?<br> <emilio> lea: can we resolve on TabAtkins writing whatever he wants and prioritizing next steps on follow-up calls?<br> <dholbert> TabAtkins: sounds good to me<br> <lea> s/and we see if we can resolve on it?/and prioritize resolving on the additional issues ASAP, next week if possible?/<br> <emilio> fantasai: we'd like not to introduce @nest as an author-facing constructs<br> <lea> might be useful to do the straw poll anyway to get a sense of what people think, even if it doesn't guide the resolution<br> <emilio> ... if this is a temporary step towards that then fine but...<br> <emilio> astearns: Proposed: Let tab spec whatever, but note that user-facing @nest is something we want to get rid of<br> <emilio> objections?<br> <emilio> RESOLVED: Tab specs @nest, with a note about user-facing stuff being something we might want to get rid of<br> <lea> TabAtkins please add mention the unresolved issues in the draft?<br> <lea> s/add mention/mention/<br> <fantasai> s/user-facing stuff/@nest rules as a usable syntactic construct/<br> </details> -- GitHub Notification of comment by css-meeting-bot Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/8738#issuecomment-2061777236 using your GitHub account -- Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Wednesday, 17 April 2024 17:00:51 UTC