Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-cascade-5] Allow authors to explicitly place unlayered styles in the cascade layer order #6323

Open
mirisuzanne opened this issue May 28, 2021 · 124 comments

Comments

@mirisuzanne
Copy link
Contributor

mirisuzanne commented May 28, 2021

Regarding CSS Cascade 5 (cascade layers), @jensimmons commented on another thread about layer ordering:

Would it be possible to allow Authors to set for themselves where in the cascade the "unlayered layer" resides? Maybe they even want to sandwich it in-between. A mechanism that's part of however they define the named layers & determine which layer is "first" & "second", etc.

By default unlayered style come first (lowest cascade priority) in the source order, but this would allow more explicit placement. Roughly (pseudo-code):

EDIT: That's no longer the case. In #6284 we reversed the behavior, and now unlayered styles have the highest priority. This explicit placement would still be useful, since there are use-cases for both approaches.

/* the default behavior */
@layer <unlayered-styles>, reset, framework, components, utilities;

/* placed "in-between" layers */
@layer reset, framework, <unlayered-styles>, components, utilities;

/* placed at the top/end of the layer order */
@layer reset, framework, components, utilities, <unlayered-styles>;

I think that feature makes a lot of sense, and I would likely use it as an author. A few considerations to keep in mind, as we develop a mechanism for this:

  • I would expect it to be repeatable for implicit sub-layers, as well the implicit outer layer
  • Since all layer names are currently custom-idents, we either need a reserved name, or some way of distinguishing the provided implicit-layer ident from author-provided idents.
@Alohci
Copy link
Contributor

Alohci commented May 31, 2021

Definitely welcome to have that level of control. If you didn't want a reserved name you could use different @ name. e.g.
@layer reset, framework;
@unlayered;
@layer components, utilities;

@fantasai
Copy link
Collaborator

fantasai commented Jun 1, 2021

Idk if it's a good idea, but one possibility would be to just leave out the identifier.

@layer reset, framework;
@layer;
@layer components, utilities;

@mirisuzanne
Copy link
Contributor Author

mirisuzanne commented Jul 5, 2021

Thinking about this a bit more: every layer (including but not limited to the default/root layer) has the potential for both direct style-rules and nested sub-layers. So this feature might be useful in nested context, not only in the root/default situation:

@layer one;
@layer;

@layer one {
  @layer two;
  @layer;
}

On the other hand, the root/default layer is the only place where authors might not be able to add explicit layering – for the sake of backwards compatibility. Once styles are layered, there is no harm in layering them further. So from that perspective, control is only needed for fully-unlayered styles.

Is it confusing if authors can specify different defaults inside each layer context? Is it more confusing if this only works at the top level, and does not work in nested contexts?

@Alohci
Copy link
Contributor

Alohci commented Jul 5, 2021

It would be a shame in my opinion if it didn't work the same in nested layers.

I'm also not sure how @import url(links.css) layer(mylayer); would work if @layer; didn't work the same when it becomes nested by the import as it does when the import doesn't inject it into a layer.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Allow authors to explicitly place unlayered styles in the cascade layer order, and agreed to the following:

  • RESOLVED: Reserve the CSS wide-keywords (making the whole layer block invalid at parse time) for now and details TBD when we have better use cases
The full IRC log of that discussion <emilio> topic: Allow authors to explicitly place unlayered styles in the cascade layer order
<emilio> github: https://github.com//issues/6323
<emilio> miriam: this one is another coming from an earlier resolution
<emilio> ... we resolved that unlayered styles are lower pri
<jfkthame> present-
<emilio> ... jen asked about whether it'd be useful to tweak the unlayered styles priority
<emilio> ... there's some syntax proposals in the issue
<Rossen_> q?
<emilio> ... and I'd expect it to work at each level of layering
<emilio> ... are we happy with an empty layer rule syntax? Does this become too complex?
<emilio> florian: I could see use cases for top/bottom, has any non-theoretical use case come up for in the middle?
<emilio> miriam: yeah, you want components at the top and resets on the bottom, so you might want most of your styles between them
<emilio> TabAtkins: Like florian I see the use case but I'm not sure we need to solve it right now
<emilio> ... we could resolve the CSS wide keywords as layer names in case we want to solve them
<emilio> miriam: does that become a problem if additional wide-keywords are added?
<Rossen_> ack fantasai
<emilio> TabAtkins: theoretically? But we haven't added many over the years
<TabAtkins> s/resolve/reserve/
<emilio> fantasai: we could also do something that isn't a keyword
<emilio> ... I don't have strong opinion on having to solve this now, and I'd be ok reserving the wide-keywords
<fantasai> s/keyword/keyword, like an asterisk/
<emilio> florian: maybe I need to re-read the minutes for when we decided to switch top/bottom, I wasn't there and it seems !important could take care of jumping to the top
<emilio> miriam: main reason for that was that putting them at the bottom allows progressive enhancement
<emilio> ... sort of like when not all browsers had media queries you'd write the specific styles in there
<emilio> ... but lots of people think of layers as a way to hide their resets
<emilio> florian: I guess I see it more like the later but that also doesn't give me a strong use case for having unlayered styles in the middle
<emilio> ... I'd be fine reserving the wide keywords though
<emilio> fantasai: so there's the question of whether we add it now, if we don't we might want to just reserve the keywords
<emilio> miriam: if we're not sure if it's needed I'd be ok with reserving the keywords and delaying
<emilio> ... since it adds a fair amount of complexity
<emilio> florian: what do we need by reserving the keyword? Just making them syntactically invalid?
<emilio> fantasai: yeah, if you define @layer with that keyword the whole block is in invalid
<emilio> florian: is that progressively-enhanceable? If you add a layer that doesn't work and then it starts working...
<emilio> fantasai: why would you type it in if it doesn't work?
<emilio> florian: would it be wholly invalid or just ignored?
<emilio> TabAtkins: could we bring that detail back to the thread?
<emilio> Emilio: fwiw it seems simpler to make the whole block invalid at parse time
<emilio> RESOLVED: Reserve the CSS wide-keywords (making the whole layer block invalid at parse time) for now and details TBD when we have better use cases

@frivoal
Copy link
Collaborator

frivoal commented Jul 27, 2021

Given the resolution above, I think we all agree that @layer initial { } is simply invalid and the whole block is rejected. However, what of @layer foo, initial, bar;? Is that whole rule rejected too, or do we simply order foo and bar and ignore the non-existing initial layer?

I'm not sure, but I suspect making the whole rule invalid is safer. Otherwise, we might have people who introduce a @layer initial { } block, fail to notice that that doesn't do anything, order that layer into the middle of the stack with @layer foo, initial, bar;, and some day, if we do make the initial keyword apply in that situation, that changes the ordering of their whole page. I think this scenario would be less likely to happen if we ignore the whole rule, as then the author would be confronted with the fact that the ordering of their foo and bar layer don't work either, making it easier to notice.

@mirisuzanne
Copy link
Contributor Author

I'm happy with that approach, and drafted some spec language around it. Not sure if we need to get an official resolution, or not?

mfreed7 pushed a commit to mfreed7/csswg-drafts that referenced this issue Aug 4, 2021
@FremyCompany
Copy link
Contributor

FremyCompany commented Oct 6, 2021

I noted while thinking about this in the context of #6284 that explicitly pinning "initial" as a layer name isn't very convenient, because this has to happen once, and so that first declaration needs to be aware of all the layers that need to be above or below the initial layer (which might not be possible if you are using themes / unrelated add-ons).

Another approach I have been thinking about is to have two lists independently, all layers that must be above the unlayered styles, and all who need to be below.

A strawman would be as follow (`!important following an at-layer name means to put in the list after unlayered styles):

@layer reset { article h1 { margin: 0; } }
@layer theme { h1 { margin-top: 1.2em; } }
@layer special-overrides !important { h1:first-child { margin-top: 0 } }
.main-title { margin-top: 0.2em; } }

That would yield the following order for the layers : reset < theme < /initial/ < special-overrides.

Adding !important to individual values has an effect as usual, the !important on @layer only changes the order of layers in the list, but does not propagate to the values themselves (but the change in order for the layer will make the declaration be more important).

@FremyCompany
Copy link
Contributor

The advantage I see is that we are not prescribing anything here about the specifics of the default, authors can get one or the other depending on their needs.

@fantasai
Copy link
Collaborator

fantasai commented Oct 6, 2021

I think it's going to be useful and important to be able to have one-off layer declaration blocks that are above or below the default-layer styles, so we should have a syntax built into the @layer rule that says whether it goes above or below. Something like:

@layer [ up | down ]? <layer-name> { ... }

where

  • up increases the priority of normal rules (and decreases priority of !important rules)
  • down decreases the priority of normal rules (and increases priority of !important rules)

@mirisuzanne
Copy link
Contributor Author

mirisuzanne commented Oct 7, 2021

I like the goal here, but have a few questions.

As I understand this, we would basically be creating two layer stacks — one above and one below the default — and then use the keywords to append layers to the top of either stack? What's the result of these cases?

@layer up one;
@layer down one;

Does that give us two layers with duplicate names (upper one & lower one)? Or do we only allow this keyword when the name is first used (in which case the second rule is invalid)? Another option is that we only provide this one-off syntax for truly one-off unnamed layers? In which case we likely need both the explicit placement, and the one-off option.

@layer  <layer-name> | [ up | down ] { ... }

I assume we don't want to allow moving layers around retroactively, so the second rule should not impact the layers defined in the first rule. That's what up/down imply to me. So if that's not what we mean, I think we should name the two layer stacks, and use their names as the keywords: something more like upper/lower or default/important or …?

@tabatkins
Copy link
Member

tabatkins commented Oct 23, 2024

In the call I brought up some potential confusion caused by being able to interleave top and bottom layers, and the UA having to resort them, like @layer foo !bar baz; actually being equivalent to @layer foo baz !bar;. Bramus had a suggestion about requiring top and bottom layers be specified in different rules, but that doesn't generalize well to nested layers.

But thinking about it more, this isn't a new problem. It's already the case that the list gets resorted in some cases: if you write @layer foo.one bar foo.two;, that's actually equivalent to @layer foo.one foo.two bar;, because sublayers are always grouped by their parent layers. (@kizu says this same thing, above; their comment collided with mine.)

Further, in practice the only difference between Option 2 and 3 is the length of the "this is a top layer" sigil. There's actually nothing distinguishing foo.!one and foo.!top.one except that in the first the special "this is a top layer" sigil is spelled !, while in the second it's spelled !top.. The extra characters don't meaningfully help distinguish it, so we can just remove them.

(And yes, the "infinitely nested !top layers" thing is an issue; I don't think we want it, so we'd have to syntactically disallow putting rules directly in a top layer; in other words, foo.!top would be an invalid layer name at the syntax level. But at that point, the !top. characters are even moreso just a five-character sigil for "this is a top layer", since the top layers don't exist on their own in a meaningful sense.)


So yeah, never mind, I'm all for Option 2 now. I just suggest spelling it somewhat more obviously, like with #, which is both "weightier" as a glyph and already indicates important things in a selector.

@kizu
Copy link
Member

kizu commented Oct 23, 2024

@tabatkins
(And yes, the "infinitely nested !top layers" thing is an issue; I don't think we want it, so we'd have to syntactically disallow putting rules directly in a top layer; in other words, foo.!top would be an invalid layer name at the syntax level. But at that point, the !top. characters are even moreso just a five-character sigil for "this is a top layer", since the top layers don't exist on their own in a meaningful sense.)

I don't think we can make the foo.!top an invalid layer, unless the proposal is to make top-level layers bubble up through regular ones and be always at the top even when they're nested?

That would mean that you couldn't encapsulate some styles by importing them into a layer you control, as the topmost layers will escape it.

And if the #top will be local to the imported layer and won't escape, we need an ability to access it through foo.#top. And with option 2, the infinitely nested top layers is not an issue, as you don't need to do !top.!top.!top when you can do just @layer !top, !topper;.

Basically, if we write a stylesheet and put some layers above the unlayered, we are only concerned about the order of styles we control. But our stylesheet could be imported into a layer inside another stylesheet, meaning the top layer will be only local inside the imported styles, and in the same way you could mention regular layers, we'll need to mention the top layers.

@mirisuzanne
Copy link
Contributor Author

mirisuzanne commented Oct 23, 2024

Yes, I believe these things are all true:

  • layer.!top.something and layer.!something are different spellings of the same behavior.
  • We have to allow these in nested contexts, so either way !top.!top.!top is a valid option.
  • Resorting already happens for nested layers

And so the advantage of option 3 (if people want it) is only that we are re-using a nesting syntax to clarify that the re-sorting behavior acts similar to nesting layers.

(Edit: Using # would make !top.!top.!top invalid 😅 but now we have #top.#top.#top. Jokes aside - I'd be happy with that spelling, since I prefer we don't associate this with importance. The two features will interact more like ids and importance interact)

@tabatkins
Copy link
Member

I don't think we can make the foo.!top an invalid layer, unless the proposal is to make top-level layers bubble up through regular ones and be always at the top even when they're nested?

I think you misunderstood what I meant. I was saying that we'd make foo.!top an invalid layer name to specify; you'd have to write a sublayer after it, like foo.!top.bar; similarly, you couldn't write @layer foo { @layer !top {...}}, you'd have to write @layer foo { @layer !top.foo {...}}. That way, no styles would ever be inserted directly into a top layer; they'd always be nested into a named layer.

We have to allow these in nested contexts, so either way !top.!top.!top is a valid option.

Not quite; those characters form valid syntax in both, but mean different things and act differently. You could have top layers named "top" in Option 2, sure, but they'd work like any other named layer, and thus could be targeted and explicitly sorted by preceding code pre-declaring the layer order. A quick @layer !top !my-stuff; ensures that your stuff wins in the layer sorting.

But in Option 3, nested !tops always appear at the end of the order on a given layer. No matter what you do, something in !top comes after foo, and even after !top.foo (because the styles are unnested within the !top layer, and thus go at the end); to put your own thing after, you have to exceed their number of !tops and do !top.!top.

@DarkWiiPlayer
Copy link

I can't think of a single case where putting unlayered styles directly in a !top layer would make sense, which would be the only advantage of !top over !my-top

@mirisuzanne
Copy link
Contributor Author

Are we moving towards a consensus here?

  • Accept option 2, with a custom syntax for naming 'override' layers, which are sorted above unlayered styles
  • Use #<layer-name> as the initial syntax (and optionally bikeshed further if needed)

@bramus
Copy link
Contributor

bramus commented Nov 15, 2024

Are we moving towards a consensus here?

  • Accept option 2, with a custom syntax for naming 'override' layers, which are sorted above unlayered styles

To those looking: here’s the link with the comment with all options: #6323 (comment)

  • Use #<layer-name> as the initial syntax (and optionally bikeshed further if needed)

Would prefer to use !<layer-name> for the syntax as the ! has a link with !important.

@benface
Copy link

benface commented Nov 15, 2024

Definitely +1 to !. I don't understand where the # proposal comes from. Well, I see it was proposed by @tabatkins here:

So yeah, never mind, I'm all for Option 2 now. I just suggest spelling it somewhat more obviously, like with #, which is both "weightier" as a glyph and already indicates important things in a selector.

But to me, # implies "ID" a lot more than it implies weight or importance.

@mirisuzanne
Copy link
Contributor Author

mirisuzanne commented Nov 15, 2024

Would prefer to use !<layer-name> for the syntax as the ! has a link with !important.

This is the entire reason I would avoid !. Importance is a distinct feature that works differently. I'm worried that if we conflate them, we only add confusion about the differences. People are already unfamiliar with the reversing behavior of importance, and often surprised by how that interacts with Cascade Layers. I'd very much like to avoid adding to that confusion. These are not important layers. They work different from important layers.

The way this works is more similar to ID selectors being the stronger of the selectors.

@astearns astearns moved this to FTF agenda items in CSSWG January 2025 meeting Jan 27, 2025
@astearns astearns moved this from FTF agenda items to Regular agenda items in CSSWG January 2025 meeting Jan 27, 2025
@astearns astearns moved this from Regular agenda items to FTF agenda items in CSSWG January 2025 meeting Jan 28, 2025
@astearns astearns moved this from FTF agenda items to Friday morning in CSSWG January 2025 meeting Jan 28, 2025
@dholbert dholbert moved this from Friday morning to Friday afternoon in CSSWG January 2025 meeting Jan 31, 2025
@astearns astearns moved this from Friday afternoon to Friday morning in CSSWG January 2025 meeting Jan 31, 2025
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-cascade-5] Allow authors to explicitly place unlayered styles in the cascade layer order.

The full IRC log of that discussion <ntim> miriam: We've discussed this before, authors have been asking for ways to explicit place their styles cascade layer order
<ntim> Miriam: The other way to think about that, is that people want to have layers above their unlayered styles
<ntim> miriam: after different proposals, we sorted them into 3 categories
<miriam> https://github.com//issues/6323#issuecomment-2207341923
<ntim> miriam: one was an explicit name for unlayered styles
<ntim> miriam: one was an explicit naming convention for putting your styles above unlayered styles
<ntim> miriam: starting with a bang, up or down
<ntim> miriam: the third was some explicitly prenamed layer that uses a special layer
<ntim> miriam: we rejected the first option
<ntim> miriam: in the discussion, we realized that options 2 & 3 are the same but with different names
<bramus> q+
<ntim> miriam: what the issue thread came to was option 2
<emilio> q+
<ntim> miriam: the proposal was that layers can start with a hash, and they would go above
<ntim> miriam: hash because they don't work like importance
<TabAtkins> +1
<hober> q+
<ntim> miriam: spelling can be discussed further if needed
<ntim> miriam: but the gist is that layers can be named differently and they would go above
<astearns> ack bramus
<oriol> q+
<kbabbitt> q+
<ntim> bramus: big +1, author requests all over the place, personal pref is not using the hash, but to use ! to denote that it's a strong layer.
<ntim> bramus: the argument for hash is that it's an ID, but layers already have a name
<astearns> ack emilio
<ntim> emilio: this looks reasonable, but I wonder, what is the order of these layers relative to each other?
<astearns> ack hober
<ntim> emilio: seems fine, i don't care too much about syntax
<ntim> hober: I like solving the use case, I have 2 issues with syntax
<ntim> hober: the first is that the hash seems particularly, hash is linked to fragments
<ntim> hober: more broadly, I like naming conventions for author, but I don't like naming conventions that the platform imposes
<fantasai> +1
<ntim> hober: I'd rather have syntax that doesn't intrude into names
<astearns> ack oriol
<ntim> oriol: I wanted to say that this hash sign seems too related to ID selectors, I'm not advocating for ! necessarily, but hash seems weird
<ntim> oriol: would that just be for named layers? would it be possible to have an unnamed layers over named ones?
<ntim> miriam: this hasn't been discussed
<astearns> ack kbabbitt
<kbabbitt> ^
<ntim> kbabbitt: I support the proposal, I would prefer not using hash, fantasai proposed a slash
<ntim> miriam: the slash proposal is quite different, and it gets complicated, and it would be simpler if it stayed in the name
<ntim> fantasai: not sure I understood that, it would work the same as !
<ntim> fantasai: you could declare I have 2 layers that go above, 2 layers that go below, pretty easily with slash
<bramus> q+
<astearns> ack fantasai
<Zakim> fantasai, you wanted to suggest https://github.com//issues/6323#issuecomment-971910037
<ntim> fantasai: and if you want to do only 1, you can just prefix with the slash
<kbabbitt> s/^/I'll also suggest ^ as an alternative to #/
<astearns> ack bramus
<fantasai> @layer / bar { stuff }
<ntim> fantasai: thinking about it as a syntax, rather than as an attachment to the name, would give more flexibility
<ntim> bramus: in prev discussions we had, there was a remark that we didn't want to introduce random ASCII characters to denote special things, so I'd rather want to stick to pre-existing ones like hash or !
<bramus> q+
<fantasai> s/syntax/separate syntax/
<astearns> q+
<kbabbitt> between # and ! I would prefer !
<ntim> bramus: when referring to nested layers, you can use the . notation, with the slash, I don't see how that would work
<astearns> ack bramus
<astearns> ack astearns
<ntim> bramus: whereas with the # / !, it would work, bc it sticks with name
<ntim> astearns: in my quick reading of the slash proposal, I was confused
<astearns> I was assuming lists would look like `above / unlayered / below`
<ntim> fantasai: this is what I had in mind
<ntim> fantasai: actually it's the other way round
<astearns> so it’s `below / unlayered / above`
<astearns> `name/` `/name`
<ntim> astearns: if we used slash, or any other char, do we have different behavior if it comes before or after?
<ntim> miriam: I think with fantasai's proposal you'd get a bit of that
<astearns> q?
<ntim> astearns: with fantasai's proposal, we're always building a list
<ntim> miriam: in the issue, i thought we had consensus, we can take it back to the issue?
<bramus> q+
<astearns> q+
<ntim> miriam: I tend to agree with bramus, that we lose a lot of flexibility around syntax, for the reasons stated previously
<ntim> fantasai: why can't you do this with slash?
<miriam> @layer #name { … } vs @layer / name { … }
<ntim> fantasai: I might not be understanding this well, but would exclamation at the start/end be the same thing?
<astearns> ack bramus
<fantasai> this: https://github.com//issues/6323#issuecomment-2433062569
<ntim> bramus: !important exists, it works in weird ways, it's considered a design mistake, but it's there so maybe we should embrace it
<kizu> q+
<fantasai> but I might have misunderstood it
<ntim> bramus: a lot of the authors don't understand the cascade well, if we use the exclamation point to denote strong layers, then authors could make the link
<ntim> miriam: I agree with that except the conclusion. We can't brush away the fact that they don't understand layers. So we have to teach them properly importance
<astearns> ack astearns
<ntim> miriam: we shouldn't confuse that for users, because they work very differently
<ntim> astearns: I want to disagree with the point made about avoiding random ASCII. It's not to avoid re-using random ASCII, but rather to make things explicit with words
<ntim> dbaron: and a word you can search for
<astearns> ack kizu
<ntim> kizu: one thing I want to mention, we can probably resolve on choosing option 2 about adding _something_ to the name
<bramus> +1
<miriam> I'd be happy with the caret
<astearns> s/avoiding random ASCII. It's not to avoid re-using random ASCII/avoiding adding random ASCII. It’s not that we should re-use existing random ASCII/
<bramus> Not blocking on caret
<ntim> kizu: I would prefer the current symbol, to avoid overloading symbols
<fantasai> s/current/caret/
<ntim> kizu: ! often denotes negation in other languages too, in addition to the current meaning in CSS
<bramus> As long as it’s not the #, I’m fine :)
<hober> q+
<ntim> astearns: ^ might be something to start with
<astearns> ack hober
<lea> Q+
<ntim> fantasai: caret also points up
<ntim> hober: caret as syntax vs caret as name?
<ntim> hober: in the CSSOM, I don't want the caret in the name if I ask for the name
<lea> Q?
<ntim> miriam: i'm ok with that, but adding a space might make it complicated for nested
<ntim> TabAtkins: we need the caret to distinguish right?
<ntim> hober: how about a function syntax?
<bramus> qq+
<TabAtkins> `@layer foo, ^foo;`is valid
<TabAtkins> need to be able to tell them apart
<fantasai> ok, can we not have separate namespaces?
<ntim> miriam: the issue that Tab was getting at, if we put a layer in the name foo, and one outside name foo. We have no way to distinguish them
<fantasai> I think that's not a good idea
<ntim> hober: maybe that would be good because it would encourage explicit names
<ntim> TabAtkins: but then you can't declare
<ntim> miriam: it's very common to declare
<astearns> ack bramus
<Zakim> bramus, you wanted to react to hober
<ntim> bramus: I agree that the caret shouldn't be part of the name when reading it back, but it should expose it through an attribute in CSSOM
<bramus> An attribute on CSSLayerBlockRule
<astearns> @layer foo(strong)
<TabAtkins> point of order, maybe? this is just us bikeshedding over syntax space we've already spent time bikeshedding over in previous meetings. we had previously reached a reasoanble consensus and just needed to decide a final detail.
<astearns> ack lea
<ntim> lea: it seems like we're converging towards caret. Why are we optimizing for conciseness? Any symbol will be less explicit than an explicit description. What if we add more ways to control layers?
<ntim> lea: if we follow this pattern, are we going to explode syntax?
<ntim> lea: I'd prefer an explicit named description
<dbaron> +1 (weakly, at least) to keywords or functions rather than symbols
<ntim> miriam: I don't think it's true that there's a lot of possible expansions, including for shadow DOM
<ntim> miriam: shadow DOM cascading happens before layer cascading
<ntim> miriam: we likely need something completely new
<ntim> miriam: layers as a feature exists in the cascade after shadow contents in teh cascade
<ntim> miriam: there is no way for stuff internal to layering that would impact something external to layering (like shadow DOM)
<ntim> lea: this is about what other ways of ordering we may want to define? not about a specific proposal
<ntim> miriam: I don't think there's any other ones internal to layering
<ntim> fantasai: I'm basically agreeing with miriam that this idea of concept of above/below always existed, just without a syntax
<ntim> fantasai: it's a feature much more fundamental, so I think it's ok if the syntax very baked
<TabAtkins> you do that by just not using a layer
<ntim> lea: is there any point at defining a layer at the same level?
<ntim> astearns: I don't think there is consensus, there are a bunch of new ideas. There's objection around re-using the chars. We need to go back to the issue
<ntim> miriam: we have done this many times, and keep rehashing the same discussions
<bramus> +1
<kizu> +1
<ntim> miriam: when we do reach consensus on the issue, we have new people coming up with the same discussions
<ntim> TabAtkins: we need to resolve on something.
<ntim> hober: a resolution would probably fail right now
<ntim> astearns: the only thing that we might be able to resolve on is the caret
<ntim> TabAtkins: is everyone ok with the exact proposal from miriam?
<ntim> hober: idk
<TabAtkins> save with ^ isntead of #
<ntim> astearns: use a single character in front of the name was the proposal
<ntim> hober: the question about whether the symbol is part of the name is very relevant
<ntim> hober: it's the contentious part of this
<ntim> miriam: is this only for CSSOM?
<ntim> hober: it's more general
<ntim> miriam: it would be attached to the name, like the dot is for nested layer
<bramus> s/it would be attached to the name, like the dot is for nested layer/it would be attached to the name, like the dot is for a classname
<ntim> miriam: so you couldn't have a strong/weak version with foo
<ntim> astearns: if it's not part of the name, and we restrict layer names to non-conflict names (strong or weak), we need some kind of processing rule
<ntim> miriam: this would be a new rule
<ntim> emilio: conflicting names with conflicting strongness, what happens there?
<ntim> hober: I could live with overriding
<ntim> miriam: neither of the options are desirable, why are we doing this?
<ntim> hober: we shouldn't mess with semantics of author defined names
<ntim> hober: double dash was a hack
<ntim> miriam: what do we gain from this ?
<bramus> `CSSLayerBlockRule.attributeThatIndicatesIfItsStrongOrNot = true | false`
<ntim> astearns: I would like the CSSOM discussion to be separate from this issue
<ntim> hober:This is about semantics more fundamentally, not just CSSOM
<ntim> astearns: we are done with this discussion
<bramus> :(

@mirisuzanne
Copy link
Contributor Author

@hober can you make any argument here that doesn't rely entirely on theoretical purity? Is there any actual advantage to be had for authors, users, implementors, or anyone else if we separate the sigil from the name?

@bramus
Copy link
Contributor

bramus commented Jan 31, 2025

I believe we were close to settling on ^, save for the CSSOM part.

As mentioned in the call, the strongness of a layer can be exposed in CSSOM through a new attribute on CSSLayerBlockRule. That way you can have layers with the same name, but a different strongness. This makes the ^ (or whatever sigil ends up being used) not part of the layer name when you read it back, similar to the to how a . is not part of a classname.

@hober
Copy link
Member

hober commented Jan 31, 2025

@hober can you make any argument here that doesn't rely entirely on theoretical purity? Is there any actual advantage to be had for authors, users, implementors, or anyone else if we separate the sigil from the name?

Coherence with the rest of CSS, in particular ID and class selectors. # and . are not part of the names.

@hober
Copy link
Member

hober commented Jan 31, 2025

I believe we were close to settling on ^, save for the CSSOM part.

As mentioned in the call, the strongness of a layer can be exposed in CSSOM through a new attribute on CSSLayerBlockRule. That way you can have layers with the same name, but a different strongness. This makes the ^ (or whatever sigil ends up being used) not part of the layer name when you read it back, similar to the to how a . is not part of a classname.

That works for me!

@hober
Copy link
Member

hober commented Jan 31, 2025

That way you can have layers with the same name, but a different strongness.

Though this is unfortunate.

@mirisuzanne
Copy link
Contributor Author

Thanks. Could we:

  • Resolve that ^ is syntax, not part of the name
  • Resolve that CSSOM should reflect if a given layer is strong or not
  • Open a new issue (if needed) to discuss disallowing strong/weak layer name conflicts

?

@Alohci
Copy link
Contributor

Alohci commented Jan 31, 2025

That way you can have layers with the same name, but a different strongness.

Though this is unfortunate.

That tells us that strong layer names and weak layer names live in different namespaces. Maybe the CSSLayerBlockRule attribute name should reflect that,

@bramus
Copy link
Contributor

bramus commented Jan 31, 2025

That way you can have layers with the same name, but a different strongness.

Though this is unfortunate.

But that choice is up to authors to make.

Or could also happen by accident: If I author a strong layer overrides and also import a framework that has a similarly named (weak) layer overrides, then that’s that.

@mayank99
Copy link

mayank99 commented Jan 31, 2025

I hate to re-tread older ground, but looking at past discussions, option 3 was never fully rejected. The tradeoffs of options 2 and 3 were discussed, but no resolution.

Option 3 would look something like @layer ^top.overrides, where ^top is a UA-reserved strong layer name, and overrides is an author-defined sub-layer name.

Benefits:

  • More explicit, addressing the concerns re: "Any symbol will be less explicit than an explicit description."
  • Clear namespace separation, so that @layer overrides does not conflict with @layer ^top.overrides.
  • (Theoretical) Provides a convention for adding future UA-reserved layer names, such as ^bottom.

It was said earlier that option 2 and option 3 are the same (which would make this bikeshed), but the namespace separation is an important distinction between 2 and 3 (at least in my mind).

(I'm only mentioning this because it might help with some of the unresolved concerns. Feel free to ignore if it's unhelpful or unviable. I care more about the overall functionality than the specifics.)

@astearns astearns moved this from Friday morning to Friday afternoon in CSSWG January 2025 meeting Jan 31, 2025
@astearns astearns moved this from Friday afternoon to Friday morning in CSSWG January 2025 meeting Jan 31, 2025
@mirisuzanne
Copy link
Contributor Author

mirisuzanne commented Jan 31, 2025

Point two is the most compelling here. That potential namespace collision is the main issue we're left with. (Which seems like a very niche issue to me in practice, since it doesn't come up in the CSS syntax).

As to theoretical future layer features (raised here and on the call):

There are three and only three positions that are fundamental to cascade layers. Two of them already exist. We can have styles not in a layer (unlayered), and styles below those (default layers). There's only one more position available for completeness – above unlayered styles. There is not some arbitrary number of future positions at this level. If we use ^top for the current situation, then we should absolutely never consider ^bottom for anything other than the existing default behavior – which is the clear opposite.

Any theoretical future reserved layer names/features would be dealing with a different level of concern – either contained within those three positions, or extending outside them entirely (as most of the existing proposals have). If we want to leave things as flexible as possible for future developments, I would avoid expanding into a new name syntax for these fundamental positions.

After following that thread, I'm (personally) back where I was, supporting the existing proposal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: TPAC/FTF agenda items
Status: Friday morning
Status: To Consider
Development

No branches or pull requests