-
Notifications
You must be signed in to change notification settings - Fork 162
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
Allow authors to apply new css features (like cascade layers) while linking stylesheets #240
Comments
I wanna add that I believe this is absolutely crucial for the adoption of Cascade Layers. Authors are conditioned to avoid the
Stylesheet authors may not be able to use @import at all, or they might not be able to change how a different external stylesheet enters the cascade all together, either because they don't have access to the processes that provide the stylesheets, or because the created stylesheet just doesn't exist to be imported, because it is being created as part of an obfuscated, optimised build-process, that will end up linking stylesheets in an automated process as well. As the order of the cascade layers can be declared in the stylesheet that authors can author, according to spec, this would allow authors to clearly separate incoming, external rulesets. This is important, because most authors currently will rely on a preprocessor such as SASS to split code into partials because authors are engrained with negative connotation for @import's, as mentioned at the beginning. Because of that, switching to cascade layers will feel like a big cost that many authors might not want to pay. But they might be, if they can do it with I personally also believe that there is a specific case to be made for refactoring sites that rely on multiple libraries. As approaches change with trends and needs, allowing Authors to assign existing, incoming stylesheets to a dedicated layer from where they are linked may allow authors to better differentiate between existing code and new code. Tooling will adapt to working with cascade layers, maybe even providing a visual support to aid with it. |
I wonder if the Right now,
On the one hand, it seems handy to re-use an existing attribute rather than minting a new one. On the other hand, it could be quite confusing for the same attribute to be used for two different purposes:
|
Heya, thanks for opening this. I appreciate the focus on use cases. Let's talk about how to solve them, and in particular how far we are from a solution in today's world. From what I understand, the functionality is available today with
Is that right? If so, the traditional next steps in this sort of situation would be to clarify the performance issue, since that seems to be at the root of most of the problems (except for the last?). For that, I'd suggest benchmarks comparing a prototype implementation based on For example, I know Chromium did some implementation work that was supposed to ensure that |
There might be some interesting advantages to encouraging more use of the <style>
/* establish layer order */
@layer reset, default, theme, framework, utilities;
/* import styles into layers */
@import url(theme.css) layer(theme);
@import url(utilities.css) layer(utilities);
/* etc… */
</style> I'm not sure which browser engineers to ping here for input on that approach, and the performance issues. In the CSSWG issue, @yoavweiss suggests that:
@adactio, an attribute solution (new or existing) would need to invalidate the entire import for browsers without layer support - otherwise the fallback path is very unpredictable. Would that be true with I know there's also been suggestions of having a new |
That is right. I am sorry I couldn't form a usecase that makes sense enough or if it just didn't make much sense. Maybe I can draw up a more comprehensive case, and once I do, I will follow up here. I am myself currently working on a projects that generates CSS without having any control over how it comes into the markup itself. The point I am trying to make is that we cannot assume that authors will @import external stylesheets. From the point of view of an Author, I see no reason for why I shouldn't be able to also define a layer when liking a stylesheet. It just seems incongruent to limit this feature to the stylesheet itself. Existing projects may have several stylesheets linked in a given document (global declarations, font-face declarations, declarations dedicated to theming), reworking the architecture and maybe even build-processes may seem too costly to support this feature. But I might be able to assign these existing stylesheets to layers, so that I can more clearly separate their concerns, especially for future reworks. Let me know if this makes a bit more sense to you. English is not my first language and I find it a bit difficult to describe this topic sufficiently enough so that it makes sense. Luckily I think the other points raised by @mirisuzanne are already strong enough on their own - at least I hope so! :) |
In that case it seems like you could not use any new markup-based solution (e.g. |
Ah yeah, that is a great thing to bring up. My person from Gecko to ping for style issues is @emilio; for WebKit I think @smfr? Anyway, if such folks generally agree that the fragility/difficulty of tokenizing CSS (instead of HTML) in the preload scanner is significant enough that we'd want to invent a new markup pattern, then that's a very helpful signal. The biggest costs I can think of a new markup pattern, beyond the usual costs of implementation/tests/developer outreach, are the security interactions. E.g. if people are using dumb HTML sanitizers that somehow the new markup pattern would bypass, that can be tricky. And we'd need to think through and test integrations with existing security primitives like CSP. These are not blockers, but just costs to be weighed.
Unfortunately no;
Agreed, we should definitely solve the future-additions problem if we go that route. Any ideas in that direction would be welcome. |
One idea might be having one or two more generic attributes that get
While it's nice to have things split into more individually meaningful attributes, this seems like the clearest way to make it forward-proof, and allows authors to match syntax between the two types of importing. |
Yes that is correct, but - and maybe I am overthinking this - in that scenario, the tool that doesn't write the actual css but does split it up and does write the HTML code could also add
But example 31 also says:
The way that I see it, is that allowing tools which automatically add stylesheets via I think I can provide two examples to make my case, though whether or not layers actually are a viable solution in these scenarios I can only determine hypothetically: In the first example, I worked on a large dynamic website that was built on top of the Zend framework. Forms where generated using the Zend Form library. Now as soon as forms where used and client-side validation was set, it also added its own stylesheet (and javascript) to render validation error messages. We couldn't touch the file without essentially ripping the plugin out of its package manager, but zend did provide us with ways to define how stylesheets like these did converge in the final document (it's been a minute, but I think it was called headLink or something), which accepted a list of parameters. In that case, we could have declared a In the second example, which is more recent, I worked on a Vite powered project. Vite asserts full control over an index.html file and in the case of this project, it was crucial, that it also controlled how stylesheets where split, merged and linked with the document in the HTML. It didn't write any actual CSS, but it did process stylesheets from npm managed packages, which we can't just @import in css, but the build tool can process it. It did however make decisions that ended up affecting the styles based on whether it ran in production or development mode. In development, whatever order was defined by the authors was left intact, because it didn't fully process the referenced files. But in production, it did - and it also all of a sudden changed the source order of the stylesheets. It also merged two files together, I guess because it determined it to be better so - but the point is, that because of the changed source order, some page-specific styles didn't override global styles and some global styles didn't override vendor styles. With the capability of simply declaring a |
Firefox definitely has a preload scanner of sorts, fwiw, and we do scan for You can already put ~whatever at the right of an import rule, and I think right now we'd preload it. It's of course less precise than So we can just ignore |
I filed https://bugzilla.mozilla.org/show_bug.cgi?id=1750917 for that fwiw. |
So, in w3c/csswg-drafts#2463 we just resolved to add I don't know if This is layering unimplemented features on top of unimplemented features, which is normally a problem, but in this case it's fine for things to fail if they're not understood or if they're understood but @layer isn't supported, and so that should work I believe. |
@tabatkins are you proposing that we would then add a new attribute for |
Yes. (Notably, this is only going to be required until |
I would be ok with that approach. But I may have been wrong about the |
So to make sure I'm understanding, the proposal is something like: <link rel="stylesheet" media="@supports at-rule(@layer)" layer="foo" href="bar.css"> which will fail to parse the value of <link rel="stylesheet" layer="foo" href="bar.css"> That does seem pretty nice. And I think it generalizes to other features in the future, as long as they're I guess the fact that <link rel="stylesheet" media="@layer(foo)" href="bar.css"> if we are comfortable abusing |
Following the grammar of @import, it would be I don't think we should invent a novel microsyntax here. |
This only requires extending I agree we don't want a micro-syntax for layers only, but the other similar solution along these lines - maybe even a bit more extensible - would be to say that |
Which legacy parsing constraints? The html spec says |
To summarize then, it sounds like the preferred direction would be extending the <link rel="stylesheet" media="layer(foo)" href="bar.css"> From an author perspective, I think the ability to share a single syntax between CSS & HTML would be amazing. The only downside I see is the name of the attribute, but that feels workable/teachable. (If there is ever a move to e.g. I'd be interested in thoughts from @emilio and @smfr. (Also curious what the next steps are here in terms of WHATWG process?) |
https://whatwg.org/working-mode#changes and in particular https://whatwg.org/working-mode#additions may be helpful. I'd say the two biggest to-dos are confirming multi-implementer interest (lots of implementers seem involved in the above discussions but they haven't explicitly said "yes we'd implement this particular solution") and writing a spec PR/web platform tests PR. It may be the case that writing the spec PR helps implementers be more confident about what they're agreeing to, so I would personally tackle that first, but on the other hand it could end up wasted effort if they are not interested. So the exact ordering between those is up to the contributors. |
Late to the party...
@emilio - thanks! I stand corrected. All this to say that I'd significantly prefer the proposed markup solutions. /cc @xiaochengh - for potential opinions on implementing the above. |
This idea looks the best to me
This has a con that it makes the |
I'm not sure what you mean by this, Miriam is just saying that we define it in a way that allows for CSS to add more conditional types to @import and have them automatically work, rather than manually copying over the current @import grammar and freezing it until we manually update it again. Maybe you're confusing this with the suggestion from Domenic that we add a
Oh good, I had a half-remembered idea that |
I'm talking about the |
Yeah, |
Good, because that was an offhand suggestion by Domenic, and both me and Miriam said we didn't want it. ^_^ |
HTML4 did that. I don't know when it was dropped from the living standard. |
@tabatkins That's not a new microsyntax they're responding to, the |
Oh! Okay, right, so then I agree that should be left out; we just want to carry the conditions over. The We can easily rearrange the @import definition to name the condition part in a way that makes it easy to reference from HTML. |
Then the proposed spec changes would be:
The long-term syntax is: <link rel="stylesheet" layer="foo" href="bar.css"> And the transitional syntax for handling browser support is: <link rel="stylesheet" layer="foo" media="supports(at-rule(@layer))" href="bar.css"> |
Should this thread be moved to whatwg/html or will you start a new one there with a summary? Maybe the latter is better at this point? |
So... am I understanding this right that with this new syntax, not only can we declare layers for linked stylesheets, but we can even detect support for them, which we can't do in regular stylesheets at the moment? |
@nachtfunke The By having |
@annevk that's my mistake, being new to the WHATWG repos. Happy to move or summarize in the other repo. I can do that this afternoon. I think at this point we've reached a general consensus on the approach, from people participating? Even though I'm not sure we have official sign-off from implementors, we at least have good input. I'm happy to start on a spec PR (and then platform tests), to get more detailed feedback there. Thank you all! |
@mirisuzanne sounds great. (If you're interested in a general introduction to the WHATWG, https://whatwg.org/working-mode and https://whatwg.org/faq might be useful.) |
Let's continue discussion in whatwg/html#7540. Thanks @mirisuzanne! |
The CSSWG recently added a feature to CSS called Cascade Layers. It allows authors to more explicitly manage the cascade behavior of styles from different parts of a design system. That can be done using
@layer
blocks in the code, but in many cases authors will want to wrap entire (sometimes third-party) stylesheets into layers at the time they are linked/imported. The new CSS spec makes that possible with additinoal@import
syntax - but the@import
rules tends to be less performant than the HTML<link>
tag. For now, the best authors can do is use@import
inside HTML<style>
:Use cases
A few variations on the layer use-case include:
Cascade Layers are already supported in preview/beta versions of Safari, Chrome, and Firefox - and we expect them to appear in stable releases over the next few months. But the lack of HTML link support has been one of the largest points of concern/feedback from authors, and one that we can't address from the CSSWG.
Constraints
At first glance it may seem like this could be solved with a new
layer
attribute on the<link>
tag, but it would cause problems for old browsers that simply ignore the attribute, and continue to the load the stylesheets without any layering. Whatever solution we land on needs to allow authors more control over the fallback path for old browsers.It might also be good to plan for this sort of situation down the road, if we're able to find a solution that can potentially be used again for new features in the future?
(I'm sure I missed some useful information here, so feel free to ask questions!)
The text was updated successfully, but these errors were encountered: