[csswg-drafts] Updating the css `env()` function to enable selection by index from a list of pre-defined environment variables (#5622)

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

== Updating the css `env()` function to enable selection by index from a list of pre-defined environment variables ==
In issue #5621 we highlighted a new syntax for the media feature that was proposed to help Web developers match and insert rules that are specific to dual-screen and foldable devices, the new syntax can be extended to cover multi-screen scenarios and offers better scalability.

Detecting whether the browser viewport is spanning across 2 or more screens is only one part of the solution, the other part is informing developers about the geometry and size of each screen and while the `env()` function is great for exposing such hardware-specific configurations, we believe it could be extended and improved to offer better experience for Web developers.

## Illustrating the problem of verbosity

Today, user-agents provide [custom-identifiers](https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident) that web developers pass to the `env()` function as a first argument to get back a value that can be assigned to numerous CSS properties. Following is an illustration of how the `safe-area-inset-top` custom-ident is used to help developers prevent content from being occluded by a smartphone's notch:

```css
body {
    padding-top: env(safe-area-inset-top);
}
```
<img width="647" alt="smartphone-notch-inset" src="https://user-images.githubusercontent.com/5052316/96070484-26bf1c80-0e55-11eb-9725-4134f8dc731e.png">

In dual-screen and foldable devices scenarios where the browser window is spanning across more than 1 display region, the user-agent might want to expose the geometry of each display region. Today, that would be something like:
| Display Region 1      | Display Region 2      | ... | Display Region N      |
|:----------------------|:----------------------|:---:|:----------------------|
| env(viewport-segment-1-width)  | env(viewport-segment-2-width)  | ... | env(viewport-segment-n-width)  |
| env(viewport-segment-1-height) | env(viewport-segment-2-height) | ... | env(viewport-segment-n-height) |
| env(viewport-segment-1-top)    | env(viewport-segment-2-top)    | ... | env(viewport-segment-n-top)    |
| env(viewport-segment-1-left)   | env(viewport-segment-2-left)   | ... | env(viewport-segment-n-left)   |
| env(viewport-segment-1-bottom) | env(viewport-segment-2-bottom) | ... | env(viewport-segment-n-bottom) |
| env(viewport-segment-1-right)  | env(viewport-segment-2-right)  | ... | env(viewport-segment-n-right)  |

<img width="1111" src="https://user-images.githubusercontent.com/5052316/96070895-f035d180-0e55-11eb-919f-526ba890d960.png">


Stylistically, the solution demonstrated above to expose the display regions' geometry is verbose. Creating a list of custom-identifiers accompanied by a mechanism for web developers to retrieve values by index offers greater scalability and better ergonomics.

## Proposal: CSS `index()` function

The `index()` CSS function can be used within the `env()` function to select one value by index from a user-agent-defined environment variables list.

### Syntax and example usage

The example below illustrates how to use the browser-provided `env()` variables to create a 2-column CSS Grid layout, where each column's size should equal the corresponding display's width.

<img width="843" alt="grid-example" src="https://user-images.githubusercontent.com/5052316/96071296-aac5d400-0e56-11eb-8bd6-d8e93eb7a6b2.png">

#### HTML

```html
<div id="grid">
    <div id="A"></div>
    <div id="B"></div>
</div>
```

#### CSS

```css
#grid {
    display: grid;
    height: 100vh;
    grid-template-columns: env(index(display-width 0), 1fr) env(index(display-width 1), 1fr);
    grid-template-rows: 100vh;
}
```

### Formal syntax

```
index( <custom-ident> <index-value> )
```

#### Parameters

- *custom-ident*: arbitrary user agent-defined string, [mdn](https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident)
- *index-value*: integer, with the index origin being 0 matching arrays behaviour.

### Behavior

#### Case sensitivity

User-agent-defined property names are case-sensitive. `env()` respects that today and `index()` will not introduce any changes to that behavior.

Example:

```css
height: env( index(display-height 0) , 700px); /* height equals the first display-region height */

height: env( index(Display-Height 0) , 700px); /* 700px, because 'Display-Height' does not match the 'display-height' property */
```

### "2D" Screen setup
In the case we have more than 1 row and 1 column of screens, we propose flattening-out the screens matrix to a linear list where the top-left gets the index 0 followed by the consecutive screens on that row.

<img width="280" src="https://user-images.githubusercontent.com/5052316/96072093-56bbef00-0e58-11eb-9ee1-b3e251ad5330.png">

photo credit [wikipedia](https://en.wikipedia.org/wiki/Row-_and_column-major_order)

### Possible future uses

#### Usage with `env()` in media query rules

`env()` function values can be used as a part of a descriptor such as Media Query rules; thus using `env(index(ua-property 0))` is also supported.

#### Usage with custom properties

The `index()` function will initially be scoped to the user-agent-defined lists of environment variables. However, if developers in the future are empowered to create lists as custom properties values, `index()` function can be used with `var()` the same way this document proposes for use with `env()`.


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


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Thursday, 15 October 2020 03:06:05 UTC