- From: CSS Meeting Bot via GitHub <noreply@w3.org>
- Date: Wed, 09 Jul 2025 17:03:52 +0000
- To: public-css-archive@w3.org
The CSS Working Group just discussed `[css-env][css-conditional] Need an approach to check whether an environment variable is supported`, and agreed to the following: * `RESOLVED: add env() function to @supports` <details><summary>The full IRC log of that discussion</summary> <bramus> `@supports (x: env(this-does-not-exist)) { … }`<br> <JoshT> bramus: about feature detecting environment vars<br> <JoshT> ... if you do a check like this, the check always returns true<br> <JoshT> ... env() only becomes invalid at computed value time, not parse time, so this check always returns true<br> <JoshT> ... authors need to check some of the env() vars are supported<br> <TabAtkins> q+<br> <JoshT> ... depending on support, authors might need to do something else in their CSS<br> <JoshT> ... proposing a new function to use inside the @supports<br> <JoshT> ... like now you can do @supports selector()<br> <lea> q?<br> <bramus> `env( <custom-ident> )`<br> <JoshT> ... we'd have @supports env() with your custom ident<br> <lea> q+<br> <astearns> ack TabAtkins<br> <JoshT> ... and when the custom-ident is one of the supported env()s, it returns true<br> <JoshT> TabAtkins: so I support this, makes sense. fallback is often all that you need but there will be cases where you need to do an alternative design<br> <JoshT> ... I saw lea's comment on the thread. 'Why aren't we detecting whether it is known at parse time?'<br> <JoshT> ... because we need to be able to do fallback<br> <JoshT> ... if it was done at parse time, fallback would not work<br> <JoshT> ... could do it in theory, but would be contrary to how other things with fallback work<br> <astearns> ack lea<br> <emilio> +1 to what tab said<br> <JoshT> lea: indeed what I was going to ask<br> <astearns> q+<br> <JoshT> ... will be web compat concerns at this point<br> <JoshT> ... if there is no fallback, maybe it could become valid at parse time, and if not, it would be evaluated as it is now<br> <bramus> q+<br> <emilio> q+<br> <JoshT> ... one issue with that is theoretically you could have a var with the env var and the fallback, and then it wouldn't be possible to know when you have a fallback.<br> <JoshT> ... but that's how vars work anyway so won't be a problem<br> <JoshT> ... these things don't have a preset known in advance anyway, but if it is known it would not be known at parse time<br> <lea> s/will be web compat concerns at this point/might be web compat concerns at this point/<br> <JoshT> astearns: in looking at this, I thought there may be places where there needs to be ??? support calls to see where a var will be supported for a particular property<br> <kbabbitt> s/???/double/<br> <lea> q+<br> <astearns> ack astearns<br> <lea> q-<br> <JoshT> ... but I don't think in practice that will be an issue. env vars are normally just <length> values<br> <JoshT> bramus: I fear if we change how env currently works to check at parse time, that would differ from how var works. people may ask why you don't do that for var<br> <lea> astearns: Even when you want to test presence in general, without a particular property in mind, it's common practice to just pick one, e.g. to test color validity authors often do @supports(color: foo)<br> <astearns> ack bramus<br> <JoshT> ... I don't think it makes sense right now because all custom properties come back as supported because you can have any name<br> <lea> q+<br> <astearns> ack emilio<br> <JoshT> emilio: I think there is value in keeping it consistent with var. even with lengths, it will just compute to the initial value of the property when it's not supported, like 'auto'. I wouldn't need to write a fallback. It feels easier to reason about at computed time.<br> <JoshT> ... I think we do want to keep env() resolving at computed value time. The simple thing is good: add the new env() query to check it's supported<br> <astearns> ack lea<br> <JoshT> ... and even if you need to behave as invalid at parse time, you can do @supports and call it a day<br> <JoshT> lea: custom properties are like this because they are defined by authors and could change.<br> <JoshT> ... it's an unfortunate wart in css that we had to accept to make it possible<br> <JoshT> ... but with env() we can do better<br> <emilio> q+<br> <TabAtkins> q+<br> <kbabbitt> q+<br> <JoshT> ... right now, it's fixed, the value doesn't change<br> <astearns> ack emilio<br> <JoshT> emilio: the values do change, so you do still need the env() reference at specified value time. so this would not be like calc() which can simplify most of the time<br> <lea> qq+<br> <JoshT> ... you still need something in between, so I suggest just keeping it like var()<br> <bramus> +1<br> <astearns> ack lea<br> <Zakim> lea, you wanted to react to emilio<br> <JoshT> emilio: you still need to keep the reference<br> <JoshT> ... that would significantly change how these work and I still think there's value make it like var()<br> <lea> q+ Or we can just define that if the name is known, it's always valid<br> <JoshT> ... you cannot get rid of the reference anyway, so I don't think it's as useful as you think. Maybe I'm wrong<br> <astearns> ack TabAtkins<br> <JoshT> ... having an in between thing where you evaluate them at parse time based on whether the name exists I think is weird<br> <JoshT> TabAtkins: I think this discussion is confused. we are not worrying about the type of the value<br> <JoshT> ... its a substitution function<br> <lea> q+<br> <JoshT> ... while the set of envs is static over the course of a page life time, we are adding more envs relatively often so knowing what is supported in a browser is non-trivial<br> <emilio> q+<br> <JoshT> ... we're worried about the fact that new stuff can be added in a way to predict and engineer around without a query<br> <JoshT> ... often the fallback is fine, but when you need more complicated reactions, knowing whether a value exists or not is valuable here<br> <JoshT> ... to have an @supports env() that checks if it exists is useful here<br> <astearns> ack kbabbitt<br> <JoshT> kbabbitt: on the topic of env vars changing, I remember a proposal to have author defined global values of some kind<br> <JoshT> ... not sure if it was env vars but that could be useful for setting values for the entire page<br> <JoshT> ... was that proposed as an extension to env vars, because then it could be extended by author definitions<br> <lea> q?<br> <JoshT> TabAtkins: the discussion never settled on that, whether var or env.<br> <JoshT> ... regardless, they are distinct because the keyword would be double dashed --<br> <JoshT> ... I agree to treat env as like var for simplicity<br> <JoshT> ... but we don't know how that would affect the rest of the discussion<br> <JoshT> lea: +1 to the problem<br> <astearns> ack lea<br> <JoshT> ... I agree it should be possible to check if a name is known and not known<br> <JoshT> ... the question is the way to do it<br> <astearns> q+<br> <JoshT> ... what is being proposed, it only makes some of these uses invalid at parse time. like with a made up env name, it would always be invalid<br> <bramus> q+<br> <JoshT> ... if the name is known, same behaviour as today. the only case that is different is when the name is not knowm<br> <JoshT> ... it seems better to improve the API surface than teach a whole new function<br> <JoshT> ... if we have a new API surface and a new function, authors would have to look it up<br> <JoshT> ... and custom envs would need to use -- dash dash anyway<br> <astearns> ack emilio<br> <JoshT> emilio: When I mentioned typing, I was wondering how we could diverge while parsing<br> <JoshT> lea: but there's no substitution. you know the name.<br> <JoshT> ... if a var is used, it's a different story<br> <JoshT> emilio: but right now, we don't check the value at parse time.<br> <JoshT> q+<br> <JoshT> emilio: it has a performance cost to change root properties after the page is loaded because you need to inherit it in the whole DOM<br> <kbabbitt> +1 emilio<br> <astearns> ack astearns<br> <lea> q+<br> <JoshT> astearns: I am agnostic to these approaches. I'm concerned about the difference of how @supports works with whether there is a fallback or nor<br> <JoshT> ... it would change the validity if you're asking for an invalid env var<br> <JoshT> TabAtkins: It would just be asking about the name<br> <astearns> ack bramus<br> <JoshT> bramus: Regarding what lea proposed, if the custom ident is an env var, I think that would allow to do something like:<br> <bramus> `@supports (background: env(safe-area-inset-left)) { … }`<br> <JoshT> ... this seems not good because the pixel value is not the value of the background<br> <JoshT> lea: it would be parsed as a background position and everything would still go back to the initial value<br> <emilio> q+<br> <JoshT> bramus: I think we should still use the @supports env() function because otherwise authors would still have to look up when an env() value works in @supports works<br> <JoshT> astearns: It could be an issue that the supported version of env ????? will fail to work properly if it has a fallback<br> <TabAtkins> The suggestion is to allow `@supports env(foo, fallback)` and just ignore the fallback<br> <romain> q+<br> <astearns> ack fantasai<br> <Zakim> fantasai, you wanted to suggest we adopt the proposal and discuss the parse-time validity of env() in its own issue<br> <JoshT> bramus: we could then also opt to change the @supports to accept the fallback, which then wouldn't take it into consideration, but maybe that's not a good thing<br> <TabAtkins> (I don't think this is a good idea.)<br> <romain> q-<br> <astearns> s/supported version of env ?????/@supports version of env(), copy-pasted env()/<br> <JoshT> fantasai: I am sympathetic to lea's option. but I think that's a separate argument to whether we have @supports env()<br> <lea> TabAtkins: ideally we could validate prop: fallback if foo is unknown, but that's less importan than env(unknown) being invalid IMO<br> <JoshT> ... even if we make that work, having a shorthand to support this is still useful<br> <emilio> +1<br> <JoshT> ... that would let us accept this proposal and we'd still consider to discuss if you could evaluate env() at parse time<br> <JoshT> ... but regarding the proposal, I don't think it should accept a fallback<br> <lea> +1 fantasai<br> <JoshT> ... the top level functions are specific about what they accept<br> <TabAtkins> I think Emilio and Bramus's point about consistency of operation is important. env() is mostly identical to var(), giving it different validity behavior makes things harder to learn.<br> <JoshT> ... it could be checkable in some way but I don't think we should allow that. we should accept the keyword<br> <kbabbitt> JoshT: there is a difference between how env and var work<br> <kbabbitt> ... because env works in mqs as well<br> <astearns> ack lea<br> <kbabbitt> ... but I don't think that's currently supported in any browser<br> <JoshT> lea: as I wrote on the IRC, we could invalidate property fallback if the name is unknown, but that is a second tier thing<br> <JoshT> ... but that would be the north star. then you could envaluate if ????<br> <astearns> ack JoshT<br> <JoshT> ... that is now app support works in general. it's already taught that that's how @support works anyway.<br> <JoshT> ... consistency has been talked about. it's an ergonomic issue<br> <JoshT> ... the way var works now anyway is an ergonomic issue<br> <JoshT> ... there is a TAG principle on consistency.<br> <astearns> zakim, close queue<br> <Zakim> ok, astearns, the speaker queue is closed<br> <JoshT> ... but there are cases where it is warranted to break consistency if the other option has better ergonomics<br> <romain> +1<br> <JoshT> ... I would argue there are cases where people currently struggle. this is a pain point.<br> <TabAtkins> The var() behavior (invalid at comptued value time) is unavoidable and shows up in several places now. Similarly, `attr(nonsense)` is valid at parse time. Etc. env() being the sole exception of substitution functions that can be invalid at parse time, *depending on what you write*, isn't great.<br> <JoshT> ... the prority of constituencies relates. we don't want authors to learn a new thing.<br> <JoshT> emilio: quick suggestion<br> <astearns> ack emilio<br> <JoshT> ... it seems everyone agrees checking whether env is supported is a useful thing<br> <JoshT> ... was going to suggest we move how env parses to a separate issue<br> <lea> @support env() is nice regardless, even as a shortcut. And it does fix the immediate issue so +1 to it<br> <JoshT> ... changing how env works has a perf cost and compat risk and it's more implementation and research cost<br> <JoshT> extending @supports is easier<br> <fantasai> +1<br> <bramus> +1<br> <ydaniv> +1 to emilio<br> <JoshT> ... if we end up with two ways to test how env() works, I think that's a relatively small cost to pay<br> <lea> astearns: I think we have consensus to add @supports env(name)<br> <fantasai> s/astearns:/astearns,<br> <kbabbitt> +1 to @supports env(name)<br> <JoshT> ... would anyone object to adding @supports env() to the top level syntax<br> <JoshT> RESOLVED: add env() function to @supports<br> </details> -- GitHub Notification of comment by css-meeting-bot Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/3576#issuecomment-3053375696 using your GitHub account -- Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Wednesday, 9 July 2025 17:03:52 UTC