polyfill 收到重大更新時,容器查詢開始進入穩定版瀏覽器

Gerald Monaco
Gerald Monaco

容器查詢功能現已推出!

好消息!開發人員最常要求的功能之一,現在已開始在網路瀏覽器中推出!自 Chromium 105Safari 16 起,您現在可以建立以大小為依據的容器查詢,並在這些瀏覽器中使用容器查詢單位值。為了讓使用者更輕鬆地使用以大小為準的容器查詢和 cq 單位,Chrome 的 Aurora 團隊一直努力更新容器查詢填充,以便支援更多瀏覽器和用途,讓您能放心使用這項強大的功能。

什麼是容器查詢?

容器查詢是 CSS 功能,可讓您撰寫樣式邏輯,指定父項元素的功能,為其子項設定樣式。您可以查詢父項的大小,建立真正以元件為基礎的回應式設計。這項資訊比媒體查詢更精細且實用,後者只會提供檢視區大小資訊。

ALT_TEXT_HERE

您可以使用容器查詢編寫可重複使用的元件,這些元件會根據頁面位置顯示不同的樣式。這可讓這些元素在各個網頁和範本中更有彈性,並且更能即時回應。

使用容器查詢

假設你有以下 HTML 程式碼:

<!-- card parent -->
<div class=”card-parent”>
  <div class=”card>
     <!-- card contents -->
      …
  </div>
</div>

如要使用容器查詢,您必須先在要追蹤的父項元素上設定容器。如要執行這項操作,請設定 container-type 屬性,或是使用 container 速記法來同時設定容器類型和容器名稱。

.card-parent {
  /* query the inline-direction size of this parent */
  container-type: inline-size;
}

現在,您可以使用 @container 規則,根據最近的父項設定樣式。如上圖所示,如果資訊卡可能從一欄變成兩欄,請編寫類似以下的內容:

@container (min-width: 300px) {
  .card {
    /* styles to apply when the card container (.card-parent in this case) is >= 300px */
    /* I.e. shift from 1-column to 2-column layout: */
    grid-template-columns: 1fr 1fr;
  }
}

為了讓內容更整齊明確,請為父項元素容器命名:

.card-parent {
  container-type: inline-size;
  /* set name here, or write this in one line using the container shorthand */
  container-name: card-container;
}

接著,將先前的程式碼重寫為:

@container card-container (min-width: 300px) {
  .card {
    grid-template-columns: 1fr 1fr;
  }
}

容器查詢單位

為了讓容器查詢更實用,您也可以使用以容器為基礎的單位值。下表列出可能的容器單位值,以及這些值與容器大小的對應關係:

單位相對於
cqw查詢容器寬度的 1%
cqh查詢容器高度的 1%
cqi查詢容器內嵌大小的 1%
cqb查詢容器區塊大小的 1%
cqmincqi 或 cqb 中較小的值
cqmaxcqi 或 cqb 中較大的值

響應式排版是使用容器為基礎的單位的其中一個例子。以檢視區為基礎的單位 (例如 vhvbvwvi) 可用於調整螢幕上任何元素的大小。

.card h2 {
  font-size: 15cqi;
}

這段程式碼會將字型大小設為容器內嵌大小的 15%,也就是說,隨著內嵌大小 (寬度) 增加,字型會變大,反之亦然。如要進一步調整,請使用 clamp() 函式為您的排版設定最小和最大尺寸限制,並根據容器大小調整尺寸:

.card h2 {
  font-size: clamp(1.5rem, 15cqi, 3rem);
}

這樣一來,頁首就不會大於 3rem 或小於 .5rem,但會佔用容器內嵌大小的 15%。

這個示範會更進一步,更新較寬的資訊卡,讓其在 2 欄檢視畫面中顯示較小的大小範圍。

容器查詢 polyfill

容器查詢是一項強大的功能,我們希望您能放心將其納入專案,並瞭解瀏覽器支援功能的重要性。因此,我們一直致力於改善容器查詢填充功能。這個 polyfill 一般支援以下項目:

  • Firefox 69 以上版本
  • Chrome 79 以上版本
  • Edge 79 以上版本
  • Safari 13.4 以上版本

經壓縮後的大小不到 9kb,並使用 ResizeObserver 搭配 MutationObserver,以支援目前穩定版瀏覽器可用的完整 @container 查詢語法:

  • 離散查詢 (width: 300pxmin-width: 300px)。
  • 範圍查詢 (200px < width < 400pxwidth < 400px)。
  • 屬性和關鍵影格中的容器相對長度單位 (cqwcqhcqicqbcqmincqmax)。

使用容器查詢 polyfill

如要使用 polyfill,請在文件標頭中加入以下指令碼標記:

<script type="module">
  if (!("container" in document.documentElement.style)) {
    import("https://unpkg.com/container-query-polyfill@^0.2.0");
  }
</script>

您也可以使用服務,根據 User-Agent 條件式地提供 polyfill,或在自己的原點上自行代管。

為了提供最佳使用者體驗,建議您一開始只將 polyfill 用於折疊下方的內容,並使用 @supports 查詢,暫時以載入指標取代 polyfill,直到 polyfill 準備好顯示為止:

@supports not (container-type: inline-size) {
  .container,
  footer {
    display: none;
  }

  .loader {
    display: flex;
  }
}

在網路和裝置速度足夠快的情況下,或是裝置原生支援容器查詢時,系統不會顯示這項載入指標。

新的 Polyfill 功能

更新後的 polyfill 支援以下功能:

  • 巢狀 @container 規則。
  • 系統支援在 @supports@media 查詢下巢狀 @container 規則,反之亦然。
  • 在 polyfill 載入後,@supports (container-type: inline-size) 等條件 CSS 會通過。
  • 完整的 CSS 語法支援 (在語法有效的任何位置放置註解時,不會再出現任何問題)。
  • 垂直書寫模式 (透過 writing-mode)。
  • 查詢條件、屬性宣告和動畫關鍵影格支援容器相對單元 (cqwcqh 等)。查詢條件支援 remem
  • 展開的容器查詢語法:
    • 範圍語法 (例如 (200px < width < 400px))。
    • 等於查詢 (例如 (width = 200px))。
  • ::before::after 等虛擬元素。
  • 透過選用的解決方法,支援沒有 :is(...)/:where(...) 的瀏覽器
  • orientationaspect-ratio 功能查詢。
  • 根據功能正確篩選查詢 (例如,在水平書寫模式下,禁止查詢 container: inline-size 上的 height)。
  • DOM 變異 (例如,在執行階段移除 <style><link> 元素)。

多重填充限制和警告

如果您使用容器查詢 polyfill,請留意以下缺少的功能:

  • 尚未支援 Shadow DOM。
  • @media 查詢條件不支援容器相對單位 (例如 cqwcqh)。
    • Safari:在 15.4 之前的版本中,動畫關鍵影格不支援容器相對單位。
  • 查詢條件尚不支援 calc()min()max() 或其他數學函式。
  • 這個 polyfill 僅適用於內嵌和相同來源的 CSS。不支援跨來源樣式表和 iframe 中的樣式表 (除非手動載入 polyfill)。
  • layoutstyle 容器需要底層瀏覽器支援:
    • Safari 15.4 以上版本
    • Firefox 目前不支援樣式包容,但我們正在開發這項功能。

警告

  • 為避免影響 FIDCLS,即使同步載入,polyfill 也不會保證何時會出現第一個版面配置,但會嘗試避免不合理延遲 LCP。換句話說,您不應將其用於首次繪製。
  • 產生 ResizeObserver Loop Errors。原始的 polyfill 也會執行這項操作,但值得一提的是,這是因為 container-type: inline-size 的區塊大小在評估查詢後可能會變更,但 ResizeObserver 無法告知系統我們不關心區塊大小變更。
  • 這個 polyfill 已通過 Web Platform 測試,通過率達到 70%,因為 JavaScript API 等特定功能並未經過 polyfill,因此通過率會刻意接近 70%。
  • 以下瀏覽器的 2.23% 使用者必須採用 :where() 解決方法
    • Safari 14
    • Chromium 88
    • Edge 88
    • Samsung Internet 15
    • Firefox 78