- From: Dael Jackson <daelcss@gmail.com>
- Date: Thu, 6 Apr 2023 13:09:41 -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 Nesting Breakout
--------------------
- RESOLVED: Redefine CSSRuleList as ObservableArray (Issue #8350:
Consider using ObservableArray<CSSRule> instead of
CSSRuleList)
- TabAtkins will file issue about CSSStyleDeclaration's array upgrade
- RESOLVED: If naked property declarations inside @media become a
thing, they are wrapped in a & {} rule (Issue #7850:
CSSOM for nested media query rules)
- fremy or plinss will file issue about whether naked declarations
get sorted to the top of the list or not
- RESOLVED: Close no change (Issue #7803: Nesting conditional rules)
- We will retain the bare & supports strategy in the spec (Issue
#8399: Feature detection for nesting)
- The lookahead proved viable for issue #8249 (Problem with mixing
properties and selectors). Discussion will continue on github as
to the final decision between the provided options.
===== FULL MEETING MINUTES ======
Agenda: https://github.com/w3c/csswg-drafts/issues?q=is%3Aopen+is%3Aissue+label%3AAgenda%2B+label%3Acss-nesting-1
Present:
Tab Atkins
Emilio Cobos Álvarez
Tantek Çelik
Matthieu Dubet
Elika Etemad
Daniel Holbert
Brad Kemper
Peter Linss
Eric Meyer
François Remy
Cassondra Roberts
Jen Simmons
Alan Stearns
Regrets:
Lea Verou
Chair: astearns
Scribe: fantasai
Scribe's scribe: emeyer
CSS Nesting
===========
Consider using ObservableArray<CSSRule> instead of CSSRuleList
--------------------------------------------------------------
github: https://github.com/w3c/csswg-drafts/issues/8350
TabAtkins: Domenic raised the fact that CSSStyleRule has a new ??
TabAtkins: it's the weird legacy CSSRuleList
TabAtkins: which is a weird old DOM interface that pretends to be a
list, but very awkwardly
TabAtkins: Suggested to use ObservableArray, which can reproduce
behavior
TabAtkins: and we can subclass it stuff
TabAtkins: I would like to be good, but I would like to be consistent
TabAtkins: so if we do this, we should do it by creating a subclass
that adds all the legacy interfaces
TabAtkins: and do it throughout the CSSOM
astearns: So on other places where we use CSSRuleList, that would
result in some extra things that you currently can't do
with those objects?
TabAtkins: so we would need tests for all this
TabAtkins: Yes, all of the array methods, which don't exist on
CSSRuleList, would start showing up there
TabAtkins: need tests that we're not doing the weird things
astearns: [missed]
fantasai: Are you going to redefine CSS rule list or something else?
TabAtkins: Redefining CSSRuleLIst
TabAtkins: I will make it a subclass of ObservableArray
<fantasai> sgtm
fremy: Mainly had a question about CSSRuleLIst, right now can you
modify it?
fremy: I thought it was a readonly array
fremy: ObservableArray is read-write
TabAtkins: That's something that we can define
TabAtkins: make sure that the readonly bits throw on the setting
they're deleting
fremy: Why Observable if it's readonly?
TabAtkins: ObservableArray is how we should do arrays generally
TabAtkins: plain array supposed to be static, not invisibly modified
by the browser
TabAtkins: ObservableArray allows modification underneath
fremy: ah, ok
TabAtkins: Browser doing Observing, which can go both ways
heycam: This might be first one where API would allow script to
modify it
TabAtkins: Possibly? But that would be by luck
TabAtkins: a script-modifiable ObservableArray is reason we defined
ObservableArray rather than frozen list
heycam: Does that have methods that can modify the array?
TabAtkins: ?? is that array
TabAtkins: it is an Array exotic object, so looks like an array to
author script code
heycam: So you can splice it etc?
* fantasai is getting confused now, is this read-write or readonly
now?
emilio: Plan is to make it readonly?
TabAtkins: Keep the current readonly-ness
TabAtkins: except now it will get the array modern methods
TabAtkins: but it will continue to be readonly
emilio: So Something.cssRules.push would throw?
TabAtkins: Yes. WebIDL has you specify the array modification
behavior using a set/delete algorithm
TabAtkins: and that gets called by all the mutation methods
underneath
TabAtkins: so if you try to modify, it'll throw
emilio: Then I'm not opposed, but, it feels weird to expose all the
mutating methods if you can't mutate it?
emilio: if you feel it's better, sure. Just want to make sure we're
not making the OM more mutable
TabAtkins: Don't intend to change mutability, just expose more
modern interfaces
fantasai: Why isn't there an equivalent observable array that's
designed to be read-only?
TabAtkins: Behavior to make readonly is trivial, just define set/
delete to throw
* fantasai doesn't think that answers the question
TabAtkins: This is an intended use case
emilio: I think it will confuse authors
emilio: but we'll see
emilio: not like you can construct CSSRuleList, so maybe not too
weird
plinss: I'm in favor, just two things to confirm
plinss: We get iterators etc?
TabAtkins: Yes
plinss: Perfect
plinss: My other question, are there other places in the CSSOM where
we're doing weird array-like things, and if so can we swap
them all at the same time?
TabAtkins: I believe that's it for CSSOM, have a pending edit for
TypedOM
TabAtkins: which currently uses a better version of fake arrays
TabAtkins: but I think in CSSOM CSSRuleList is the only actual list
we have
TabAtkins: everything else is individual rules
plinss: Would be good to do a quick pass over everything else, do
them all
TabAtkins: Been looking over OM, and everything seems to use
CSSRuleList, and Declaration doesn't expose anything like
that
TabAtkins: theoretically we could also make CSSStyleDeclaration an
ObservableArray, since it has indexed getting/setting
TabAtkins: happy to look into it
plinss: Or making it something maplike or whatever, but in any case
modernize anything that should be modernize it
TabAtkins: Should raise as a separate issue
TabAtkins: only other one that fits in this area, I think
<fremy> I believe CSSStyleDeclaration should not be made an
ObservableArray
<fremy> Otherwise, there can be conflicts between CSS property names
and Array methods
matthieudubet: CSSGroupingRule and now CSSStyleRule are really
similar implementation-wise
matthieudubet: insertRule/deleteRule are exactly the same
matthieudubet: should we expose those as (??)
matthieudubet: or share code only in the implementation
TabAtkins: Those all have .cssRules, and then they have legacy
insertRule/deleteRule
TabAtkins: If we wanted we could pull those two methods out into a
mixin, but that wouldn't be a behavior change
TabAtkins: just better organized specification
fantasai: I was following up on emilio's concern that we define
methods that doesn't do anything.
TabAtkins: Just don't call them
TabAtkins: Having something be a real array is valuable, and having
it behave like an array but not have all the methods is
hard and unnatural in JS
astearns: Proposed resolution is redefine CSSRuleList as
ObservableArray, with all of the readonly bits defined
astearns: particularly carefully since this is the first time we're
defining such a readonly ObservableArray
RESOLVED: Redefine CSSRuleList as ObservableArray
astearns: and also follow-up issue about CSSStyleDeclaration?
ACTION: TabAtkins to file issue about CSSStyleDeclaration's array
upgrade
CSSOM for nested media query rules
----------------------------------
github: https://github.com/w3c/csswg-drafts/issues/7850
<astearns> https://github.com/w3c/csswg-drafts/issues/7850#issuecomment-1404011020
has the new bits
TabAtkins: Last discussed in January
TabAtkins: Basic question was, given that we allow nesting @media
rule, and then you can put naked declarations inside, how
do we expose that in the OM?
TabAtkins: currently CSSMediaRule only exposes child rules
TabAtkins: The current proposal is if you have naked properties,
they are effectively wrapped in a nested style rule with
the & selector
TabAtkins: and are exposed that way
TabAtkins: This rule is the first rule in @media's child rules
TabAtkins: and only exists if it needs to
TabAtkins: There were two further suggestions
TabAtkins: One was to add .style accessor that roots to this first
style rule
TabAtkins: and/or to change parsing of all nested rules to wrap in &
{} as well
TabAtkins: There was mild opposition to both ideas, but ran out of
time
TabAtkins: Some concern about adding more rules to large stylesheet
TabAtkins: suggestion that all nested @rules that accept style rules
usually, wrap in & {}
astearns: We could do things later?
TabAtkins: We couldn't do the second thing, but adding .style is
still possible in the future
plinss: Some concern with ability to put raw declarations inside an
@media rule that's nested
plinss: because we get yet another situation where you can mix
declarations and rules, but defaulting differently
TabAtkins: ...
plinss: @media contains rules, so it's in rule error recovery
plinss: if you have stuff in side ...
TabAtkins: Using same error recovery in all places
TabAtkins: parser will fail rule parsing if it encounters ; before
the block
TabAtkins: today if trying to parse a rule, it will encounter the ;,
stop there, throw it out, and then start parsing fresh
TabAtkins: semicolons have never been valid in the front of rules
before, no expectation that this would break anything
plinss: If we have declaration top-level with braces, then something
that follows braces?
TabAtkins: Generally fine, some restrictions that we want to obey
for future compatibility concerns, but very minor
TabAtkins: part of larger issue
TabAtkins: same effect here as anywhere else
TabAtkins: won't affect current stuff, because nothing looks like
that today
TabAtkins: and in the future, you'll have the same set of
restrictions everywhere, which are extremely minimal
TabAtkins: but that's the larger parsing issue, same issue; only
concern here is whether existing @media would be parsed
differently, and I think the answer is "no in practice"
plinss: I accept it's part of the other issue
plinss: also concerned about older browsers parsing new content
TabAtkins: If you do nesting in an older browser, things will be
very screwed up, misparsing is the least of your concerns
astearns: In the interest of moving forward, perhaps we can resolve
to wrap things in an implicit & rule if we allow naked
declarations inside an @media rule
plinss: I'm ok with that. I'm concerned about requiring &{}
wrapping, ok if OM is same either way
RESOLVED: If naked property declarations inside @media become a
thing, they are wrapped in a & {} rule.
emilio: Is this anonymous rule well-defined? it's at the beginning?
TabAtkins: Details in the issue, always at the beginning if it's
needed
plinss: If mix of declarations and rules, all the declarations sort
to the beginning?
TabAtkins: Yes
matthieudubet: If they actually write & { ... } explicitly, do we
group with that?
TabAtkins: No
TabAtkins: If they explicitly write a rule, that's their rule, we
don't do anything magic with that
matthieudubet: OK, that's not what Safari Tech Preview is doing
right now
matthieudubet: it tries to show the smallest representation with the
same semantics
matthieudubet: so it removes it
TabAtkins: This isn't in the spec yet, so it's not tested yet, so
Safari will discover if it's doing the wrong thing
emilio: You can't just merge them because the order matters
<heycam> @media (...) { & { color: red; } color: green; } /* element
would be red */ ?
heycam: So just want to clarify that all the bare declarations get
hoisted to the top of the rule
heycam: so it might be a little confusing, about the order they'll
applied
TabAtkins: It's the same behavior you get in ordinary nested style
rules, though
TabAtkins: all your naked declarations are sorted before all of the
style rules
fremy: We resolved that we would be consistent, and maybe discuss
what to do (but nobody filed an issue about that)
fremy: I think it's weird that they move, but should be consistent
plinss: If I have a bare red and then two wrapped blue, and then
bare green, I expect it to be green and it will be blue
fremy: We discussed in the past, if we agree, we should file an
issue about that
TabAtkins: This is a minor issue for compat purposes, so we can
adjust this
TabAtkins: I think the answer is, don't put naked things after
rules; but no reason to ban them
TabAtkins: either way it's confusing
TabAtkins: but I don't care which way we go
TabAtkins: but aside from that, that would be a separate issue, I
think we're done with this issue
astearns: Resolution makes us consistent for the moment, but we can
look at general issue on what to do with general
declarations
ACTION: fremy or plinss to file issue about whether naked
declarations get sorted to the top of the list or not
Nesting conditional rules
-------------------------
github: https://github.com/w3c/csswg-drafts/issues/7830
TabAtkins: Implementer in Chrome was wondering if we could punt
conditional rules to L2, but he ended up implementing and
it wasn't that bad anyway
TabAtkins: so proposal is to close this no change
RESOLVED: Close no change
Feature detection for nesting
-----------------------------
github: https://github.com/w3c/csswg-drafts/issues/8399
astearns: Something shipped in Chrome that's not quite what we want,
but not clear on what we want
astearns: we should have had a good story before shipping anything
TabAtkins: I agree that this being parsable before shipping was
ready was a mistake, but I don't think we can fix
retroactively
TabAtkins: Don't think we should expose whether nesting is possible
or not
astearns: We shouldn't have feature detection?
TabAtkins: We shouldn't add anything except selector detection,
it'll just misfire on some versions of Chrome/Safari
plinss: Wasn't there discussion of using & in other places?
TabAtkins: Allowing it elsewhere, yes, but concurrent with Nesting
being supported
plinss: Is that guaranteed?
TabAtkins: In practice yes
plinss: But it's usable in another feature that's not dependent on
Nesting
TabAtkins: Only @scope, but it's also nesting rules ...
fantasai: That's different from the nesting feature because @scope
can only contain nesting rules
TabAtkins: Don't think ti's a problem in practice
matthieudubet: For feature detection, should we try to give the
proper result with a relative selector
matthieudubet: should @supports be aware of the nesting stack?
matthieudubet: and always return true/false regardless of nesting
stack?
TabAtkins: The latter. @supports shouldn't be aware of where it is
in the stylesheet
<TabAtkins> .foo { @supports selector(&) {...}}
TabAtkins: that should not give different results at the top level
vs nested
<fremy> .foo { @supports selector(+a) {...}}
matthieudubet: & is allowed both places, but relative selectors are
allowed or not depending on whether nested
TabAtkins: I would prefer we don't make @supports context-sensitive
TabAtkins: Right now we don't carry context into the querying APIs,
and you can't express that in JS
TabAtkins: so as much as possible I'd like to keep those consistent
matthieudubet: Right now for Safari, it does take context into
account
matthieudubet: so if the selector is not supported *there* it'll
return false
<TabAtkins> CSS.supports()
TabAtkins: What about CSS.supports()?
TabAtkins: The JS API can't know the context
matthieudubet: That's what we do for the at-rules. For JS API, we do
the same, so when you write a relative one will
always say false
matthieudubet: because not in a nested context
TabAtkins: That interpretation is novel, and not expressed in the
spec right now
TabAtkins: if we want to do that, can you raise an issue?
TabAtkins: new issue, please; this is unrelated to the current issue
astearns: It's better to have specific issues on narrow problems
astearns: so agree we should have a separate issue on whether
relative selectors inside @supports are context-sensitive
plinss: Important that nesting be readily detectable at the top level
plinss: I have concerns about feature detection of one feature being
dependent on another feature
plinss: just because we implemented & and nesting together is cute,
but not something to rely on
<emilio> Agreed nesting should def. be detectable in top-level and
CSS.supports
fremy: If you want to feature-detect @scope, how do you do it?
plinss: How do I detect & for @scope?
TabAtkins: at-supports API doesn't yet allow querying that sort of
thing
plinss: We need reliable support detection for nesting, that works
reliably for @import supports().
plinss: so & detection is not good enough
TabAtkins: Currently can only express as selector(&), if you want
something more specific need a new thing
plinss: That needs to ship with Nesting
astearns: Any suggestion of what this might look like?
plinss: @nest?
fremy: How about we check whether & is a valid property? That would
be checking for nesting
fremy: e.g. @supports (&) { ... }
<heycam> @supports rule(p { & { } })
<fremy> @supports (&{})
<bradk> @supports (nesting) { … }
TabAtkins: That's not valid property
TabAtkins: Maybe not that bad given how messy the shipping has been
with this feature, but in general want to avoid special
casing
plinss: We might want a general feature() function for things that
are hard to feature-detect
fantasai: I think Francois's suggestion does fit the current syntax
fantasai: That said, if we do allow that, we'll be allowing any kind
of selector-based rule that can be nested to be in there
fantasai: Might be more parsing than we want, but not inconsistent
TabAtkins: Depends if you think of it as () parses a declaration or
if () parses "stuff that could go in a declaration block"
plinss: Would be a problem if we allow selectors, since range of
selectors is open-ended
plinss what if we add a div property
fremy: Same problem we have today already
fremy: To me, I think it's a nice extension, doesn't require a big
change
fremy: not saying we have to do it, it's just an idea
TabAtkins: Can we do the rest of the design work in the thread? we
have 9 min on the most important issue
astearns: Sounds to me that for this issue, we're going to retain
the bare & supports strategy in the spec, but might also
add something that is a little more complex or specific?
TabAtkins: Think so
astearns: So leave discussion here, don't need a resolution since
selector(&) already works
astearns: but will leave this issue open for further discussion of
supports functionality
plinss: I believe it's very important that we have a stable and
reliable mechanism before we ship anything, can we agree on
that
TabAtkins: I think it's a good idea, I'm not going to commit to it
plinss: I think shipping this without reliable feature detection is
a huge mistake
<fantasai> +1
astearns: Agree with plinss
<emeyer> +1
<bradk> Me too
astearns: I think we should have another breakout on Nesting next
week
Problem with mixing properties and selectors
--------------------------------------------
github: https://github.com/w3c/csswg-drafts/issues/8249
astearns: plinss's suggestion is we put the lookahead version into
the spec
astearns: and remove references that we had to parts that we had
based on old parsing mode
astearns: is that a way forward?
TabAtkins: That's exactly what I want to do
astearns: So can we resolve the problem by saying that we'll specify
the new parsing-enabled version only?
plinss: I'm uncomfortable with that, depends how we phrase it
plinss: I'm thrilled that lookahead proved viable. I think this
should take Option 3 off the table.
plinss: we should ship with lookahead, or something else entirely
plinss: I don't care if there's one STP or whatever that shipped
differently, but what we spec
TabAtkins: I agree completely
jensimmons: I don't
<fremy> fwiw, the lookahead option would satisfy me
plinss: I still think there are issues with lookahead, but it's far
better than Option 3
plinss: I won't formally object provided that we take a step back
and review all the advantages/disadvantages
plinss: and reconsider all the options
plinss: and look at the big picture
plinss: and whatever we decide as a group, I'll be fine with
fremy: My concern was that copy and paste would not be viable, but
with lookahead it is
jensimmons: I am disappointed that plinss is once again making
demands that we do what he wants, and assures us that if
we do he'll be OK
plinss: I haven't changed my position
plinss: I'm demanding that we follow the process and make rational
decisions
jensimmons: What is happening is that browsers have implemented what
was specified, and are moving forward despite the
situation we've found ourselves in in the past several
months
jensimmons: and I'm a believer that as we evolve CSS and take an
idea, work through it, implement and ship it, evolve it,
continue to add more to it or make it better, and
implement and ship the newer version
jensimmons: we have a method to do this, we have levels for
specifications
jensimmons: and we keep a trail as we go so browsers can make
interoperable implementations
jensimmons: I don't want to obliterate the spec, because it is
shipping. I would like to write up Level 2
jensimmons: and browsers can ship that as it's possible to do
<fremy> -1 because they are not compatible
<TabAtkins> (we have a working draft https://www.w3.org/TR/css-nesting-1/)
plinss: We don't have a spec for that, browser shipped outside the
W3C process
jensimmons: That's your opinion, don't want to fight about it
plinss: We had contention and two browsers shipped anyway
plinss: We have no obligation to spec retroactively
astearns: We are out of time
astearns: I would point out that we do have a process for asking the
WG "are you ready to ship", and that was not followed in
this case
astearns: but we'll have to leave this open. We can have another
breakout next week.
astearns: Would like people to add comments to the issues so we can
hash this out and not have new arguments on the call
[Meeting closed]
+++ Continued IRC conversation +++
<TabAtkins> We do in fact have an obligation to spec reality. We can
try to *nudge* reality, but we're not writing fiction.
<TabAtkins> And we *did* try to follow process, the process was
dragged out over several browser's explicit requests to
resolve it.
<TabAtkins> The process (the WG) failed to work effectively, and was
routed around.
<TabAtkins> And now we're dealing with the consequences. Luckily I
made sure that what we went with was compatible with the
ideal future, so now moving to the ideal future is easy.
<plinss> And sometimes the process takes longer than people want,
but that's still the process, routing around it does not
supersede the process
<fremy> To be fair, I will argue the process worked properly here.
Without objections, we would not have the lookahead version.
It was deemed impossible. Only when so much pushback
happened was it properly tested.
<astearns> +1 fremy
<fremy> I think the process yielded a better outcome, but
unfortunately some lost faith before it reached its course
<fremy> It's understandable, I would have wanted to ship this too if
I was the PM
<fremy> No blame handed out
<fremy> But I think the "work around" was not optimal, here
<TabAtkins> fremy: The "workaround" was required, because the chairs
allowed one threatened objection to indefinitely delay
resolution. That was, itself, a violation of process, as
Jen pointed out in an earlier call when she *cited* the
Process and asked for a vote to resolve the logjam, and
was rejected by the chairs.
<TabAtkins> More generally, the Process is an way of working toward
interop, not a suicide pact. We abide by it because it
generally produces good results, and is a useful
schelling fence to ground discussions with. But we very
intentionally do not *require* W3C signoff on shipping
code in Chrome.
<fantasai> Dude, not only do you to not require it, you don't even
*ask* for it, even when it would be useful for the CSSWG
to have that discussion and even when you would get it.
It's really obnoxious.
<fantasai> You ask for TAG signoff, but don't care to ask the CSSWG.
<fantasai> Even when the CSSWG would actually have more useful input.
<plinss> and for the record, the TAG didn't sign off on nesting
either
Received on Thursday, 6 April 2023 17:10:21 UTC