env()

The env() CSS function can be used to insert the value of a user-agent defined environment variable into your 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.

In addition, unlike custom properties, which cannot be used outside of declarations, the env() function can be used in place of any part of a property value, or any part of a descriptor (e.g. in Media query rules). As the spec evolves, it may also be usable in other places such as selectors.

Originally provided by the iOS browser to allow developers to place their content in a safe area of the viewport, the safe-area-inset-* values defined in the specification can be used to help ensure content is visible even to viewers using non‑rectangular displays.

For example, 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 case for env() variables is for desktop Progressive web apps (PWAs) that use the Window Controls Overlay feature to take advantage of the full application window surface area. Using the titlebar-area-* values, they can position elements where the title bar would have been and ensure that content stays clear of the window control buttons.

语法

css
/* Using the four safe area inset values with no fallback values */
env(safe-area-inset-top);
env(safe-area-inset-right);
env(safe-area-inset-bottom);
env(safe-area-inset-left);

/* Using them with fallback values */
env(safe-area-inset-top, 20px);
env(safe-area-inset-right, 1em);
env(safe-area-inset-bottom, 0.5vh);
env(safe-area-inset-left, 1.4rem);

safe-area-inset-top, safe-area-inset-right, safe-area-inset-bottom, safe-area-inset-left

The safe-area-inset-* variables are four environment variables that define a rectangle by its top, right, bottom, and left insets from the edge of the viewport, which is safe to put content into without risking it being cut off by the shape of a non‑rectangular display. For rectangular viewports, like your average laptop monitor, their value is equal to zero. For non-rectangular displays — like a round watch face — the four values set by the user agent form a rectangle such that all content inside the rectangle is visible.

titlebar-area-x, titlebar-area-y, titlebar-area-width, titlebar-area-height

The titlebar-area-* variables are useful for PWA installed on Desktop devices. When a desktop PWA uses the window-controls-overlay display_override value, then it can use the titlebar-area-* variables to make sure content doesn't overlap with the window control buttons (i.e. minimize, maximize, and close).

keyboard-inset-top, keyboard-inset-right, keyboard-inset-bottom, keyboard-inset-left, keyboard-inset-width, keyboard-inset-height

The keyboard-inset-* variables provide information about the on-screen virtual keyboard's appearance. They define a rectangle by its top, right, bottom, and left insets from the edge of the viewport (the width and height insets are calculated from the other insets). To learn more, see the VirtualKeyboard API.

注意:与其他 CSS 属性不同,用户代理定义的属性名称区分大小写。

正式语法

用法

要告诉浏览器使用屏幕上的所有可用空间,并启用我们使用env()变量,我们需要添加一个新的视口元值

html
<meta name="viewport" content="viewport-fit=cover" />

然后你可以在你的 CSS 中使用env()

css
body {
  padding: env(safe-area-inset-top, 20px) env(safe-area-inset-right, 20px)
    env(safe-area-inset-bottom, 20px) env(safe-area-inset-left, 20px);
}

示例

使用 env() 确保按钮不会被设备 UI 遮挡

在下面的例子中,env()被用来确保固定的应用程序工具栏按钮不会被出现在屏幕底部的设备通知遮挡。在桌面设备上,safe-area-inset-bottom0。但是,在屏幕底部显示通知的设备上,比如 iOS,它包含一个留出通知显示空间的值。这可以在 padding-bottom 的值中使用,以创建一个在这个设备上看起来自然的间隙。

html
<main>Main content of app here</main>
<footer>
  <button>Go here</button>
  <button>Or here</button>
</footer>
css
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  font: 1em system-ui;
}

main {
  flex: 1;
  background-color: #eee;
  padding: 1em;
}

footer {
  flex: none;
  display: flex;
  gap: 1em;
  justify-content: space-evenly;
  background: black;
  padding: 1em 1em calc(1em + env(safe-area-inset-bottom));
  /* adds the safe-area-inset-bottom value to the initial 1em of padding.
  a larger black area will display for a device that has a positive value for this variable. */
  position: sticky;
  bottom: 0;
}

button {
  padding: 1em;
  background: white;
  color: black;
  margin: 0;
  width: 100%;
  border: none;
  font: 1em system-ui;
}

使用回退值

下面的例子使用了env()的可选第二个参数,它允许你在环境变量不可用时提供一个回退值。

html
<p>
  If the <code>env()</code> function is supported in your browser, this
  paragraph's text will have 50px of padding between it and the left border —
  but not the top, right and bottom. This is because the accompanying CSS is the
  equivalent of <code>padding: 0 0 0 50px</code>, because, unlike other CSS
  properties, user agent property names are case-sensitive.
</p>
css
p {
  width: 300px;
  border: 2px solid red;
  padding: env(safe-area-inset-top, 50px) env(safe-area-inset-right, 50px)
    env(safe-area-inset-bottom, 50px) env(SAFE-AREA-INSET-LEFT, 50px);
}

示例值

css
/* zero for all rectangular user agents */
padding: env(safe-area-inset-bottom, 50px);

/* 50px because UA properties are case sensitive */
padding: env(Safe-area-inset-bottom, 50px);

/* as if padding: '50px 20px' were set because x is not a valid environment variable */
padding: env(x, 50px 20px);

/* ignored because '50px, 20px' is not a valid padding value and x is not a valid environment variable */
padding: env(x, 50px, 20px);

回退值的语法,就像自定义属性一样,允许使用逗号。但是,如果属性值不支持逗号,则该值无效。

注意:用户代理属性不会被all属性重置。

使用 env() 确保内容不会被桌面 PWA 中的窗口控制按钮遮挡

在下面的例子中,env()确保在使用 窗口控制叠加 API 的桌面渐进式 Web 应用程序中显示的内容不会被操作系统的窗口控制按钮遮挡。titlebar-area-*值定义了一个矩形,标题栏通常会在该矩形中显示。在不支持窗口控制叠加功能的设备上,例如移动设备,使用回退值。

以下是通常安装在桌面设备上的 PWA 的样子

Illustration of what a PWA installed on desktop normally looks like, with window control buttons, a title bar, and web content below that

使用窗口控制叠加功能,Web 内容覆盖整个应用程序窗口表面积,窗口控件和 PWA 按钮以叠加方式显示

Illustration of what a PWA installed on desktop looks like with the Window Controls Overlay feature, with window control buttons, no title bar, and web content spanning the whole window

html
<header>Title of the app here</header>
<main>Main content of app here</main>
css
header {
  position: fixed;
  left: env(titlebar-area-x);
  top: env(titlebar-area-y);
  width: env(titlebar-area-width);
  height: env(titlebar-area-height);
}

main {
  margin-top: env(titlebar-area-height);
}

注意:使用position:fixed确保标题不会随着其他内容滚动,而是与窗口控制按钮保持对齐,即使在支持弹性过度滚动的设备/浏览器上(也称为橡皮筋效果)。

规范

规范
CSS 环境变量模块级别 1
# env-function

浏览器兼容性

BCD 表格仅在浏览器中加载

另请参阅