Menganimasikan ke Ukuran Intrinsik

Menganimasikan elemen ke ukuran dinamis seperti block-size: auto atau inline-size: max-content secara historis memerlukan JavaScript atau peretasan "max-height" yang rentan. Properti interpolate-size dan fungsi calc-size() memungkinkan browser melakukan interpolasi secara native antara panjang tetap dan kata kunci ukuran intrinsik.

Langkah-langkah implementasi

  1. Mengaktifkan interpolasi kata kunci: Terapkan interpolate-size: allow-keywords ke elemen induk (biasanya :root) untuk mengaktifkan transisi untuk properti yang menggunakan kata kunci intrinsik.
  2. Tentukan transisi: Tetapkan transition untuk properti ukuran (misalnya, block-size, inline-size) pada elemen target.
  3. Gunakan kata kunci intrinsik: Ubah properti ukuran menjadi kata kunci intrinsik yang didukung—auto, min-content, max-content, fit-content, atau (untuk flex-basis) content—selama interaksi (misalnya, :hover atau class status).
  4. Melakukan penghitungan (Opsional): Gunakan calc-size() jika Anda perlu melakukan penghitungan matematika pada ukuran intrinsik (misalnya, auto + 2rem). calc-size() juga mendukung kata kunci any untuk penghitungan yang tidak bergantung pada basis.

Contoh: Pola Perluasan Generik

Anda dapat menerapkan pola ini ke penampung apa pun (seperti bagian "Tampilkan Lainnya" atau menu navigasi) untuk melakukan transisi antara tinggi yang dibatasi dan ukuran alami elemen.

/* 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;
}

Contoh: Ukuran Inline Intrinsik yang Dihitung

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

Contoh: Contoh: Transisi dari Intrinsik ke Tetap

Anda juga dapat menganimasikan ke arah yang berlawanan—mulai dari ukuran alami dan diciutkan ke panjang tertentu. Hal ini berguna untuk komponen yang "dapat ditutup".

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

Batasan kunci

  • Batasan Kata Kunci ke Kata Kunci: Anda tidak dapat menganimasikan antara dua kata kunci yang berbeda secara langsung (misalnya, dari min-content ke max-content). Salah satu ujung transisi harus berupa panjang atau persentase tetap (misalnya, 0 ke auto).
  • Sintaksis Calc-size: Di dalam calc-size(), Anda tidak dapat menggabungkan berbagai kata kunci intrinsik dalam ekspresi yang sama. Argumen pertama (dasar) menentukan apa yang diwakili oleh size.
  • Persyaratan Keikutsertaan: Transisi ke kata kunci intrinsik dinonaktifkan secara default (numeric-only) untuk mempertahankan kompatibilitas mundur. Anda harus menerapkan interpolate-size: allow-keywords ke elemen atau ancestor. calc-size() bertindak sebagai penggantian per properti, yang otomatis mengaktifkan interpolasi setiap kali digunakan.

Strategi penggantian

interpolate-size dan calc-size() adalah progressive enhancement. Browser yang tidak mendukungnya akan langsung beralih ke ukuran target.

  • Degradasi Halus: Untuk transisi block-size: auto sederhana, browser standar hanya akan mengubah ukuran secara instan, yang berfungsi tetapi kurang rapi.
  • Penggantian kata kunci manual: Saat menggunakan calc-size(), selalu berikan penggantian kata kunci standar untuk browser lama, karena browser tersebut akan menghapus seluruh deklarasi 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;
}