Testing CSS env Variables
About Page
I have been running into some problems using CSS env variables to try to improve the styling of this site, so I am going to try to learn more about them here and demonstrate their values so that I can see what their values are in different browsers. I specifically run into this problem when open <dialog> elements are large on mobile (they are obscured by the bottom navbar), with the floating text edit toolbar in the lexical editor, and with the sticky toolbar for the article builder on mobile. I have tried to use the safe-area-inset
The env() CSS function can be used to insert the value of a user-agent defined environment variable into you CSS, in a similar fashion to the var() function and custom properties. The difference is that, as well as being user-agent defined rather than author defined, environment variables are globally scoped to a document, whereas custom properties are scoped to the element(s) on which they are declared.
Mozilla Docs
These variables were originally provided by the iOS browser to allow developers to place their content in a safe area of the viewport, the safe-area-insert-* values defined in the specification can be used to help ensure content is visible event to viewers using non-rectangular displays.
A common issue solved by env() is that of device notifications covering up some of the app user interface. By positioning fixed elements using env(), you can ensure that they display in a safe area of the viewport.
Another use of env() is for Progressive Web Apps that use the Window Controls Overlay feature to take advantage of the full application window surface area. Using the titlebar-area-* values, you can position elements where the titlebar would have been and ensure that content stays clear of the window controls buttons.
env() Variables
Reference: Mozilla Docs
- safe-area-inset-top
This value defined the distance from the top of the screen which is safe to put content in for non-rectangular displays. For rectangular displays, this is equal to 0.
- safe-area-inset-right
This value defined the distance from the right of the screen which is safe to put content in for non-rectangular displays. For rectangular displays, this is equal to 0.
- safe-area-inset-bottom
This value defined the distance from the bottom of the screen which is safe to put content in for non-rectangular displays. For rectangular displays, this is equal to 0.
- safe-area-inset-left
This value defined the distance from the left of the screen which is safe to put content in for non-rectangular displays. For rectangular displays, this is equal to 0.
- titlebar-area-x
Useful for PWA installed on Desktop devices. When the desktop PWA uses the windows-control-overlay display override value, then it can use these variables to make sure content doesn't overlap with the window control buttons.
- titlebar-area-y
Useful for PWA installed on Desktop devices. When the desktop PWA uses the windows-control-overlay display override value, then it can use these variables to make sure content doesn't overlap with the window control buttons.
- titlebar-area-width
Useful for PWA installed on Desktop devices. When the desktop PWA uses the windows-control-overlay display override value, then it can use these variables to make sure content doesn't overlap with the window control buttons.
- titlebar-area-height
Useful for PWA installed on Desktop devices. When the desktop PWA uses the windows-control-overlay display override value, then it can use these variables to make sure content doesn't overlap with the window control buttons.
- keyboard-inset-top
These variables provide information about the on-screen virtual keyboard's appearance. They define a rectangle by its top, right, bottom, and left inset from the edge of the viewport.
- keyboard-inset-right
These variables provide information about the on-screen virtual keyboard's appearance. They define a rectangle by its top, right, bottom, and left inset from the edge of the viewport.
- keyboard-inset-bottom
These variables provide information about the on-screen virtual keyboard's appearance. They define a rectangle by its top, right, bottom, and left inset from the edge of the viewport.
- keyboard-inset-left
These variables provide information about the on-screen virtual keyboard's appearance. They define a rectangle by its top, right, bottom, and left inset from the edge of the viewport.
- keyboard-inset-width
These variables provide information about the on-screen virtual keyboard's appearance. They define a rectangle by its top, right, bottom, and left inset from the edge of the viewport.
- keyboard-inset-height
These variables provide information about the on-screen virtual keyboard's appearance. They define a rectangle by its top, right, bottom, and left inset from the edge of the viewport.
You can use these variables with fallback values:
* {
top: env(safe-area-inser-top);
bottom: env(safe-area-inset-top, 20px); /* Using fallback values */
}
Env Variable Demonstration
Property | Value |
---|---|
safe-area-inset-top | |
safe-area-inset-right | |
safe-area-inset-bottom | |
safe-area-inset-left | |
titlebar-area-x | |
titlebar-area-y | |
titlebar-area-width | |
titlebar-area-height | |
keyboard-inset-top | |
keyboard-inset-right | |
keyboard-inset-bottom | |
keyboard-inset-left | |
keyboard-inset-width | |
keyboard-inset-height |
CSS *vh and *vw
Reference: CSS *vh (dvh, lvh, svh) and *vw units
Browser Support
The vh unit, as it originally existed, was defined as Equal to 1% of the height of the initial contain block
. This is fine, except the UI of the browser changes on mobile devices as you scroll to maximize screen space:
Browser UI State | Browser UI | 100vh in pixels |
---|---|---|
See everything / maximized / first page load / on scroll upward | 15px | 85px |
Small / minimized / on scroll downward | 10px | 90px |
In 2015, Safari / Webkit engineers decided to change the behavior of vh units:
Dynamically updating the height was not working, we had a few choices: drop viewport units on iOS, match the document size like before iOS 8, use the small view size, use the large view size. From the data we had, using the larger view size was the best compromise.
Chrome / Blink engineers later agreed to so the same. One of the problems with vh on mobile devices is that anything that is min-height: 100vh is now larger or overflows the screen when you first load a page. A CSS proposal was born to solve this problem in 2019 and it was accepted in 2021. It involves adding the large, small, and dynamic viewport units.
- Large Viewport Units
- lvh and lvw are defined as
the viewport size assuming any UA interfaces that are dynamically expanded and retracted to be retracted.
- The size when the browser UI is the smallest and the website content is the largest.
- Small Viewport Units
- svhsvw are defined as
the viewport sized assuming any UA interfaces that are dynamically expanded and retracted to be expaned.
- The size when the browser UI is the largest and the website content is the smallest.
- Dynamic Viewport Units
- dvhdvw are defined as
the viewport sized with dynamic consideration of any UA interfaces that are dynamically expanded and retracted.
- The size of the dynamic viewport percentage units are not stable even while the viewport itself is unchanged.
- Using these units can cause content to resize. Depending on the usage, this can be disturbing to the user and/or costly in terms of performance. You should only use these units in very rare and specific situations.
- Traditional Viewport Units
- vhvw are defined as
thew UA-defined UA-default viewport size