- From: Dael Jackson <daelcss@gmail.com>
- Date: Wed, 17 Apr 2024 19:41:48 -0400
- To: www-style@w3.org
=========================================
These are the official CSSWG minutes.
Unless you're correcting the minutes,
Please respond by starting a new thread
with an appropriate subject line.
=========================================
CSS Cascade & Nesting
---------------------
- TabAtkins introduced the proposal for issue #8738 (Figure out
whether we're fine with "shifting up" bare declarations after
rules) and proposed moving serialization into a separate issue
- There were some concerns raised about author confusion given that
it's easy to make a small change that would alter behavior.
- The proposal was viewed as an improvement over the current spec
text and there was a desire to make a change now before the
current spec text becomes relied upon by authors.
- The group discussed the likelihood of this being used by authors
and the value of having it as something an author (especially in
a tooling use case) could access vs the value of having
well-defined and predictable magic.
- Though there was some pushback to magic, the principle of taking
the least user-facing approach had wide agreement.
- RESOLVED: Tab specs @nest, with a note about @nest rules as a
usable syntactic construct being something we might want
to get rid of (Issue #8738)
===== FULL MEETING MINUTES ======
Agenda: https://lists.w3.org/Archives/Public/www-style/2024Apr/0003.html
Present:
Rachel Andrew
David Baron
Kevin Babbitt
Oriol Brufau
Stephen Chenney
Keith Cirkel
Emilio Cobos Álvarez
Yehonatan Daniv
Matthieu Dubet
Elika Etemad
Paul Grenier
Robert Flack
Chris Harrelson
Daniel Holbert
Brian Kardell
Brad Kemper
Jonathan Kew
David Leininger
Vladimir Levin
Alison Maher
Romain Menke
Miriam Suzanne
Bramus Van Damme
Lea Verou
Chair: astearns
Scribe: emilio
Scribe's scribes: TabAtkins & dholbert
CSS Cascade & Nesting
=====================
Figure out whether we're fine with "shifting up" bare declarations
after rules
------------------------------------------------------------------
github: https://github.com/w3c/csswg-drafts/issues/8738#issuecomment-2057868087
TabAtkins: So, background... current spec for nesting allows you to
interleave declarations with rules
TabAtkins: The way it's handled in the syntax spec is that all the
declarations get collected together
TabAtkins: losing the order information relative to the rules
TabAtkins: This appears to cause author confusion
TabAtkins: particularly if you repeat the same declaration a few
times between things
TabAtkins: It also means that whenever we introduce mixins, the
ability to make it work with nesting doesn't work well
TabAtkins: so thought was, can we instead interpret declarations in
between rules as if they were wrapped in another rule
TabAtkins: it interacts nicely with cssRules etc
TabAtkins: andruud added use counters and it seems it can probably be
made
TabAtkins: I proposed the change in the comment from the agenda
TabAtkins: Basically collect declarations into a new type of atrule
(tentative name `@nest`)
TabAtkins: `@nest` doesn't do anything other than grouping the
declarations
TabAtkins: This is slightly different to wrapping the parent selector
TabAtkins: So it improves our behavior when nesting declarations
inside media queries
TabAtkins: Everyone seemed happy with it, only question was about
serialization which we'd move to a different issue
TabAtkins: Authors can write it but it's not particularly useful for
them to do so
astearns: Before going to the queue, wanna say that we only need to
resolve on the approach
kbabbitt: A little uncertain about how this interact with the OM
kbabbitt: was playing with an example
<kbabbitt> .rule1 { font-family: serif; color: blue; }
<kbabbitt> .rule2 { font-family: serif; @media (...) { ... } color:
blue; }
kbabbitt: If I do setProperty("color", "red")
kbabbitt: does it know how to dig inside @nest?
kbabbitt: or ends up not having an effect
TabAtkins: The latter
kbabbitt: That's a bit concerning
kbabbitt: In this world setProperty I added an @media and suddenly
that doesn't work anymore
TabAtkins: I agree you can run into potentially confusing situations
with this
TabAtkins: but it's not incompatible with current usage
emilio: It is unfortunate that that would stop working, but it's also
a tradeoff that seems hard to avoid
emilio: In the same 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...
emilio: Like, maybe you can discard the previous somehow. But if you
want to keep the latter declaration you need a place to store
it.
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
emilio: Not convinced that's worth it
emilio: I also think we generally discourage mutations in CSSOM when
they affect stylesheets.
emilio: Doing so has pretty bad perf implications, it dedups shared/
cached stylesheets.
emilio: So not sure it's worth rejiggering to "fix" this case
emilio: If you wrapped the decl in a *different* rule, it would also
not be changed by setProperty()
kbabbitt: To be clear, in my example the decl isn't in the @media
emilio: Right, just saying that it's in an @nest, and if it were any
other rule it wouldn't be surprising
kbabbitt: Just concerned that adding an @media in the middle of a
rule causes the behavior to change
matthieud: In the issue we discussed using cssstyledeclaration, and
that would avoid the issue
emilio: That wouldn't fix this, you'd need the exact same logic to
find the "correct" cssstyledeclaration to mutate
lea: What if we have the property there but it's not enumerable
lea: Like a property that gives you all the decls, and a
non-enumerable getter that gives you non-interleaved properties
lea: So normally you'd get the first set, but if you want to read a
specific property you'd just all of them from @nests
emilio: What if you have multiple?
emilio: I agree that this setProperty() breakage is somewhat
surprising/unfortunate. I don't see a great way of
avoiding it.
lea: I think we could design it to minimize the surprise
lea: but we can't do this during the call
lea: reading properties should work, and there's an unambiguous value
for each property, reading them should give you correct
emilio: I don't think it's worth complicating the OM substantially.
The implicit rule is already magic, I don't want more.
emilio: This is pretty fundamental to what we're discussing. If we
want the latter rules to act like rules...
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.
<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.
<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.
<lea> We may also want to consider adding a new CSS OM property to
get *all* declarations, including the interleaved ones.
emilio: You'd still need to come up with something to return from
CSSNestRule.cssText or what not
emilio: I think I'd rather avoid trying to hide the fact that we
implicitly add this rule
emilio: otherwise this kind of complexity proliferates and causes
tons of edge cases everywhere that are bad for both authors
end browser developers
<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)?
<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
matthieud: In general I don't think we need @nest
matthieud: because we don't want authors to actually use it
matthieud: it's just an implementation detail
matthieud: all these serialization questions would go away if we
didn't put it on the spec
matthieud: One solution would be to be able to use multiple
CSSStyleDeclarations
matthieud: I think modifying CSSOM is a better solution
matthieud: Adding a new at-rule that we don't want authors to be
using is a good solution
matthieud: I think it's pretty fundamental to this approach
matthieud: I think the question is do we add a new at-rule or not
matthieud: the setProperty issue is less of an issue
emilio: Multiple CSSStyleDeclarations don't fix any of the weirdness
that @nest introduces
emilio: I think the at-rule is the most obvious path forward to fix
this
emilio: I think it's weird but it's the most obvious weirdness that
we don't have to propagate to everywhere else
emilio: I don't see how a different approach fixes the annoyances
it'd introduce, without massive redesign work
<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?
emilio: lea, somewhat? I don't think we have a precedent for anything
like that
TabAtkins: What's being brought up is about what's more convenient or
predictable when reading and modifying the OM
TabAtkins: when is that done, compared to writing CSS
TabAtkins: tool writers do
TabAtkins: but for anything that's not doing that specific thing, the
most I've seen anybody do is copying stylesheets around
TabAtkins: so actually modifying the OM is really rare
TabAtkins: so any complexity we introduce there needs to be weighted
against the relatively small audience
TabAtkins: also, when I do this kind of thing I value more
consistency / predictability
TabAtkins: vs. convenient APIs
TabAtkins: I think the @nest proposal keeps consistency for CSSOM
TabAtkins: Anyways, let's resolve on keeping styles where they are
TabAtkins: I need to write _something_
TabAtkins: can't go "do this in an unspecified way"
TabAtkins: unless anybody has a strong objection right now my plan is
to put the proposal on the spec, open to change
<dbaron> (does writing of polyfills tend to touch the OM, or just
reparse everything from scratch?)
<lea> dbaron, depends on the polyfill and how closely it tries to
follow the actual syntax
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.
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).
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.
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
emilio: If that rule can't be written by authors, what does that do?
lea: What is the reason to do insertRule in that case?
emilio: If you're writing a tool that wants to move rules around.
that's the consistency argument that TabAtkins was talking
about
<TabAtkins> Yup, having *one* object that acts differently from
everything else inside of .cssRules is generally bad (and
needs a fairly significant justification to break)
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
lea: Why does that need @nest { ...declarations...}?
emilio: That's not a rule
TabAtkins: That today would fail to parse. Would be a potential
compat impact if we were to make that suddenly valid
matthieud: Why would we use insertRule to insert declarations anyway?
emilio: You'd use it to insert a nested rule
lea: We do want to be able to use CSSOM to insert interleaved rules,
so that does seem like a problem
matthieud: I agree CSSOM is a very small audience
matthieud: We should not introduce new complexity in the CSS spec
matthieud: for that
matthieud: only modifying CSSOM is less invasive
matthieud: If you create new @-rules, then we need to explain it to
all authors
<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.
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?
fantasai: so it'd be in .style and .cssRules[0].style
TabAtkins: Duplicating them would be inconsistent
TabAtkins: @page does have declarations and rules
matthieud: font-feature-values could take various at-rules and then a
nested declaration
emilio: The other option, a bit less weird perhaps, is:
emilio: so right now, we're using this trick of a style rule with the
& selector
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
emilio: @nest is conceptually a style rule with a magic selector that
doesn't get wrapped
emilio: we could define such magic selector somehow
emilio: Would that make people less worried about the OM shenanigans?
TabAtkins: That wouldn't fix the problems that were brought up
emilio: It would behave like @nest, and like bare declarations in
@media. So less breaking change than what we've been
discussing
TabAtkins: Every issue discussed has been from being in a rule of
*any* kind
emilio: It doesn't happen if it's a style rule... I guess we need to
explain the new selector
TabAtkins: That sounds even more magical
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
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
<astearns> +1 to start with the least user-facing change
kbabbitt: I do agree that we need some kind of a solution, and I
think @nest is better than the status quo
kbabbitt: IIUC what emilio was proposing was making @nest explicitly
with some sort of selector, it feels less magical
kbabbitt: It doesn't solve the setProperty issue but it makes it so
that if you have to confront that it becomes obvious
<fantasai> +1 to lea
<lea> +1 to astearns
<ydaniv> +1 to both
astearns: Does it sound reasonable to make @nest {} as a magic thing
that authors can't write for now?
lea: Wasn't it what matthieud proposed?
matthieud: I was proposing using CSSStyleDeclaration
matthieud: but this sounds a bit in the middle
TabAtkins: If we make @nest parse invalid we can't round-trip
TabAtkins: Anything we do here has significant complexity that makes
corners of stuff behave weirdly
astearns: Your point was that this wasn't affecting authors much
TabAtkins: It does because we need to define @nest to not serialize
lea: Yes, the idea was there would be no @nest in serialization
for now
emilio: I agree with TabAtkins for what it's worth
emilio: if we settle on @nest then we switch to serialize it
<lea> straw poll?
<oriol> +1 to Tab and emilio
emilio: doing this in two steps that can break code seems unnecessary
TabAtkins: Really strongly against extra magic other than in parsing
TabAtkins: unless there's a great argument for that, but I haven't
heard one
TabAtkins: the more changes we make here the more potential there is
for compat risk
TabAtkins: I'm close to objecting to things that put lots of magic in
the CSSOM
TabAtkins: the less magic is CSSStyleDeclaration
lea: I think it's great, we have that object already
emilio: I disagree. how can you make CSS Rules return something that
isn't a CSS Rule?
lea: cssstyledeclaration is the least surprising option. it already
exists and fits this perfectly
emilio: I disagree. Every time we introduce an @ rule, it causes
things that [...]
lea: Can we resolve that TabAtkins can write whatever makes him
happy, and prioritize resolving on the additional issues ASAP,
next week if possible?
TabAtkins: sounds good to me
fantasai: We'd like not to introduce @nest as an author-facing
constructs
fantasai: if this is a temporary step towards that then fine but...
<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
astearns: Proposed: Let tab spec whatever, but note that user-facing
@nest is something we want to get rid of
astearns: Objections?
RESOLVED: Tab specs @nest, with a note about @nest rules as a usable
syntactic construct being something we might want to get
rid of
<lea> TabAtkins please mention the unresolved issues in the draft?
Received on Wednesday, 17 April 2024 23:42:20 UTC