Animowanie do pierwotnych rozmiarów

Funkcje internetowe: calc-size() interpolate-size

Animowanie elementów do rozmiarów dynamicznych, takich jak block-size: auto lub inline-size: max-content, wymagało wcześniej użycia JavaScriptu lub niestabilnych rozwiązań typu „max-height”. Właściwość interpolate-size i funkcja calc-size() umożliwiają przeglądarce natywne interpolowanie między stałymi długościami a słowami kluczowymi dotyczącymi rozmiaru wewnętrznego.

Etapy wdrażania

  1. Włączanie interpolacji słów kluczowych: zastosuj interpolate-size: allow-keywords do elementu nadrzędnego (zwykle :root), aby włączyć przejścia dla właściwości korzystających z wewnętrznych słów kluczowych.
  2. Zdefiniuj przejście: ustaw transition dla właściwości rozmiaru (np. block-size, inline-size) w elemencie docelowym.
  3. Używaj słów kluczowych związanych z rozmiarem wewnętrznym: podczas interakcji (np. :hover lub klasy stanu) zmień właściwość rozmiaru na obsługiwane słowo kluczowe związane z rozmiarem wewnętrznym – auto, min-content, max-content, fit-content lub (w przypadku flex-basis) content.
  4. Wykonywanie obliczeń (opcjonalnie): użyj calc-size(), jeśli chcesz wykonać obliczenia matematyczne na rozmiarze wewnętrznym (np. auto + 2rem). calc-size() obsługuje też słowo kluczowe any do obliczeń niezależnych od podstawy.

Przykład: ogólny wzorzec rozwijania

Możesz zastosować ten wzorzec do dowolnego kontenera (np. sekcji „Pokaż więcej” lub menu nawigacyjnego), aby przechodzić między ograniczoną wysokością a naturalnym rozmiarem elementu.

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

Przykład: obliczony wewnętrzny rozmiar inline

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

Przykład: przejście z rozmiaru wewnętrznego na stały

Możesz też animować w przeciwnym kierunku – od naturalnego rozmiaru do określonej długości. Jest to przydatne w przypadku komponentów, które można zamknąć.

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

Ograniczenia kluczy

  • Ograniczenie dotyczące słów kluczowych: nie można animować bezpośrednio między 2 różnymi słowami kluczowymi (np. od min-content do max-content). Jeden koniec przejścia musi mieć stałą długość lub wartość procentową (np. od 0 do auto).
  • Składnia calc-size: w funkcji calc-size() nie można mieszać różnych słów kluczowych w tym samym wyrażeniu. Pierwszy argument (podstawa) określa, co reprezentuje size.
  • Wymóg akceptacji: przejścia na słowa kluczowe wewnętrzne są domyślnie wyłączone (numeric-only), aby zachować zgodność wsteczną. Musisz zastosować interpolate-size: allow-keywords do elementu lub elementu nadrzędnego. calc-size() działa jako zastąpienie dla poszczególnych właściwości, automatycznie włączając interpolację za każdym razem, gdy jest używana.

Strategie zastępcze

interpolate-size i calc-size() to progresywne ulepszanie. Przeglądarki, które nie obsługują tej funkcji, będą natychmiast przechodzić do rozmiaru docelowego.

  • Łagodna degradacja: w przypadku prostych przejść block-size: auto standardowe przeglądarki po prostu natychmiast przełączą rozmiar, co jest funkcjonalne, ale mniej dopracowane.
  • Ręczne ustawianie zastępczych słów kluczowych: gdy używasz calc-size(), zawsze podawaj standardowe zastępcze słowo kluczowe dla starszych przeglądarek, ponieważ odrzucą one całą deklarację 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;
}