以動畫方式呈現原始大小

網頁功能: calc-size() interpolate-size

過去,如要將元素動畫化為 block-size: auto 或 inline-size: max-content 等動態大小,必須使用 JavaScript 或不穩定的「max-height」駭客手法。interpolate-size 屬性和 calc-size() 函式可讓瀏覽器在固定長度和內建大小關鍵字之間,以原生方式插補。

導入步驟

  1. 選擇加入關鍵字內插:將 interpolate-size: allow-keywords 套用至父項元素 (通常是 :root),為使用內建關鍵字的屬性啟用轉場效果。
  2. 定義轉場效果:為目標元素的大小屬性 (例如 block-size、inline-size) 設定 transition。
  3. 使用內建關鍵字:在互動期間 (例如 :hover 或狀態類別),將大小屬性變更為支援的內建關鍵字:auto、min-content、max-content、fit-content 或 (適用於 flex-basis) content。
  4. 執行計算 (選用):如需對內建大小 (例如 auto + 2rem) 執行數學運算,請使用 calc-size()。calc-size() 也支援 any 關鍵字,可用於與基準無關的計算。

範例:一般展開模式

您可以將這個模式套用至任何容器 (例如「顯示更多」部分或導覽選單),在受限高度和元素的自然大小之間轉換。

/* Opt-in globally for all children */
:root {
  /* MANDATORY: Transitions to intrinsic keywords are disabled by default for compatibility */
  interpolate-size: allow-keywords;
}

.expandable-container {
  /* 1. Define a fixed initial size (or 0) and hide overflow */
  block-size: 100px;
  overflow: hidden;
  
  /* 2. Transition the sizing property */
  transition: block-size 0.4s ease-out;
}

.expandable-container.is-expanded {
  /* 3. Smoothly animate to the intrinsic natural height */
  block-size: auto;
}

範例:計算出的內建內嵌大小

.badge {
  inline-size: 40px;
  overflow: hidden;
  white-space: nowrap;
  transition: inline-size 0.3s ease;
}

.badge:hover {
  /* calc-size(basis, calculation) */
  /* 'size' refers to the evaluated basis (max-content in this case) */
  inline-size: calc-size(max-content, size + 20px);
}

範例:從內建轉換為固定

您也可以反向動畫,從自然大小開始,然後收合至特定長度。這項功能適用於「可關閉」的元件。

.collapsible-alert {
  /* 1. Start with the natural content height */
  block-size: auto;
  overflow: hidden;
  transition: block-size 0.5s ease-in-out, opacity 0.5s ease;
}

.collapsible-alert.is-dismissed {
  /* 2. Smoothly collapse to zero */
  block-size: 0;
  opacity: 0;
  pointer-events: none;
}

/* MANDATORY Copy-Paste Safety: Disable sizing animations for sensitive users */
@media (prefers-reduced-motion: reduce) {
  .expandable-container,
  .badge,
  .collapsible-alert {
    transition: none !important;
  }
}
// MANDATORY Accessibility Synchronization: Ensure elements collapsed to zero dimensions are removed from the assistive technology tree, and sync aria-expanded states on triggers.
const alertElement = document.querySelector('.collapsible-alert');
alertElement.addEventListener('transitionend', (e) => {
  if (e.propertyName === 'block-size' && alertElement.classList.contains('is-dismissed')) {
    alertElement.hidden = true;
  }
});

// Example trigger syncer
const triggerBtn = document.querySelector('.accordion-trigger');
triggerBtn?.addEventListener('click', () => {
  const isExpanded = triggerBtn.getAttribute('aria-expanded') === 'true';
  triggerBtn.setAttribute('aria-expanded', !isExpanded);
});

金鑰限制

  • 關鍵字對關鍵字限制:您無法直接在兩個不同關鍵字之間建立動畫 (例如從 min-content 到 max-content)。轉換的一端必須是固定長度或百分比 (例如 0 到 auto)。
  • Calc-size 語法:在 calc-size() 中,您無法在同一個運算式中混合不同的內建關鍵字。第一個引數 (基準) 定義 size 代表的內容。
  • 選擇加入規定:為維持回溯相容性,預設會停用轉換為內建關鍵字的功能 (numeric-only)。您必須將 interpolate-size: allow-keywords 套用至元素或祖系。calc-size() 會覆寫個別屬性,只要使用就會自動啟用內插。

備用策略

interpolate-size 和 calc-size() 是漸進增強功能。不支援這類效果的瀏覽器會立即跳至目標大小。

  • 優雅降級:對於簡單的 block-size: auto 轉換,標準瀏覽器只會立即切換大小,雖然功能正常,但較不精緻。
  • 手動關鍵字備用方案:使用 calc-size() 時,請務必為舊版瀏覽器提供標準關鍵字備用方案,因為這類瀏覽器會捨棄整個 calc-size() 宣告。
.card {
  block-size: auto; /* Fallback for older browsers */
  block-size: calc-size(auto, size); /* Modern browsers use this */
  transition: block-size 0.3s ease;
}