[css-cascade] Cascade layers need an import syntax · Issue #5681 · w3c/csswg-drafts · GitHub
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] Cascade layers need an import syntax #5681

Closed
mirisuzanne opened this issue Oct 28, 2020 · 5 comments
Closed

[css-cascade] Cascade layers need an import syntax #5681

mirisuzanne opened this issue Oct 28, 2020 · 5 comments

Comments

@mirisuzanne
Copy link
Contributor

mirisuzanne commented Oct 28, 2020

This issue was raised on Cascade 5.

The current cascade-layers proposal offers several directions.

This also raises some question around ordering of @layer and @import rules. Currently:

  • Layering is determined by source-order of @layer rules
  • @import is required to come first in a document.

Using @layer

The most direct approach would be allowing a url() in place of a {…} code block in the @layer rule:

/* @layer <name>? url(<contents>) */
@layer reset url(reset.css);
@layer bootstrap url(bootstrap.css);

Using @import

It may also be possible to build on the existing @import syntax:

@import layer reset url(reset.css);
@import layer(reset) url(reset.css);

Other options?

Other proposals include creating a new at-rule, or allowing imports to be nested inside the block syntax:

/* new rule */
@layer-import reset url(reset.css);

/* nested imports */
@layer reset { 
  @import url(reset.css); 
}

/* etc… */
@una
Copy link
Contributor

una commented Jan 6, 2021

Are there any conflicts/potential issues with reusing @import? I like the idea of using the same syntax here (i.e. @import url(reset.css) as layer; , but I'm not sure if that will create future conflicts. Does @import function the same as the mechanism for the layer imports?

@w3c w3c deleted a comment Jan 6, 2021
@fantasai
Copy link
Collaborator

fantasai commented Jan 9, 2021

Having reviewed the @layer syntax in the draft, I think I prefer that option to something built on @import. We have both a block syntax and an import syntax, which have different rules about where they're allowed to occur in the stylesheet. But there's also an empty layer declaration syntax @layer name; which if we use a different syntax for layer imports has to have its own special placement rules (so that it can be allowed before @import) rather than just being a degenerate form of the block and import versions. I also think having the indication of the import being a layered import up front, rather than at the end of the rule syntactically, is helpful.

However, whatever import syntax we use, it should have fully identical syntax and capabilities after the @Keyword. @import for example accepts media queries and supports queries; @layer imports should match it exactly.

@una @import differs from @layer because it does not wrap its contents in a layer, merely pulls them into whatever is the base layer of the current style sheet, exactly as if those rules were copy-pasted into the style sheet in place of the @import rule.

@SebastianZ
Copy link
Contributor

SebastianZ commented Jan 10, 2021

@fantasai Please be careful to put at-rules in backticks to avoid mentioning unrelated people here on GitHub.

I also slightly tend to extending the exising @import syntax for the purpose of importing the style sheet into a new cascade layer.

@una @import differs from @layer because it does not wrap its contents in a layer, merely pulls them into whatever is the base layer of the current style sheet, exactly as if those rules were copy-pasted into the style sheet in place of the @import rule.

Is that so? I thought specifying the layer's name is meant to wrap its contents into a new layer under that name.

Sebastian

@fantasai
Copy link
Collaborator

@SebastianZ I think you misread my comment. :) I'm in favor of using @layer for importing into a new layer. I think it should have all the same syntax options as @import, though. Basically identical, except for the @layer part.

@astearns astearns added this to the VF2F-2021-02-11 APAC milestone Feb 2, 2021
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-cascade] Cascade layers need an import syntax, and agreed to the following:

  • RESOLVED: Cascade layer imports is done using @import followed by URL followed by layer declaration
The full IRC log of that discussion <Rossen_> Topic: [css-cascade] Cascade layers need an import syntax
<myles> ScribeNick: myles
<Rossen_> github: https://github.com//issues/5681
<myles> miriam: We have this in the spec as an option for how you write the @layer rule. You can include a URL in the layer. In @layer, and it it works similar to an import. But there have been questions about whether we should instead extend the existing import to allow layer names, or even come up with a 3rd option.
<myles> miriam: A new import layer rule that is different from @layer or @import.
<myles> miriam: What's in the spec now is @layer can take a URL.
<Rossen_> q?
<myles> Rossen_: ok.
<myles> Rossen_: Is that the current proposed syntax... do you just want feedback from the group?
<myles> miriam: Some people had a preference for extending @import. I don't have strong feelings on this. I think it works nicely to keep it all in @layer. We'll need to allow @layer before @import because it's important that layer names are able to be established early.
<bkardell_> I also don't have strong feelings, but I like @import'ing being import I guess
<myles> Rossen_: How does @layer differ from @import?
<myles> miriam: @layer imports a stylesheet into a layer. It allows you to add layering while you're imorting
<myles> fantasai: @import doesn't establish any layers. It just puts rules into the stylesheet as if they are inlined. @layer creates a layer for things inside it, but doesn't inline them. In theory we can say @layer can take @import inside the nested block, but then you have to deal with the fact that @import has to be the first thing in the stylesheet, so it's complex. So the syntax should be "this statement creates a layer and imports a stylesheet into
<myles> it" as if it was @layer with an @import inside it.
<Rossen_> q?
<myles> fantasai: do we use @import with extra syntax? Or do we allow @layer to take a URL instead of a block of rules.
<emilio> q+
<jensimmo_> q=
<jensimmo_> q+
<myles> florian: Sticking to @layer is better. 3 variants: @layer name;, @layer layername {...}, @layer layername url. There is symmetry between 3 variants.
<myles> florian: It's self-contained and clean.
<bkardell_> q+
<Rossen_> ack emilio
<myles> emilio: would that layer syntax have the same restrictions as @import? For appearing before other rules?
<myles> fantasai: yes.
<myles> emilio: *not* doing that means we have to teach prescanners.
<myles> fantasai: It's defined as it has the same placement as @import.
<Rossen_> ack jensimmo_
<myles> emilio: it's ok then
<myles> jensimmo_: It's convenient for authors to put it anywhere, though
<myles> fantasai: @layer name {...} can go anywhere. @layer name url can only go at the top.
<myles> jensimmo_: @layer name url might not need restrictions, which would be valuable
<myles> astearns: Maybe we should use @import for that case, then, to make the restrictions simpler
<myles> fantasai: We already have precdent for putting @layer anywhere. IT's just the one with {} can go anywhere. I'm leaning to have all 3 have the saem syntax for consistency. Because otherwise we would have 2 placement rules, which would be weird.
<Rossen_> q?
<myles> bkardell_: i don't understand something.
<fantasai> s/{} can go anywhere/{} can only go after any importing rules/
<myles> bkardell_: In "other options" there is @layer reset with a nested import. Does emilio's comment mean it's not possible?
<myles> emilio: Please let's make it not possible
<myles> bkardell_: Let's remove that as an option then
<myles> bkardell_: So the options are using @layer or using @import. that's it.
<myles> bkardell_: I'd like @import to be about importing, and having a special version of import which can also create a layer. But I don't have strong feelings.
<Rossen_> q?
<Rossen_> ack bkardell_
<myles> fantasai: This is a naming discussion.
<myles> Rossen_: Yes and but it feels like a bit more. @import is already rather understood and well-used by the community.
<myles> Rossen_: Having yet another mechanism to import seems odd.
<myles> florian: We're having yet another mechanism to import anyway. We're just discussing syntax.
<myles> Rossen_: Explicitly yes.
<astearns> either one is fine by me - slight preference for @import
<myles> Rossen_: Alright, so. Let's try to move this forward and get to a conclusion. Most people were in favor of @layer. A few who prefer @import to be used for import: namely: bkardell_ and Rossen_ . But for me it's just a preference; I can live with @layer.
<myles> bkardell_: You articulated the way i feel. I feel like people understand the limits of @import, and we have machinery to do those limits already. Playing into that is goodl.
<myles> emilio: Another benefit of @import is we don't have to come up with OM thing to hold stylesheets. I lean toward re-using @import
<myles> astearns: We need OM changes anyway
<myles> emilio: We need to change the conditon. We have a proposal for @import-supports. So we need to expose that "import conditoin" or "import layer" but that seems like an easier change than exposing a CSS layer rule that may have a URL or not, and may have an inner block or not, or inner stylesheet or not.
<myles> Rossen_: That was the motivation behind my preference as well. They have the same behavior from importing POV. In the future, when we extend @import, we have to make a parallel change in something else too.
<myles> emilio: That's a good point. We have proposals for @import-cross-origin to maek cross-origin requests. WOuld be good to not duplicate
<myles> TabAtkins: I agree, and am strongly for using @import.
<jensimmo_> q+
<myles> florian: There are variants. @import layer (name url). Or @import url as layername. Which is more readable, but couldn't deal with unnamed layer (unless we add a new keyword meaning "import as unnamed") which wouldnt' mean "import into the layer named 'unnamed'" but instead "import into unnaemd ...."
<argyle> https://github.com//issues/5681#issuecomment-755513963
<myles> Rossen_: what are you talking about
<myles> florian: Una suggested something that seems both more readable and not working in the unnamed layer case.
<florian> @import layer reset url(reset.css);
<florian> @import layer(reset) url(reset.css);
<florian> @import url(reset.css) as layer;
<Rossen_> q?
<argyle> `@import reset from url(reset.css) as layer;`?
<myles> jensimmo_: There are 2: one is to add another keyword or whatever it's called to the import statement to say which layer it goes to, and the other which is about nesting @layer reset (@import url). I keep going back and forth. THere's something about how clear it is that you start a layer, when you define a layer, you import a stylesheet. THat's appealing. But I also understand the keyword would still work well.
<Rossen_> ack jensimmo_
<myles> jensimmo_: I'm leaning toward nesting.
<myles> Rossen_: Now we're swinging the other way.
<Rossen_> @import layer reset url(reset.css); @import reset url(reset.css) as layer; @import layer(reset) url(reset.css);
<myles> fantasai: My preference would be for whatever syntax we choose to have the word "layer" in there somewhere. We need a way to have unnamed layers for parallelism. MOst of the parameters for our @import rules come after the @import rules (conditions, parsing) is a little bit open-ended. It might make more sense to do this before the URL and it also brings up tot he front and makes it obvious "we are making a layer with this URL". SO my preference is
<myles> one of the earlier options.
<myles> Rossen_: I pasted the 3 variants that are in the issue.
<myles> jensimmo_: por que no los dos?
<myles> Rossen_: <lists the 3 options verbally>
<myles> emilio: Can we add a 4th one? @import url something something layer(something)
<myles> emilio: reasoning: that's how the extra things to @import work already. like media queries.
<myles> fantasai: THat would parse as an invalid media query, and it would get imported anyway whether or not you support layer
<Rossen_> @import url(reset.css) as layer(reset)
<myles> emilio: We have that issue for the proposed @supports function, right. I'd like to have the mandatory parts at the front, like @import url, then the optional stuff like the conditions
<myles> Rossen_: where does the @support go in this case.
<astearns> what was the 'both' you were asking about, jensimmo_ ?
<fantasai> https://www.w3.org/TR/css-cascade-4/#conditional-import
<myles> emilio: I think we resolved on this at the end, but it's not in the spec. It goes where the media query goes. Which is weird cause you text can mean either
<myles> Rossen_: Without dumping the whole issue into this one, wasn't the issue to have @supports evaluated so you're not hitting the network? The current solution is to have @supports at the end?
<fantasai> https://www.w3.org/TR/css-cascade-4/#at-import
<myles> emilio: yes. We added an @supports function.
<fantasai> Current syntax is @import [ <url> | <string> ]
<fantasai> [ supports( [ <supports-condition> | <declaration> ] ) ]?
<fantasai> <media-query-list>? ;
<jensimmo_> Could we do `@import layer(reset) url(reset.css);` AND `@import url(reset.css) layer(reset) ;` AND @layer reset {
<jensimmo_> @import url(reset.css); }
<myles> emilio: With the function syntax it's possible. You just determine if it's this function or not, and if it's not, then assume it's something else.
<myles> jensimmo_: What is the precise syntax for namign the layer? I like haivng layer() and reset. THat would allow us to use layer with 2 parens and no name and leave it blank to do what fantasai was metnioning to assign it to a named layer without it being too messy. And having the name of the layer an argument to a function, it might not matter which name comes first
<myles> jensimmo_: I also was trying to say, would it be possible to do an import statement with a way to namet eh layer *and* CSS does both so authors cna pick which ever way they want to do it, or and the nested @layer { @import ... }
<Rossen_> q?
<Rossen_> ack f
<florian> q+
<myles> fantasai: My concern with the nested one is you'd be tempted to put declarations there. IN theory you could do that once, but then you coudln't put further @import rules. So then you 'd have @layer blocks which don't include any declarations, and if you do, then it becomes invalid, so it will be confusing. I dont' want to give the author the impressino they can put rules in the block. they can't do that.
<TabAtkins> @import currently has a req that it comes first in a file, which lets impls pretend that the imported files are ordered fully before its importing file (they dont' have to track nesting of imports for purpose of figuring out source order of declarations)
<Rossen_> ack f
<myles> florian: Assuming we go with @import, esp. for extension ability. It shouldn't be after the rule. Because it's syntactically ambiguous with media queries. We don't want something to parse both as a layer and as a media query, that's bad
<myles> emilio: we already do that with supports, right?
<fantasai> Also, everything after the URL is currently a condition. This isn't a conditional.
<TabAtkins> @layer { @import} doesn't impose this restriction.
<myles> emilio: fantasai pasted the supports syntax now. It would only be ambiguous if you add a layer() function into media queries. but not otherwise
<myles> florian: But supports and layer are conditional things, they belong in roughly the same place, so i'm still uncomfortable with thtat, but less so
<myles> emilio: I don't mind much either way. It would be slightly nicer, given all browsers have bespoke @import preload parseing, and scan for literally "@import string" and then preload that, I would be slightly happier if we didn't have to add harder parsers, because that code is pretty ugly already.
<myles> emilio: I don't know.
<myles> Rossen_: Let's try to resolve.
<fantasai> Wouldn't you want your speculative loader to parse conditions on the @import?
<myles> Rossen: Let's try to record a resolution here. It will be easier to revisit the specific syntax of where the layer declaration goes if we're not happy with it later, but at least it seems we're all leaning toward where the declaration goes with @import.
<myles> Rossen: emilio, your proposal is @import url layerstuff?
<myles> emilio: <silence>
<myles> Rossen: Is that something we can start working with?
<myles> s/emilio: <silence>/emilio: yes/
<emilio> fantasai: yeah, that is right (I think right now we just don't preload conditional stuff)
<jensimmo_> @import url(reset.css) [layer stuff];
<myles> RESOLVED: Cascade layer imports is done using @import followed by URL followed by layer declaration
<jensimmo_> @import url(reset.css) layer(reset) ;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants