Animeren naar intrinsieke grootten

Voor het animeren van elementen naar dynamische formaten zoals block-size: auto of inline-size: max-content was in het verleden JavaScript of een kwetsbare max-height-hack nodig. Met de property interpolate-size en de functie calc-size() kan de browser native interpoleren tussen vaste lengtes en intrinsieke zoekwoorden voor grootte.

Stapsgewijze implementatie

  1. Aanmelden voor zoekwoordinterpolatie: Pas interpolate-size: allow-keywords toe op een bovenliggend element (meestal :root) om overgangen aan te zetten voor eigenschappen die intrinsieke zoekwoorden gebruiken.
  2. Definieer de overgang: Stel een transition in voor de formaateigenschap (bijv. block-size, inline-size) op het doelelement.
  3. Gebruik intrinsieke zoekwoorden: Wijzig de grootte-eigenschap in een ondersteund intrinsiek zoekwoord (auto, min-content, max-content, fit-content of (voor flex-basis) content) tijdens een interactie (bijvoorbeeld :hover of een statusklasse).
  4. Berekeningen uitvoeren (optioneel): Gebruik calc-size() als je berekeningen wilt uitvoeren op een intrinsieke grootte (bijv. auto + 2rem). calc-size() ondersteunt ook het zoekwoord any voor basis-agnostische berekeningen.

Voorbeeld: Algemeen uitbreidingspatroon

Je kunt dit patroon toepassen op elke container (zoals een gedeelte Meer tonen of een navigatiemenu) om over te schakelen tussen een beperkte hoogte en de natuurlijke grootte van het element.

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

Voorbeeld: berekende intrinsieke inline-grootte

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

Voorbeeld: Overgang van intrinsiek naar vast

Je kunt ook in de tegenovergestelde richting animeren: beginnend bij een natuurlijke grootte en samenvouwend tot een specifieke lengte. Dit is handig voor componenten die kunnen worden gesloten.

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

Belangrijke beperkingen

  • Beperking van zoekwoord naar zoekwoord: Je kunt niet rechtstreeks animeren tussen 2 verschillende zoekwoorden (bijvoorbeeld van min-content naar max-content). Eén uiteinde van de overgang moet een vaste lengte of een vast percentage zijn (bijvoorbeeld 0 naar auto).
  • Syntaxis van calc-size: In calc-size() kun je verschillende intrinsieke zoekwoorden niet combineren in dezelfde expressie. Het eerste argument (de basis) definieert wat size vertegenwoordigt.
  • Aanmeldingsvereiste: Overgangen naar intrinsieke zoekwoorden staan standaard uit (numeric-only) om compatibiliteit met eerdere versies te behouden. Je moet interpolate-size: allow-keywords toepassen op het element of een bovenliggend element. calc-size() fungeert als een overschrijving per property en zet interpolatie automatisch aan wanneer deze wordt gebruikt.

Reservestrategieën

interpolate-size en calc-size() zijn progressive enhancements. Browsers die deze niet ondersteunen, springen meteen naar het doelformaat.

  • Graceful degradation: Voor eenvoudige block-size: auto-overgangen schakelen standaardbrowsers het formaat onmiddellijk om. Dit is functioneel, maar minder verfijnd.
  • Handmatige zoekwoord-fallbacks: Als u calc-size() gebruikt, moet u altijd een standaard zoekwoord-fallback opgeven voor oudere browsers, omdat deze de hele calc-size()-declaratie negeren.
.card {
  block-size: auto; /* Fallback for older browsers */
  block-size: calc-size(auto, size); /* Modern browsers use this */
  transition: block-size 0.3s ease;
}