env()

Baseline 廣泛可用 *

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2020 年 1 月⁩ 起,所有主流瀏覽器均已支援。

* 此特性的某些部分可能存在不同級別的支援。

env() CSS 函式可用於將使用者代理定義的環境變數的值插入到 CSS 中。

語法

css
/* Without a fallback value */
env(safe-area-inset-top);
env(titlebar-area-width);
env(viewport-segment-right 0 0);

/* With a fallback value */
env(safe-area-inset-right, 1em);
env(titlebar-area-y, 40px);
env(viewport-segment-width 0 0, 40%);

引數

env( <environment-variable>, <fallback> ) 函式接受以下引數:

<environment-variable>

一個 <custom-ident>,指定要插入的環境變數的名稱。如果提供的名稱表示一個類陣列環境變數,則名稱後會跟一個或多個 <integer> 值,用於標識該名稱引用的特定例項。區分大小寫的環境變數名稱可以是以下之一:

safe-area-inset-topsafe-area-inset-rightsafe-area-inset-bottomsafe-area-inset-left

從視口頂部、右側、底部或左側內邊距邊緣的安全距離,定義了可以將內容安全放置而不會被非矩形顯示器的形狀切斷的區域。這四個值形成一個矩形,在此矩形內的所有內容都是可見的。如果視口是矩形,並且沒有工具欄或動態鍵盤等功能佔用視口空間,則這些值為 0;否則,它是一個大於 0px 值。

safe-area-max-inset-topsafe-area-max-inset-rightsafe-area-max-inset-bottomsafe-area-max-inset-left

當所有動態使用者介面功能都收起時,其對應的動態 safe-area-inset-* 變數的靜態最大值。雖然 safe-area-inset-* 的值會隨著當前可見內容區域的變化而變化,但 safe-area-max-inset-* 的值是常量。

titlebar-area-xtitlebar-area-ytitlebar-area-widthtitlebar-area-height

可見的 titlebar-area-* 區域的尺寸。當使用清單欄位 display_overridewindow-controls-overlay 值時,這些變數可用。這些變數的值可用於確保在桌面裝置上安裝的漸進式 Web 應用(PWA)中,內容不會與視窗控制按鈕(即最小化、最大化和關閉)重疊。

keyboard-inset-topkeyboard-inset-rightkeyboard-inset-bottomkeyboard-inset-leftkeyboard-inset-widthkeyboard-inset-height

裝置螢幕虛擬鍵盤相對於視口邊緣的內邊距和尺寸。在 VirtualKeyboard API 中定義。

viewport-segment-widthviewport-segment-heightviewport-segment-topviewport-segment-rightviewport-segment-bottomviewport-segment-left

特定視口分段的尺寸和偏移位置。viewport-segment-* 關鍵字後跟兩個以空格分隔的 <integer> 值,表示分段的水平和垂直位置或索引。僅當視口由兩個或多個分段組成時(如在可摺疊或帶鉸鏈的裝置上),才會定義 viewport-segment 關鍵字。

<fallback> 可選

一個備用值,如果第一個引數中引用的環境變數不存在,則會插入此值。第一個逗號之後的所有內容都被視為備用值。這可以是一個單一的值、另一個 env() 函式,或者一個用逗號分隔的值列表。

描述

env() 函式用於將全域性作用域的、使用者代理定義的環境變數的值插入到你的 CSS 中。env() 函式可以用作屬性值,或代替屬性值或描述符的任何部分(例如,在媒體查詢規則中)。

該函式接受一個 <environment-variable> 作為其第一個引數。這是一個區分大小寫的 <custom-ident>,與要替換的環境變數的名稱相等,但如果需要,也可以包含額外的以空格分隔的值。例如,env(viewport-segment-width 0 0) 將返回具有多個視口分段的裝置上頂部或左側分段的寬度。

第二個引數(如果提供)是備用值,如果第一個引數中引用的環境變數不受支援或不存在,則使用該值。備用值可以是另一個環境變數,甚至可以帶有自己的備用值。

備用值的語法類似於用於插入 CSS 自定義屬性var() 函式的備用值語法,它允許使用多個逗號。第一個逗號和函式末尾之間的任何內容都被視為備用值。但是,如果 env() 函式在不包含逗號的屬性值或描述符中使用,那麼包含逗號的備用值將是無效的。

當瀏覽器首次讀取和解釋下載的 CSS 文字時,包含語法有效的 env() 函式的屬性或描述符在解析時被假定為有效。它僅在計算時進行語法檢查,即在每個 env() 函式被其瀏覽器提供的值(或備用值,如果作為第一個引數傳遞的環境變數不是一個可識別的環境變數名)替換之後。如果該值無效且未提供備用值,則包含 env() 函式的屬性或描述符在計算值時無效

env() 替換無效,並且包含了無效的備用值或省略了備用值時,該宣告不會被忽略。相反,會使用屬性的初始值繼承值。該屬性被設定為一個新值,但可能不是預期的值。

用例

最初由 iOS 瀏覽器提供,用於允許開發者將其內容放置在視口的安全區域內,而不會被裝置劉海或圓角遮擋,safe-area-inset-* 值可以用來幫助確保內容對觀看者可見。此功能後來擴充套件到其最初目的之外,以支援諸如防止裝置通知覆蓋部分應用使用者介面等用例。

env() 變數的另一個用例是桌面漸進式 Web 應用(PWA),這些應用使用視窗控制元件覆蓋功能來利用整個應用程式視窗的表面區域。使用 titlebar-area-*,開發者可以將元素放置在標題欄原本所在的位置,並確保內容不會被視窗控制按鈕遮擋

viewport-segment-* 變數名可用於設定你的容器,使其整齊地適應多視口分段裝置(如鉸鏈式或可摺疊裝置)的可用分段。viewport-segment-* 名稱後面的整數表示環境變數所引用的多個分段中的哪一個。

名稱後跟整數

當環境變數是類陣列時,意味著該名稱可能引用多個值,例如在具有多個視口分段的裝置上,<environment-variable> 引數既包括變數的名稱,也包括函式所引用的變數特定例項的索引。例如,對於 viewport-segment-* 變數,變數名稱與兩個整數一起傳遞給 env() 函式,這兩個整數表示要返回其值的分段的索引。這些值都是 0 或更大的整數。第一個整數表示分段的水平索引,其中 0 是最左邊的分段,第二個值表示分段的垂直索引,其中 0 表示最底部的分段。

Two device segment layouts; in a horizontal layout, 0 0 is the first segment and 1 0 is the second segment. In a vertical layout, the indices are 0 0 and 0 1

  • 在水平並排佈局中,左側分段由 0 0 表示,右側分段由 1 0 表示。
  • 在垂直從上到下佈局中,頂部片段由 0 0 表示,底部片段由 0 1 表示。
  • 在具有兩個以上分段的裝置中,數字可能會更大。例如,具有三個水平分段的裝置可能用 1 0 表示中心分段,用 2 0 表示右側分段。

例如,以下程式碼返回一個雙分段可摺疊裝置上右側分段的寬度,其中分段是水平排列的:

css
env(viewport-segment-width 1 0)

有關完整的可執行演示,請參閱 Viewport segment API 演示原始碼)。另請檢視使用 Viewport Segments API 以獲取完整的演示說明。

正式語法

<env()> = 
env( <custom-ident> <integer [0,∞]>* , <declaration-value>? )

示例

使用 env() 確保按鈕不被裝置 UI 遮擋

在以下示例中,env() 用於確保固定的應用工具欄按鈕不會被出現在螢幕底部的裝置通知所遮擋。在桌面上,safe-area-inset-bottom0。然而,在螢幕底部顯示通知的裝置上,例如 iOS,它包含一個為通知顯示留出空間的值。然後,這個值可以用於 padding-bottom 的值中,以建立一個在該裝置上看起來自然的間隙。

HTML

我們有一個包含偽應用程式的 <main> 部分和一個包含兩個 <button> 元素的 <footer>

html
<main>Main content of app here</main>
<footer>
  <button>Go here</button>
  <button>Or here</button>
</footer>

CSS

使用 CSS 彈性盒子佈局,我們建立了一個高度僅為所需高度的頁尾,而包含應用程式的主體部分則填滿了視口的其餘部分:

css
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  font: 1em system-ui;
}

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

footer {
  flex: none;
  display: flex;
  gap: 1em;
  justify-content: space-evenly;
  background: black;
}

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

我們設定 position: sticky 將頁尾固定在視口的底部。然後,我們使用 padding 簡寫為頁尾新增內邊距。我們將 safe-area-inset-bottom 環境變數的值新增到初始的 1em 底部內邊距中。在對此變數具有正值的裝置上,將顯示一個更大的黑色區域,以確保頁尾中的按鈕永遠不會被遮擋。

css
footer {
  position: sticky;
  bottom: 0;

  padding: 1em 1em calc(1em + env(safe-area-inset-bottom));
}

結果

使用備用值

此示例利用了 env() 的可選第二個引數,該引數在環境變數不可用時提供備用值。

HTML

我們包含一段文字:

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

我們設定了 300pxwidth 和一個 border。然後我們新增 padding,使用 env() 函式併為每邊的內邊距大小提供一個備用值。我們故意為左內邊距設定了一個無效的值(請記住,環境變數名稱是區分大小寫的),以演示備用值的使用。

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);
}

結果

使用 env() 確保內容不被桌面 PWA 中的視窗控制按鈕遮擋

在以下示例中,env() 確保在使用 Window Controls Overlay 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 可以確保標題欄不會隨其餘內容滾動,而是與視窗控制按鈕保持對齊,即使在支援彈性過度滾動(也稱為橡皮筋效應)的裝置/瀏覽器上也是如此。

視口分段

Viewport segment API 演示使用 Viewport Segments API 指南提供了使用 env() 函式和 viewport-segments-* 環境變數的演示和說明。

規範

規範
CSS Environment Variables Module Level 1
# env-function

瀏覽器相容性

另見