使用環境變數
CSS 環境變數模組引入了 CSS 中環境變數的概念,並定義了 env() 函式來啟用環境變數。在本指南中,我們將瞭解什麼是環境變數、瀏覽器定義的環境變數,以及如何使用環境變數和 env() 函式。
什麼是環境變數?
CSS 環境變數是全域性變數;其作用域是整個文件。它們由使用者代理定義。環境變數是瀏覽器或作業系統提供的特殊值,可幫助你的樣式適應使用者的裝置或上下文。它們透過 env() 函式訪問。
環境變數的工作方式類似於自定義屬性和 var() 函式,但它們是全域性定義和作用域的。這意味著它們的作用域始終是整個文件,而不像自定義屬性那樣作用於元素。此外,環境變數是隻讀的,而自定義屬性是可變的。
與自定義屬性類似,環境變數是區分大小寫的。與自定義屬性不同,自定義屬性不能在宣告之外使用,而 env() 函式可以用來替代屬性值的任何部分,或描述符的任何部分(例如,在 媒體查詢規則中)。
History
Apple 最早在 iOS Safari 瀏覽器中引入了環境變數,以使開發者能夠為不規則的裝置顯示最佳化佈局。例如帶有劉海和曲面邊緣的裝置。最初的 safe-area-inset-* 環境變數允許開發者將內容放置在視口的安全區域內,無論使用者使用何種裝置或瀏覽器。
用例
使用環境變數可以解決的常見問題包括:
- 裝置通知遮擋應用程式使用者介面的部分割槽域。
- 處理動態鍵盤顯示和隱藏時的視口大小變化。
- 在漸進式 Web 應用(PWA)安裝後,將元素放置在標題欄原本所在的位置,並確保內容不會與視窗控制按鈕重疊。這在桌面瀏覽器上尤其是一個問題。
瀏覽器定義的環境變數
CSS 環境變數規範定義了一些區分大小寫的變數,包括:
preferred-text-scale-
preferred-text-scale環境變量表示使用者首選的文字縮放因子。這是對作業系統或使用者代理的“預設”字型大小所做的調整。在text-size-adjust生效的裝置和瀏覽器上,這是text-size-adjust: auto應用的縮放因子。例如,如果text-size-adjust: auto會導致文字大小加倍,那麼env(preferred-text-scale)將解析為2。 safe-area-inset-*-
四個安全區域內邊距環境變數——
safe-area-inset-top、safe-area-inset-right、safe-area-inset-bottom和safe-area-inset-left——透過其與視口邊緣的上、右、下、左的內邊距來定義一個矩形安全區域。將內容放置在此區域內是安全的,不會被非矩形顯示的形狀所切斷。對於矩形、無遮擋的視口,如常規的桌上型電腦和筆記型電腦顯示器,這四個值都等於0。對於非矩形顯示——包括帶有圓角的全面屏裝置和圓形或圓形顯示的智慧手錶——這四個由使用者代理設定的值形成一個矩形,使得矩形內的所有內容都是可見且無遮擋的。 safe-area-max-inset-*-
四個安全區域最大內邊距環境變數——
safe-area-max-inset-top、safe-area-max-inset-right、safe-area-max-inset-bottom和safe-area-max-inset-left——各自代表其動態對應的safe-area-inset-*變數的靜態最大值。它們代表當所有動態使用者介面功能都收起時,其safe-area-inset-*對應項的最大值。例如,在某些平臺上,向上或向下滾動時可能會顯示一個按鈕欄,從而改變safe-area-inset-*的值。雖然safe-area-inset-*的值會隨著當前可見內容區域的變化而變化,但safe-area-max-inset-*的值始終保持不變。 viewport-segment-*-
這些變數僅與具有多個分割槽的裝置相關,例如可摺疊手機。
viewport-segment-bottom、viewport-segment-left、viewport-segment-right和viewport-segment-top變數,以及viewport-segment-height和viewport-segment-width,定義了視口中邏輯上分離的區域的位置和尺寸。這些變數僅在視口被劃分為至少兩個分割槽時才會被定義。它們用於將 UI 的不同部分舒適地放置在多分段裝置的不同分段中,並避免你的內容被摺疊處切斷。
其他規範定義了額外的環境變數。
視窗控制元件覆蓋 API 定義了 WindowControlsOverlay 介面,該介面公開了安裝在桌面裝置上的漸進式 Web 應用(PWA)中標題欄區域的幾何資訊。當使用 window-controls-overlay display_override 值時,會定義以下環境變數:
titlebar-area-*-
titlebar-area-x、titlebar-area-y、titlebar-area-width和titlebar-area-height變數定義了在桌面環境中執行的已安裝 Web 應用中通常由標題欄佔據的區域。使用titlebar-area-*變數來確保內容不會與視窗控制按鈕(即最小化、最大化和關閉)重疊。 keyboard-inset-*-
keyboard-inset-top、keyboard-inset-right、keyboard-inset-bottom、keyboard-inset-left、keyboard-inset-width和keyboard-inset-height變數提供了關於螢幕虛擬鍵盤位置和大小的資訊,特別是其與視口邊緣的上、右、下、左的內邊距(寬度和高度內邊距是根據其他內邊距計算的)。要了解更多資訊,請參閱 VirtualKeyboard API。
你可能已經注意到,前面所有的變數名都包含了物理術語左、右、上、下、高和寬。不需要邏輯等價物,因為變數名指的是裝置硬體的物理屬性,而不是顯示的網站。
env() 函式
env() 函式用於將環境變數的值插入到 CSS 上下文中。env() 函式可以用於任何元素上任何屬性值的任何部分,或任何 at-rule 規則上任何描述符值的任何部分,包括在自定義屬性值中。它可以在任何允許使用 CSS 值的地方使用。
基本語法如下:
env( <environment-variable-name> )
env( <environment-variable-name>, <fallback-value> )
該函式接受一個區分大小寫的環境變數名和一個可選但通常推薦的回退值。
line-height: env(preferred-text-scale, 2);
margin: env(safe-area-inset-top, 0) env(safe-area-inset-right, auto)
env(safe-area-inset-bottom, 3em) env(safe-area-inset-left, auto);
第一個引數是要替換的環境變數的名稱。如果提供了逗號後的引數,則為回退值,當第一個引數引用的環境變數不存在時使用該值。在這些示例中,如果瀏覽器中不存在 preferred-text-scale 環境變數,則 line-height 將被設定為 2。並且,如果瀏覽器沒有 safe-area-inset-* 值,則 margin 將被設定為 margin: 0 auto 3em auto。
回退值的語法類似於自定義屬性的語法,因為它允許多個逗號。第一個逗號和函式末尾之間的任何內容都被視為回退值。然而,如果屬性值或描述符不支援逗號,則該值無效。
如果一個屬性或描述符包含了語法上有效的 env() 函式,它在解析時被認為是有效的。它僅在計算時進行語法檢查,即在 env() 函式被替換為其瀏覽器提供的值之後。如果作為第一個引數傳遞的環境變數不是一個可識別的環境變數名,則使用回退值。回退值可以是另一個環境變數,甚至帶有它自己的回退值。如果沒有提供回退值,則包含 env() 函式的屬性或描述符在計算值時是無效的。
使用 env() 函式和環境變數的示例
我們可以使用環境變數來確保固定的應用工具欄不會被裝置底部出現的通知所遮擋。在螢幕底部顯示通知的裝置上,使用者代理將 safe-area-inset-bottom 環境變數的值設定為從遮擋視口的內容頂部到視口底部的距離;在我們的示例中,這很可能是任何可見通知的高度。在矩形的桌面顯示器上,safe-area-inset-bottom 通常是 0。我們將使用這個值在視口底部建立空間,以便通知顯示而不會遮擋內容。
我們的 <body> 有兩個子元素;<main> 包含了我們整個應用,除了 <footer> 工具欄。
<body>
<main>Application</main>
<footer>Toolbar</footer>
</body>
<body> 被定義為一個填充視口高度的 flex 容器。<main> 應用被允許增長以填充其兄弟元素 <footer> 未佔用的任何空間。
body {
display: flex;
flex-flow: column nowrap;
height: 100vh;
}
main {
flex: 1;
padding: 1em;
overflow-y: auto;
}
<footer> 被定位以固定在視口的底部。position: sticky 宣告根據 bottom 值為 0,將元素相對於 <body>(其滾動祖先和包含塊)進行偏移。我們給 <footer> 一個四邊都是 1em 的 padding 值。然後,我們將 safe-area-inset-bottom 的值加到 1em 的底部內邊距上,並提供 1em 的回退值。
footer {
position: sticky;
bottom: 0;
padding: 1em;
padding-bottom: calc(1em + env(safe-area-inset-bottom, 1em));
}
為簡潔起見,隱藏了額外的 CSS。
在 safe-area-inset-bottom 環境變數值大於 0 的裝置上,頁尾的底部內邊距將超過 1em。這個 CSS 提供了額外的內邊距,以便根據需要擴充套件頁尾,無論是由於通知、螢幕上的裝置劉海,還是因為裝置沒有方形的角落。
未來,我們可能會看到對開發者定義的環境變數的支援,但這尚未被定義或實現。