Description
Refer to https://bugzilla.mozilla.org/show_bug.cgi?id=1539708#c2 for background. An issue will need to be filed on Chromium, the precise shape of which will depend on the outcome of this issue. Maybe WebKit too; not sure.
The problem relates to https://drafts.csswg.org/css-env-1/#env-function:
If a property contains one or more env() functions, and those functions are syntactically valid, the entire property’s grammar must be assumed to be valid at parse time. It is only syntax-checked at computed-time, after env() functions have been substituted.
I’m not confident in my understanding of the terms involved, but I think that is just saying that you can’t classify a value as invalid out-of-hand at parse time, but will need to wait until you compute it, to decide whether it’s valid. (If that’s not what it does actually mean, I will glibly assert that it’s still what it should mean, and what a non-spec-reading human will expect it to do.)
However, Firefox seems to have only implemented the first part and not compute-time syntax-checking, and Chrome also seems to have missed the compute-time syntax-checking, and moreover sensibly ignored a small part of the stipulated parse time validity checking. Not sure about Safari, as I don’t have access to a Mac.
I’ve created this issue to confirm the correct interpretation, and request that a clarifying note be added to this place in the spec, since this is evidently a fiddly detail for implementers.
I think this is a fairly important issue for css-env, due to interactions with other upcoming specs. The code that precipitated my coworker finding this seems quite reasonable, and was roughly this:
margin-bottom: 15px;
margin-bottom: env(safe-area-inset-bottom, 15px);
margin-bottom: max(env(safe-area-inset-bottom, 15px), 15px);
That one could need to wrap the third line up in @supports (margin-bottom: env(safe-area-inset-bottom)) and (margin-bottom: max(0, 15px))
would be decidedly unfortunate.
Test case 1: env()
that is substituted with an invalid value
<body style="background-color:limegreen;background-color:env(bar, 1)">
A human reading this will expect it to be limegreen
, since background-color: env(bar, 1)
will become, by substitution, background-color: 1
, which is invalid.
Firefox accepts the second rule as valid, but equates it to… I’m not actually sure what it is technically, but initial
or unset
, at a guess? So the limegreen background is overridden, and you get a white background.
Chrome does the same.
Safari I have no access to, so I’m not sure what it may do. (Feel free to update this text with the result of testing it in Safari; or I will if someone comments it.)
Test case 2: env()
used inside an unknown function
<body style="margin:10em;margin:foo(env(bar, blue))">
A human reading this will expect margin: foo(env(bar, blue))
to be ignored, since there is no function foo()
; and so for the body margin to be 10em.
Firefox treats it as valid but the default value of zero, again.
Chrome decides that since it doesn’t have a foo()
function, the value is invalid, and uses 10em. I’d guess it does this at parse time.
Safari I have no access to, so I’m not sure what it may do.