[csswg-drafts] [css-env] Consider value-level parsing like calc() rather than token-level like var()

SimonSapin has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-env] Consider value-level parsing like calc() rather than token-level like var() ==
## Background

The syntax of the `calc()` function is defined "at the value level":

https://drafts.csswg.org/css-values/#calc-notation
> A math function can be used wherever `<length>`, `<frequency>`, `<angle>`, `<time>`, `<flex>`, `<resolution>`, `<percentage>`, `<number>`, or `<integer>` values are allowed. 

This allows both authors and implementers to only consider those functions in contexts where these value can be used. For example, `display: calc(…)` is never valid for any `…`.

The `var()` function however works "at the token stream level", before even considering the value syntax of a given property:

https://drafts.csswg.org/css-variables/#using-variables
> The `var()` function can be used in place of any part of a value in any property on an element.

Being so general is useful for `var()` because many authors will be defining custom properties with arbitrary bits of syntax. We don’t want the spec to have to anticipate and enumerate each value type that could be used in custom property values.

However, this causes `var()` to "infect" more of the language. The presence of a `var()` function somewhere in the middle of a declaration affects the behavior of the entire declaration in ways that both authors and implementers need to be aware of and deal with:

https://drafts.csswg.org/css-variables/#using-variables
> If a property contains one or more var() 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-value time, after var() functions have been substituted.

In this sense, `var()` is a more fundamental part of CSS syntax than just another feature that can be used in values.

## `env()`

Currently, the syntax of the `env()` function is defined in a way very similar to `var()`:

https://drafts.csswg.org/css-env-1/#env-function
> The `env()` function can be used in place of any part of a value in any property on any element, or any part of a value in any descriptor on any at-rule, and in several other places where CSS values are allowed.

I think it doesn’t need to be, and it should be redefined in a way similar to the `calc()` function: it is an additional set of valid values for a given set of types like `<length>`.

The spec defines a closed set of environment variables, and all of them are currently defined as `<length>`. In the future if/when new variables of other types are added (possibly `<color>`?), we can extend parsing support to those types.

## Compat

I understand that this feature is already shipping in some browsers (despite not having a working draft yet). Hopefully it was only shipped recently enough that relatively few sites use it, and it is simple enough that they mostly use it ways (only using length variables in length contexts) that are similar to each other and not affected by this proposed change.


Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/3285 using your GitHub account

Received on Monday, 5 November 2018 12:03:10 UTC