-
Notifications
You must be signed in to change notification settings - Fork 676
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] Proposal: @layer initial
should always be the first layer
#10094
Comments
@layer initial
always being the first layer@layer initial
should always be the first layer
In general, "special syntax to make something go first" isn't very composable. Things end up fighting over being first, the set of things putting themselves first still needs to establish a relative ordering. You just kick the bucket of "it's hard to coordinate" a little bit down the line, but not very far. On the other hand, we have had multiple proposals for something like So this might indeed be reasonable, just establishing that there's a specific layer that's always defined and before all named layers. Some specific comments:
|
It can be useful when the top layer is set up by someone else, such as when a stylesheet is imported into a layer. It would be confusing if the behavior of // In foo.css
@layer A, B;
@layer A {…}
@layer B {…}
@layer initial {
/* expected to go before A and B, normally */
} @import "foo.css" layer(foo);
/* foo.initial now comes after foo.A and foo.B 🙁 */ Of course there is a workaround, so maybe not a big concern. @layer initial, A, B; |
I was thinking about this again, and I'm starting to wonder if we need something like Let's think about CSS resets again. Most sites do something like this today: *, ::before, ::after {
box-sizing: border-box;
margin: 0;
} This has low specificity and can be de-prioritized further using <my-component>
<template shadowrootmode="open">
<style>
/* This gets overridden by our reset 🙁 */
:host { margin: 1rem }
</style>
<slot></slot>
</template>
</my-component> What if we instead allowed authors to put styles in a context that precedes all other contexts? This would be the ideal place to put resets and default styles. @context defaults {
*, ::before, ::after {
box-sizing: border-box;
margin: 0;
}
} To take this one step further, it would be equally useful to have a context that comes after all other contexts. This would be a great place for e.g. browser extensions to put user styles (see #7535/#6323). For this to work, we'd need either pre-determined names or a different at-rule. @context(first) {
/* resets/defaults go here */
}
/* all regular styles will fit in between */
@context(last) {
/* user styles go here */
} There's a lot of bikeshedding opportunities, but hopefully the idea is clear: |
I find the
So your proposal would result in…
But if styles can be added to a first/last context from either the light or shadow DOM… does their originating context still come into play? Or do we now ignore the shadow/page context, and conflicts within first/last have to continue in the cascade?
|
@mirisuzanne Thanks for looking into this. If you think this idea has legs, should I open a new issue specifically for
I want to say the originating context should not matter because it's a totally different context. The alternative would be that
We could also have something built into
I only picked "context" because it seems like the right layer (no pun intended) to place "first"/"last" styles. What would be other ways of solving the problem I described in my earlier comment? Is it possible to make |
Based on #6323 (comment), I guess the original proposal in this thread could also be renamed to something like I still think the It makes sense to place it before presentational hints, because I expect default styles to have the lowest priority in the author origin, and be overridden by preshints. As an added benefit of this, the behavior of |
Problem
Currently, layers all need to be explicitly defined. This means the page author needs to be very disciplined in setting their layer order upfront, before adding any “real” styles.
This almost always involves creating a layer named something like “defaults” early on.
This works, but is problematic for a few reasons:
@layer defaults
can potentially declare layers that come first.defaults
if they want to declare low-priority styles later.defaults
layer.Proposal
Allow authors to declare all low-priority styles in a layer named
initial
.initial
is one of the layer names that are "reserved for future use", so this layer can be automatically set up by the browser, such that:@layer initial
exists implicitly, regardless of the page’s layer order, similar to the implicit “outer” (unlayered) layer.Polyfill
In my testing, I found that the three major browsers do not do anything special to the “reserved” layer names, even though the spec says these must be invalid at parse time. I initially thought this was a bug and/or maybe the spec should be changed (see #10067), but then I realized that the current browser behavior makes this feature somewhat easy to polyfill, by setting
@layer initial;
as the very first style. This could even be done automatically by frameworks.Use cases
This solves all of the problems described above, and makes cascade layers easier to incorporate into existing workflows.
initial
layer, without having to come up with a carefully-coordinated layer setup.@layer initial
will provide a canonical way to deprioritize certain styles. It "always works" and is not impacted by order of appearance or existing layer architecture.@layer initial
, with a guarantee that they will cascade first, regardless of how/where they are imported.initial
layer.@layer initial
for their default styles, even though.adoptedStyleSheets
is ordered after the inner context’s own.styleSheets
.initial
layer will still cascade before the shadow-root's layered and unlayered styles.Open questions
initial
also be implicitly set up for nested sub-layers? (I think yes)initial
?The text was updated successfully, but these errors were encountered: