Description
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 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:
body {
padding-top: env(safe-area-inset-top);
}
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) |
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.
HTML
<div id="grid">
<div id="A"></div>
<div id="B"></div>
</div>
CSS
#grid {
display: grid;
height: 100vh;
grid-template-columns: env(index(viewport-segment-width 0), 1fr) env(index(viewport-segment-width 1), 1fr);
grid-template-rows: 100vh;
}
Formal syntax
index( <custom-ident> <index-value> )
Parameters
- custom-ident: arbitrary user agent-defined string, mdn
- 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:
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.
photo credit wikipedia
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()
.