Animationen zu intrinsischen Größen

Webfunktionen: calc-size() interpolate-size

Für die Animation von Elementen auf dynamische Größen wie block-size: auto oder inline-size: max-content war bisher JavaScript oder ein fehleranfälliger „max-height“-Hack erforderlich. Mit der Property interpolate-size und der Funktion calc-size() kann der Browser nativ zwischen festen Längen und intrinsischen Größen-Keywords interpolieren.

Implementierungsschritte

  1. Keyword-Interpolation aktivieren: Wenden Sie interpolate-size: allow-keywords auf ein übergeordnetes Element (normalerweise :root) an, um Übergänge für Properties mit intrinsischen Keywords zu aktivieren.
  2. Übergang definieren: Legen Sie für das Zielelement einen transition für die Größenanpassungseigenschaft (z.B. block-size, inline-size) fest.
  3. Intrinsische Keywords verwenden: Ändern Sie die Größen-Property während einer Interaktion (z.B. :hover oder eine Zustandsklasse) in ein unterstütztes intrinsisches Keyword: auto, min-content, max-content, fit-content oder (für „flex-basis“) content.
  4. Berechnungen durchführen (optional): Verwenden Sie calc-size(), wenn Sie Berechnungen mit einer intrinsischen Größe durchführen müssen (z.B. auto + 2rem). calc-size() unterstützt auch das Keyword any für basisunabhängige Berechnungen.

Beispiel: Generisches Erweiterungsmuster

Sie können dieses Muster auf jeden Container anwenden (z. B. einen Bereich „Mehr anzeigen“ oder ein Navigationsmenü), um zwischen einer eingeschränkten Höhe und der natürlichen Größe des Elements zu wechseln.

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

Beispiel: Berechnete intrinsische Inline-Größe

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

Beispiel: Übergang von intrinsisch zu fest

Sie können auch in die entgegengesetzte Richtung animieren, also von einer natürlichen Größe ausgehen und auf eine bestimmte Länge reduzieren. Das ist nützlich für „schließbare“ Komponenten.

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

Schlüsseleinschränkungen

  • Einschränkung für Keyword-zu-Keyword-Übergänge: Sie können nicht direkt zwischen zwei verschiedenen Keywords animieren (z.B. von min-content zu max-content). Ein Ende des Übergangs muss eine feste Länge oder ein Prozentsatz sein (z.B. 0 zu auto).
  • Syntax von „calc-size“: Innerhalb von calc-size() können Sie nicht verschiedene intrinsische Keywords im selben Ausdruck mischen. Das erste Argument (die Basis) definiert, was size darstellt.
  • Aktivierungsanforderung: Umstellungen auf intrinsische Keywords sind standardmäßig deaktiviert (numeric-only), um die Abwärtskompatibilität zu gewährleisten. Sie müssen interpolate-size: allow-keywords auf das Element oder ein übergeordnetes Element anwenden. calc-size() fungiert als Überschreibung pro Attribut und aktiviert die Interpolation automatisch, wenn sie verwendet wird.

Fallback-Strategien

interpolate-size und calc-size() sind progressive Verbesserungen. In Browsern, die sie nicht unterstützen, wird sofort zur Zielgröße gesprungen.

  • Graduelle Fehlertoleranz: Bei einfachen block-size: auto-Übergängen wird die Größe in Standardbrowsern einfach sofort umgeschaltet. Das funktioniert, sieht aber nicht so gut aus.
  • Manuelle Keyword-Fallbacks: Wenn Sie calc-size() verwenden, sollten Sie immer ein Standard-Keyword-Fallback für ältere Browser angeben, da diese die gesamte calc-size()-Deklaration verwerfen.
.card {
  block-size: auto; /* Fallback for older browsers */
  block-size: calc-size(auto, size); /* Modern browsers use this */
  transition: block-size 0.3s ease;
}