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

Allow authors to apply new css features (like cascade layers) while linking stylesheets #7540

Open
mirisuzanne opened this issue Jan 27, 2022 · 50 comments
Labels
addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest topic: style

Comments

@mirisuzanne
Copy link

mirisuzanne commented Jan 27, 2022

I opened this issue in the wrong repo initially, so summarizing that conversation here:

The problem

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>:

<style>
@import url(reset.css) layer(reset);
@import url(default.css) layer(default);
@import url(bootstrap.css) layer(framework);
@import url(theme.css) layer(theme);
@import url(utilities.css) layer(utilities);
</style>

Use cases

A few variations on the layer use-case include:

  • importing third-party tools (resets, bootstrap, etc) into a specific locally-defined layer
  • JS frameworks loading linked component styles into appropriate layers
  • loading styles from different parts of an organization (design system, component library, application) into layers
  • using CSS conventions like Harry Roberts Inverted Triangle CSS, across multiple stylesheets

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?

[In the other thread we also encountered the constraint that extending media should not go beyond conditions that result in a boolean - so we're in favor of adding support() syntax to the existing attribute, but not in favor of adding layer() to the same attribute.]

(I'm sure I missed some useful information here, so feel free to ask questions!)

Proposed Solution (from discussion)

The proposed spec changes would be:

  • Extend the media attribute to support all 'import conditions' (I suppose we could clarify that term as a part of the CSS syntax to be referenced)
  • Add a layer attribute…
    • Attribute value is treated as a layer name
    • Empty value creates a new anonymous layer

The long-term syntax for adding a layer 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">
@annevk
Copy link
Member

annevk commented Feb 15, 2022

cc @whatwg/css

@myakura
Copy link

myakura commented Feb 15, 2022

<link rel="stylesheet" layer="foo" media="supports(at-rule(@layer))" href="bar.css">

This still fetches bar.css, right? or will this media attribute extension allow UAs to fetch stylesheets conditionally?

@tabatkins
Copy link
Collaborator

Yeah, that's the intent - it's how @import works (browser can speculatively fetch imports conditioned on @media, but must treat @supports as a strict gate). That'll probably end up needing some clarification.

@kevinwhoffman
Copy link

WordPress is another use case where applying CSS cascade layers via linked stylesheets could greatly accelerate the use of layers across the web.

/* Imagine if WordPress core could separate all of its enqueued styles into logical layers. */
@layer core, themes, plugins;

Why CSS Conflicts Are So Prevalent in WordPress

As someone who writes CSS for a distributed WordPress plugin, I cannot predict what other themes, plugins, or frameworks will add styles alongside my own. As a result, CSS specificity and source-order conflicts have long been a major pain for WordPress theme and plugin developers who write clean CSS, only to have their styles lose out to greedier selectors in other themes and plugins.

The Need for Widespread Adoption of Layers in WordPress

The success of CSS cascade layers in an ecosystem like WordPress depends on whether developers can reliably count on other themes and plugins to also use layers in a logical manner. If not, un-layered styles will continue to trump the responsible use of layered styles, and even those developers who are ready to adopt layers will feel the need to continue using high-specificity selectors of their own to defend against conflicts.

But what if WordPress core could logically assign layers to the styles that are enqueued through its content management system even if the styles being loaded do not use layers internally?

This is where assigning layers via <link> comes into play.

Driving Adoption Through WordPress Core

In WordPress development, the recommended method for enqueuing styles is to use the PHP function wp_enqueue_style() which in turn generates a <link> element on the page.

If it was possible to assign a layer with a <link> element, then WordPress core could do much of the heavy lifting necessary to implement layers in the WordPress ecosystem. Theoretically it could detect whether WordPress core, or a theme, or a plugin is responsible for enqueuing the stylesheet and attach a core, themes, or plugins layer accordingly.

In the past, we have seen that driving change through WordPress core has greatly accelerated the adoption of new browser features such as responsive images and the use of srcset. WordPress core could have a similar impact on the widespread use of cascade layers if it is possible to assign layers through <link> elements.

@mirisuzanne
Copy link
Author

In the draft PR @domenic asks:

So to double-check, do we have implementer buy-in for changing not only link and style, but also meta and source? I think it's best if we change them all, for consistency. But it is extra work, and some implementers might not be excited about doing that extra work so that you can do conditional meta theme colors.

I suppose that's a question for @emilio, @lilles, @xiaochengh… someone from Webkit?

@emilio
Copy link
Contributor

emilio commented Aug 5, 2022

@anttijk / @heycam / @nt1m would probably be reasonable points of contact from WebKit.

So having import conditions (supports / media) everywhere consistently makes sense.

But I'm not sure how that ties to cascade layers or <meta> / <source>? The layer is not quite a condition, is a modifier. It makes sense on <style> and <link>, but not on <meta> / <source>, right? What am I missing?

@domenic
Copy link
Member

domenic commented Aug 5, 2022

To clarify, I was asking this question because this PR changes the behavior for <meta> and <source>'s media="" attributes, so I wanted to check we have buy-in for it. I don't actually know what the use case would be for that.

@heycam
Copy link
Contributor

heycam commented Aug 5, 2022

If supports(at-rule(@layer)) is a valid media query, then it should work in <meta media> and <source media> too, for consistency. Is there any need for a change on the HTML side for this to work though? I would've thought that adding new media queries to css-conditional would be enough.

Regarding the transitional state: if supports(at-rule(@layer)) is not something that's supported yet (it's not, right?), then I don't think we should suggest authors write <link rel=stylesheet media="supports(at-rule(@layer))" layer=... href=...>, if we can ship support for the new layer attribute at the same time (or earlier) than at-rule().

@emilio
Copy link
Contributor

emilio commented Aug 5, 2022

Ah yeah, that should work, I thought the meta/source bits were also about layer= attributes

@mirisuzanne
Copy link
Author

Sorry, let me fill in some missing context. (This was discussed previously in a thread I opened on the wrong repo.) The proposal starts with a new layer attribute to the <link> element, which would allow assigning styles to a layer. As you point out, that's enough for modern browsers. When browsers add support for the layer attribute, it will work as expected.

The problem is with older browsers, and the desired fallback behavior when the layer attribute is not supported. By default, old browsers will ignore the new attribute, and load the stylesheet without applying layers. That will have dramatically unexpected & unpredictable consequences.

The only way we know to avoid that is by having authors write a currently-invalid media. Since linked styles with invalid media are not loaded, that will hide the stylesheet from older browsers - and only make it available in a browser that supports both the extended media and also cascade layers. So we've proposed extending the media attribute to allow all 'import conditions' as defined on the @import rule: both media-query and support-query conditions.

If we don't provide a solution that hides layered styles from old browsers, authors will need to fake that behavior, likely using a similar syntax and manually updating the media attribute with JS based on the result of testing support for @layer.

But if we take this approach, the solution becomes re-usable for similar situations in the future. For example, the CSSWG is already working on an @scope rule, and there are already requests to allow scoped imports. Again, it would be a problem to have scoped styles applied without their scope, so authors will need a way to ensure browser-support for any new attributes. With this extended condition functionality on media, authors can again add eg media="supports(at-rule(@scope))" in order to ensure old browsers don't load scoped styles globally.

@heycam
Copy link
Contributor

heycam commented Aug 5, 2022

So we've proposed extending the media attribute to allow all 'import conditions' as defined on the @import rule: both media-query and support-query conditions.

I see, in the @import rule syntax definition, support(...) is not a kind of media query. It's a separate thing. I thought we had added a support(...) function to media query syntax so that authors can write e.g. @media (width > 500px) and support(color: rainbow) but I must be mis-remembering.

@heycam
Copy link
Contributor

heycam commented Aug 5, 2022

But if we take this approach, the solution becomes re-usable for similar situations in the future.

I think it's totally reasonable to have an approach like this available for future, similar situations. I just am not sure it's strictly necessary for detecting cascade layer support, since engines will need to ship at least one of { layer attribute, new support(...) } syntax for authors to avoid the script-based fallback, so we may as well try to ship the layer attribute first so that there won't be a period where authors have to write media="support(at-rule(@layer))".

@emilio
Copy link
Contributor

emilio commented Aug 5, 2022

Since linked styles with invalid media are not loaded, that will hide the stylesheet from older browsers - and only make it available in a browser that supports both the extended media and also cascade layers.

This is not true, for what is worth: The stylesheet is loaded, but not applied because the media query doesn't match. It still appears in document.styleSheets, etc, and wastes network traffic.

As far as I know this is a compat requirement too, because lots of old "load styles async" solutions use it:

https://github.com/filamentgroup/loadCSS/blob/c14df53ebed55d4d06490d19bbc0265e2af19b98/src/loadCSS.js#L35

(It might be still worth doing, just wanted to point out the trade off might be a bit different)

@mirisuzanne
Copy link
Author

@emilio Sorry, yes - loaded but not applied. That still has the intended behavior in this case.

@heycam The point of using media is exactly that browsers don't have to do anything for this new media syntax to block styles from being applied immediately. Authors can already add media="support(at-rule(@layer))" to a link attribute, and that will block the linked stylesheet from being applied. With that approach, there's no need for any scripting at any point. The lack of support for supports-in-media has the desired impact. Styles with that combination won't be applied until browsers support both layers and support-queries-in-media.

@heycam
Copy link
Contributor

heycam commented Aug 5, 2022

Styles with that combination won't be applied until browsers support both layers and support-queries-in-media.

Of course, that makes sense. Thanks for spelling it out.

In terms of the mechanics of allowing support() inside <link media> and other media attributes, if I am mis-remembering that the CSSWG has already discussed having a support() function in media queries, and we agree that for consistency all media attributes should support support(), then it might be worth considering baking it in at the MQ level.

@mirisuzanne
Copy link
Author

As far as I understand the conversations/resolutions so far:

  1. There is a @supports rule similar to media-queries, but distinct from @media – that's where the at-rule() function is defined
  2. There is a supports() function that has been added to @import along-side media-queries (but not as part of the media query) – see https://drafts.csswg.org/css-cascade-5/#typedef-import-condition (this is what we're hoping to use)
  3. There's been discussion of a joint @when rule with both media() and supports() functions, but that is currently stalled by a debate about the name of the rule

But (as far as I know) there is not a supports() function that can be used inside @media queries. If that is happening, I agree it would solve the problem without changes to the media attribute – but I haven't seen it.

@o-t-w
Copy link

o-t-w commented Aug 6, 2022

And the transitional syntax for handling browser support is:

<link rel="stylesheet" layer="foo" media="supports(at-rule(@layer))" href="bar.css">

While it's true that there will be "dramatically unexpected & unpredictable consequences" in browsers that don't support it, is it really a good solution to just not include the styles at all? Wouldn't it be better if browsers just added the "long-term syntax" as quickly as possible and developers waited until they're happy with the level of browser support to use it? It doesn't feel like there's any great solution for old browsers so I don't see why it's worthwhile to cram in new syntax like this.

@mirisuzanne
Copy link
Author

Yes, it is best if authors can choose to only load layer-based styles when the layer attribute is supported. Authors still have the option to 'just wait' - but (when that's the only option) it often turns into an indefinite waiting period, where it becomes 'best practice' not to use a new feature 'yet', and that becomes a hard narrative to reverse. We have consistently found in CSS that it is best when authors can use feature detection, and make conditional style choices based on those results. This is a much-needed feature that CSS has had for years, not specific to layers or even at-rules, and it would be generally useful if the feature was also available in HTML.

This isn't a one-off syntax for layers, and it isn't particularly being 'crammed' anywhere. This exact syntax already exists in CSS, and is available anywhere CSS stylesheets are being imported - including the fact that supports & media queries are allowed side-by-side in the same syntax. This proposal brings HTML links more closely in line with the current functionality of CSS, using exactly the same syntax as CSS (but in an attribute), and will be useful for authors any time they want to do feature-support detection, now and into the future.

@xiaochengh
Copy link
Contributor

Re #7540 (comment):

Extending the media attr syntax also for <meta> and <source> makes a lot of sense to me. I can imagine cases like making conditional theme colors when there's a new color function introduced but not fully supported yet.

@jacobrask
Copy link

media="supports()" is great feature, but tying it to the simpler layer attribute change seems to be one reason for the stall on layer, which is also a useful feature in itself. Assuming @layer support should be safe within the next year or so for a lot of sites anyway, so the sooner we get the layer attribute the better.

@bramus
Copy link

bramus commented Jun 20, 2023

This issue seems to have stalled. Is there extra info needed to get the ball rolling again? By the looks of it, I think we all agree that adding media="supports()" makes sense – even well outside of the layers problem space that triggered this.

@mirisuzanne
Copy link
Author

This has stalled on my end for a few reasons:

  • It touches a number of different specs from HTML to CSSOM, conditional-styles, and cascade. Some of the interactions between those specs are complicated, and a bit difficult to parse or update.
  • I am not an editor on most of the specs involved, and very unfamiliar with several of them. For me alone, it's a big lift. Maybe it would be less of a lift for someone else?
  • As far as I can tell, there's no way to get a 'resolution' in WHATWG without all the specs being drafted, and a PR that several browsers agree to. Since people (including browser engineers) raise concerns every time it comes up here, it's hard to motivate a deep dive into untangling all the specs involved without a clear sense that people agree on the approach.
  • Since it spans two different orgs, there's been no joint conversation agreeing on the direction from both sides. That's why I suggested we add it to agenda for a joint meeting at TPAC.

I would love to see this move forward. I don't feel like I'm in a position to make that happen on my own at this point. I would be happy to pick it up again with some help on the various specs, and some more clarity that this is an approach browsers will implement.

@emilio
Copy link
Contributor

emilio commented Sep 18, 2023

@zcorpan what does that give you that renaming this to <style-sheet-condition> or so and referencing that everywhere doesn't?

With your proposal it feels rather weird to be able to do @media supports(), and you'd need to track the "supports" result across the whole condition tree, which is a bit odd. So we'd need to convert the media query evaluation to track not only true/false/unknown as it does now, but something like always-true/always-false/true/false/unknown.

To be clear, I think that's doable, but it's probably less straight-forward than the alternative?

@zcorpan
Copy link
Member

zcorpan commented Sep 18, 2023

I guess my main concern is consistency for web developers about where supports() works, and how to expose it in the CSSOM. So maybe first we need to decide whether @media supports() should be a thing.

Edit: filed w3c/csswg-drafts#9375

@zcorpan
Copy link
Member

zcorpan commented Sep 19, 2023

I've received some pushback to the supports() in @media idea. @noamr suggested in #whatwg chat that maybe there's a better solution than adding supports() in the media attribute in HTML.

Maybe the failed closed requirement is not a hard requirement, since authors can use @import in a style element (which fails closed). Then we can instead add a supports attribute:

long-term syntax for layer:

<link rel="stylesheet" layer="foo" href="bar.css">

transition period for layer:

<style>
@import url(bar.css) layer(reset);
</style>

long-term syntax for supports:

<link rel="stylesheet" supports="at-rule(@scope)" href="bar.css">

transition period for supports:

<style>
@import url(bar.css) supports(at-rule(@scope));
</style>

@noamr
Copy link
Contributor

noamr commented Sep 19, 2023

I've received some pushback to the supports() in @media idea. @noamr suggested in #whatwg chat that maybe there's a better solution than adding supports() in the media attribute in HTML.

Maybe the failed closed requirement is not a hard requirement, since authors can use @import in a style element (which fails closed). Then we can instead add a supports attribute:

long-term syntax for layer:

<link rel="stylesheet" layer="foo" href="bar.css">

transition period for layer:

<style>
@import url(bar.css) layer(reset);
</style>

long-term syntax for supports:

<link rel="stylesheet" supports="at-rule(@scope)" href="bar.css">

transition period for supports:

<style>
@import url(bar.css) supports(at-rule(@scope));
</style>

The resistance I have for putting supports inside media is that it feels inconsistent. In CSS those are separate rules, and we're bundling them together in HTML, with the reason being a side-benefit (supporting legacy). This divergence can cause problems in the future if we expand what media queries can do.

So I was more drawn the idea of using the existing working thing (<style>) as the solution for legacy while keeping link element attribute naming consistent.

@annevk
Copy link
Member

annevk commented Sep 19, 2023

If media queries and supports are distinct concepts in CSS I'm inclined to agree we should not group them here. Bit surprising nobody pushed back on that during the CSS WG discussion, but maybe not everyone was paying attention.

In that case we should add layer and leave supports for another issue, to be decided separately.

@noamr
Copy link
Contributor

noamr commented Sep 19, 2023

If media queries and supports are distinct concepts in CSS I'm inclined to agree we should not group them here. Bit surprising nobody pushed back on that during the CSS WG discussion, but maybe not everyone was paying attention.

I was paying attention to this at the joint discussion and IIRC I raised this point (perhaps not loudly enough). but I didn't have a good solution for backwards compat at the time.

In that case we should add layer and leave supports for another issue, to be decided separately.

Yes, and while there is a legacy period relevant CSS can be wrapped in @supports at-rule(@layer) or imported from a style element rather than directly from a link.

@zcorpan
Copy link
Member

zcorpan commented Dec 13, 2023

See w3c/csswg-drafts#9375 (comment)

New proposal is to add a condition attribute instead of supports attribute, and reference CSS import condition:

<link rel="stylesheet" condition="supports(at-rule(@scope))" href="bar.css">

Pro: easier to add new import conditions
Pro: fail-closed instead of fail-open processing when using a new (unsupported) import condition
Pro: syntax is more consistent with @import
Con: more verbose

@emilio
Copy link
Contributor

emilio commented Dec 13, 2023

We'd also need to specify how they interact right? If media says to load but condition says not to, what wins?

@noamr
Copy link
Contributor

noamr commented Dec 13, 2023

We'd also need to specify how they interact right? If media says to load but condition says not to, what wins?

I'd suggest that condition doesn't load at all, while media loads but doesn't apply (like today). This makes condition "win".

I didn't see this mentioned, but isn't it a problem that browsers that don't support the condition attribute would still load the stylesheet in this case?

@romainmenke
Copy link

romainmenke commented Dec 13, 2023

We'd also need to specify how they interact right? If media says to load but condition says not to, what wins?

They can be combined right?

<link
  rel="stylesheet"
  condition="supports(at-rule(@scope)) (min-width: 300px)"
  media="(min-height: 400px)"
  href="bar.css"
>

This could be roughly equivalent to :

@media (min-width: 300px) {
  @supports (at-rule(@scope)) {
    @media (min-height: 400px) {
      /* ... * /
    }
  }
}

It would need to be defined exactly how they combine, in which order and how it affects cascade layers.

But I don't think one attribute should effectively disable the other.

@ryantownsend
Copy link

I'd suggest that condition doesn't load at all, while media loads but doesn't apply (like today). This makes condition "win".

+1 to this.

isn't it a problem that browsers that don't support the condition attribute would still load the stylesheet in this case?

@noamr unless I'm misunderstanding your question: you could mirror whatever conditions are present in the HTML within the stylesheet to mitigate this in the short-term, right?

e.g. if a browser erroneously loads bar.css from @romainmenke's example above because it doesn't support condition yet, but the contents of the file include the @media and @supports from condition, worst-case it's a waste of loading the resource unnecessarily but doesn't break anything because when the CSS evaluates it won't apply.

@noamr
Copy link
Contributor

noamr commented Dec 13, 2023

I'd suggest that condition doesn't load at all, while media loads but doesn't apply (like today). This makes condition "win".

+1 to this.

isn't it a problem that browsers that don't support the condition attribute would still load the stylesheet in this case?

@noamr unless I'm misunderstanding your question: you could mirror whatever conditions are present in the HTML within the stylesheet to mitigate this in the short-term, right?

e.g. if a browser erroneously loads bar.css from @romainmenke's example above because it doesn't support condition yet, but the contents of the file include the @media and @supports from condition, worst-case it's a waste of loading the resource unnecessarily but doesn't break anything because when the CSS evaluates it won't apply.

Sounds good to me as a temporary mitigation!

@bramus
Copy link

bramus commented Dec 13, 2023

See w3c/csswg-drafts#9375 (comment)

New proposal is to add a condition attribute instead of supports attribute, and reference CSS import condition:

My original suggestion was to basically expand [media] to accept any type of condition, so that its future proofed for whenever a new type of condition comes up.

media="supports(…) prefers(…)"
media="media(…)"
media="dayofweek(…)" 🤪

But because [media="media(…)"] makes no sense, I also suggested to rename media to condition (over time). The two would essentially be aliases.

condition="supports(…) prefers(…)"
condition="media(…)"

That rename is entirely optional though, as [media] is used on a lot of elements …

That way:

  • Authors can use existing and recent conditionals by passing them all into media.
    • Passing it into media instead of a new attribute is to make sure that old browsers also try to parse these conditions, at which point they will choke on them and not apply anything.
  • There’s no worry of how to combine media and condition. You can only use one.
  • There’s no issues in the future when adding new conditions.

Unless I'm misunderstanding your question: you could mirror whatever conditions are present in the HTML within the stylesheet to mitigate this in the short-term, right?

Not a fan of this. Putting everything into [media] would also prevent this problem from existing.

@mirisuzanne
Copy link
Author

Putting everything into [media] would also prevent this problem from existing.

If we were ok with just putting everything in the media attribute, we wouldn't be having this conversation in the first place. That was the original proposal, and it was rejected.

The simpler short-term polyfill that came up in the CSSWG call today is that authors can add a reliably-failing media attribute along side the condition attribute, and then remove the media attr for browsers that support condition.

This could be made even simpler (as proposed by @fantasai on the CSSWG telecon) by adding an optional from-condition value (name TBD) to the media attribute. That value would fail the import in old browsers, and defer to the condition attribute in modern browsers. Then no other polyfill would be required:

<link rel="stylesheet" media="use-condition" condition="supports(at-rule(@scope))" href="bar.css">

@bramus
Copy link

bramus commented Dec 13, 2023

Putting everything into [media] would also prevent this problem from existing.

If we were ok with just putting everything in the media attribute, we wouldn't be having this conversation in the first place. That was the original proposal, and it was rejected.

I came to properly understand the reasons behind this during the meeting and am now OK with not being able to simply rename it now, nor in the future. So yes, condition in addition to media it is :)

@valtlai
Copy link

valtlai commented Dec 13, 2023

I’m not sure, but would when be a better name for the new attribute (instead of condition)? It would be consistent with the @when at-rule which takes similar (or the same?) syntax.

From w3c/csswg-drafts#9375 (comment)

@noamr
Copy link
Contributor

noamr commented Dec 13, 2023

I’m not sure, but would when be a better name for the new attribute (instead of condition)? It would be consistent with the @when at-rule which takes similar (or the same?) syntax.

From w3c/csswg-drafts#9375 (comment)

FWIW I also prefer when.

@romainmenke
Copy link

@when <boolean-condition> and @import <url> <import-condition> are different things.
I don't have a preference on what it should be, but it should make sense when viewing CSS and HTML side by side.

Either of these would make sense to me:

  • condition="<import-condition>"
  • when="<boolean-condition>"

@mirisuzanne
Copy link
Author

I agree with @romainmenke. I do like the when approach, if we can take it all the way (and if that doesn't become a blocker for the feature). I don't know if that's a conversation we'd want to kick back over to the CSSWG, or if there's a way to settle on a direction here?

@zcorpan
Copy link
Member

zcorpan commented Feb 22, 2024

@when has a media() function, is it desirable to support that in HTML when=""?

@noamr
Copy link
Contributor

noamr commented Feb 22, 2024

@when has a media() function, is it desirable to support that in HTML when=""?

No, because links already have media (and soon supports). @when enhances the syntax around those conditions to have if/else semantics but it's not a new type of condition.

@romainmenke
Copy link

romainmenke commented Feb 22, 2024

@when does have different syntax.

These are valid (as specified, not everything is implemented):

@media (width: 300px) {}
@supports (display: grid) {}
@when media(width: 300px) {}
@when supports(display: grid) {}

@import "foo.css" (width: 300px); 
@import "foo.css" layer(foo) supports(display: grid) (width: 300px); 

These are not valid (today):

@when (width: 300px) {}
@import "foo.css" media(width: 300px); 

I think that when might be not be ideal after all because in CSS it isn't tied to @import. I also don't think they should be tied together. Not all conditions will make sense for stylesheet loading.

I do think it is important that authors can intuitively copy/paste conditions between CSS and HTML.

So if when="" is used in HTML then it must align with @when in CSS and that implies a media() function.

@noamr
Copy link
Contributor

noamr commented Feb 22, 2024

@when does have different syntax.

Yea, but it's not a new type of condition.

I think that when might be not be ideal after all because in CSS it isn't tied to @import. I also don't think they should be tied together. Not all conditions will make sense for stylesheet loading.

Exactly. It's a CSS syntax feature.

I do think it is important that authors can intuitively copy/paste conditions between CSS and HTML.

What makes this important? Those expressive conditionals seem to be a CSS syntax feature. What should be copy-pastable IMO is imports, and for that supports/media is enough.

@romainmenke
Copy link

romainmenke commented Feb 22, 2024

I do think it is important that authors can intuitively copy/paste conditions between CSS and HTML.

What makes this important? Those expressive conditionals seem to be a CSS syntax feature. What should be copy-pastable IMO is imports, and for that supports/media is enough.

I am not fully sure what you mean, maybe we are saying the same thing :)


I like how these align:

<link rel="stylesheet" href="bar.css" condition="supports(display: grid) screen">
@import "bar.css" supports(display: grid) screen;

I am not convinced of this:

<link rel="stylesheet" href="bar.css" when="supports(display: grid) and media(screen)">
@import "bar.css" supports(display: grid) screen;

But I think authors will get it.
They will learn the syntax of @when and will intuit that that is what they are supposed to use in when=""


I don't like this:

<link rel="stylesheet" href="bar.css" when="supports(display: grid) screen">
@import "bar.css" supports(display: grid) screen;

Because supports(display: grid) screen isn't valid in @when.


(Keeping in mind that @when hasn't shipped and there isn't even consensus that it should be named @when)

@noamr
Copy link
Contributor

noamr commented Feb 22, 2024

I do think it is important that authors can intuitively copy/paste conditions between CSS and HTML.

What makes this important? Those expressive conditionals seem to be a CSS syntax feature. What should be copy-pastable IMO is imports, and for that supports/media is enough.

I am not fully sure what you mean, maybe we are saying the same thing :)

Not exactly. I'm saying that when is a general-purpose condition syntax, a bit different from import conditions, and <link rel=stylesheet> is equivalent to imports - it's a specific purpose thing rather than something general purpose.

I like how these align:
...
(Keeping in mind that @when hasn't shipped and there isn't even consensus that it should be named @when)

One thing to remember is that in terms of imports/links, supports and media are different: a false supports would not fetch stylesheet, while a false media would fetch but not apply the stylesheet. Trying to flatten both into a when statement makes that distinction less apparent, and perhaps when it comes down to links it also doesn't buy much added value on top of the existing import conditions?

@zcorpan
Copy link
Member

zcorpan commented Feb 28, 2024

Thinking about this again, I'm not sure it's a good idea to introduce duplication of MQ for <link>. It's possible to have well-defined processing, but it still seems confusing for web developers to now have two possible places for MQ. Should they use both, for better compatibility? For how long? Is the media attribute deprecated now?

It seems better to separate import conditions into two parts, one for MQ and one for everything else, and let the new attribute for <link> exclude MQ.

The syntax as compared to @import is not identical anyway, since the URL goes into its own attribute.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest topic: style
Development

No branches or pull requests