Mit intrinsischen Größen berechnen

Webfunktionen: calc-size() interpolate-size

calc-size() ist eine CSS-Funktion, mit der mathematische Operationen für intrinsische Größen-Keywords wie auto, min-content und fit-content ausgeführt werden können. OBLIGATORISCH: Verwende calc-size() nur, wenn du eine intrinsische Größe mit einer Berechnung oder Einschränkung ändern musst. Für einfache keywordbasierte Animationen (z. B. 0 zu auto) musst du interpolate-size: allow-keywords verwenden.

Implementierungsschritte

  1. Intrinsische Basis ermitteln: Bestimmen Sie, welches intrinsische Keyword (auto, min-content usw.) die Grundlage für Ihre Berechnung bilden soll.
  2. Einschränkungen definieren: Verwenden Sie im zweiten Argument mathematische CSS-Funktionen wie clamp(), min() oder max(), um Designeinschränkungen für die intrinsische Größe festzulegen.
  3. OBLIGATORISCH: Fallback angeben: Deklarieren Sie immer ein Standard-Keyword für die Größe oder Länge unmittelbar vor der Property mit calc-size(), damit das Layout in nicht unterstützten Browsern funktionsfähig bleibt.
  4. Logische Eigenschaften anwenden: Standardmäßig werden logische Eigenschaften wie inline-size oder block-size verwendet, damit die Berechnungen den Schreibmodus des Dokuments berücksichtigen.
  5. Optional: Progressive Verbesserung: Verpacken Sie komplexe Layoutlogik oder Animationen in einen @supports (inline-size: calc-size(auto, size + 0px))-Block, um erweiterte Funktionen nur für kompatible Browser bereitzustellen.

Grundlegende Syntax

/* calc-size(<calc-size-basis>, <calc-sum>) — mathematical operations on intrinsic sizing keywords */
.element {
  /* MANDATORY: Always provide a fallback for browsers that do not support calc-size() */
  inline-size: min-content;
  
  /* DO: Use calc-size to modify an intrinsic basis with a calculation or function */
  inline-size: calc-size(min-content, size + 2rem);
}

Gültige Basisargumente (<calc-size-basis>)

Das erste Argument definiert die „Basisgröße“ für die Berechnung.

Standard-Keywords:

  • auto: Die Standardgröße für das Element.
  • min-content: Die kleinste Größe, die das Element ohne Überlauf annehmen kann.
  • max-content: Die Größe, die das Element benötigt, damit der gesamte Inhalt in eine Zeile passt.
  • fit-content: Entspricht clamp(min-content, auto, max-content).
  • content: Nur gültig, wenn calc-size() innerhalb der Property flex-basis verwendet wird.

Spezielle Argumente:

  • any: Eine allgemeine Basis, die verwendet wird, wenn der spezifische intrinsische Typ unbekannt ist oder wenn Berechnungen verschachtelt werden.
  • Verschachteltes calc-size(): Ermöglicht mehrstufige oder bedingte Berechnungen.
  • <calc-sum>: Eine bestimmte Länge, ein Prozentsatz oder ein mathematischer Ausdruck (z.B. 100px oder 20%). Wenn ein fester Wert als Basis verwendet wird, ist das Schlüsselwort size weiterhin verfügbar (aber nur innerhalb des zweiten Arguments) und stellt den aufgelösten Wert dieser Basis dar.

OBLIGATORISCH: Das Schlüsselwort size ist im ersten Argument (<calc-size-basis>) selbst nicht gültig. Es handelt sich um eine lokale Variable, die nur dazu dient, im zweiten Argument (<calc-sum>) auf die Basis zu verweisen.

Gültige Berechnungsargumente (<calc-sum>)

Das zweite Argument ist der mathematische Ausdruck.

  • In der Regel wird das Keyword size verwendet, um auf den Wert der Basis zu verweisen.
  • Das Keyword size ist zwar technisch optional, aber wenn Sie es weglassen, wird die Berechnung zu einem festen Wert aufgelöst und die Basis wird vollständig ignoriert.
  • Sie kann mathematische Standardoperatoren (+, -, *, /) enthalten.
  • Es kann mathematische CSS-Funktionen wie clamp(), min(), max() und round() enthalten.
  • OBLIGATORISCH: calc-size() lässt nur einen einzigen intrinsischen Größenwert (die Basis) in jeder Berechnung zu. Sie können Keywords für die intrinsische Größenanpassung nicht im selben calc-size()-Aufruf mischen.

Anwendungsfälle

Animationen zu und von intrinsischen Größen

Standardmäßig können Browser nicht zwischen einer Länge (z.B. 0px) und einem intrinsischen Keyword (z.B. auto) interpolieren. Wenn Sie das Keyword in calc-size() einschließen, wird es zu einem interpolierbaren Wert.

Das richtige Tool für Animationen auswählen

  • OBLIGATORISCH: interpolate-size: allow-keywords verwenden: Für einfache Animationen zu oder von intrinsischen Größen (z.B. height: 0 zu height: auto) ohne mathematische Änderungen. Dies ist der erforderliche Ansatz für die einfache Keyword-Interpolation und sollte idealerweise global über :root angewendet werden.

    :root {
      /* Best practice: Enable keyword interpolation globally */
      interpolate-size: allow-keywords;
    }
    
    .item {
      height: 0;
      transition: height 0.3s ease;
    }
    
    .item.open {
      /* Simple interpolation from 0 to auto now works without calc-size() */
      height: auto;
    }
    
  • calc-size() verwenden: NUR, wenn Sie während eines Übergangs mathematische Berechnungen für eine intrinsische Größe durchführen müssen (z.B. Padding hinzufügen oder die Größe begrenzen).

.accordion-content {
  display: block;
  overflow: hidden;
  /* MANDATORY: Fallback value for closed state */
  block-size: 0;
  transition: block-size 0.3s ease-out;
}

.accordion-content.open {
  /* MANDATORY: Fallback value for open state */
  block-size: auto;

  /* 
    DO: Use calc-size(auto, ...) to enable animation from 0 to the element's 
    intrinsic size while doing a calculation (in this case, adding a space of 2rem).
  */
  block-size: calc-size(auto, size + 2rem);
}

OBLIGATORISCH: Die Interpolation zwischen zwei Schlüsselwörtern für die intrinsische Größe ist nicht direkt möglich. Ein Ende des Übergangs muss eine Länge oder ein Prozentsatz sein.

Nutzereinstellungen für Bewegungen berücksichtigen

Animationen, die die Größe großer Layoutbereiche ändern, können für Nutzer mit vestibulären Störungen besonders störend sein. OBLIGATORISCH: Berücksichtigen Sie immer die Bewegungseinstellungen der Nutzer, indem Sie die Medienabfrage prefers-reduced-motion verwenden, um nicht wesentliche Animationen zu vereinfachen oder zu minimieren. Zu den gängigen Strategien gehören das vollständige Deaktivieren von Bewegungen, das Reduzieren der Dauer oder das Ersetzen von Layoutverschiebungen durch subtile Übergänge der Deckkraft.

.accordion-content {
  opacity: 0;
  transition: block-size 0.3s ease, opacity 0.3s ease;
}

.accordion-content.open {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .accordion-content {
    /* 
       EXAMPLE: Replacing disruptive layout animations with a subtle fade-in.
       Setting the block-size instantly and transitioning opacity 
       provides a clear state change without large-scale motion.
    */
    transition: opacity 1.5s ease;
  }

  .accordion-content.open {
    /* Jump the size instantly */
    block-size: auto;
  }
}

Einschränkungen auf intrinsische Größen anwenden

Sie können calc-size() mit jeder mathematischen CSS-Funktion wie min(), max(), clamp() oder round() verwenden, um dafür zu sorgen, dass die intrinsische Größe eines Elements innerhalb der Designgrenzen bleibt.

.dynamic-container {
  /* MANDATORY: Always provide a fallback for browsers that do not support calc-size() */
  inline-size: fit-content;

  /* 
    DO: Establish a dynamic size based on content, while:
    1. Enforcing boundaries using CSS math functions (min, clamp, etc.)
    2. Modifying the intrinsic size with fixed or relative offsets
  */
  inline-size: calc-size(fit-content, min(size + var(--extra-space), var(--max-allowed)));
}

Wichtige Überlegungen

  • Prozentangaben: Prozentangaben innerhalb von <calc-sum> werden anhand der Containergröße und nicht anhand des Keywords size aufgelöst. Beispiel: calc-size(auto, size + 10%) fügt 10 % der Breite des übergeordneten Elements zur auto-Breite des Elements hinzu, was zu unerwarteten Ergebnissen oder Überläufen führen kann.
  • Anforderung für Berechnungen: OBLIGATORISCH: Verwende für einfache Animationen (z.B. 0 bis auto) interpolate-size: allow-keywords anstelle von calc-size(). calc-size() sollte nur verwendet werden, wenn das Layout dynamische mathematische Anpassungen an der intrinsischen Basis erfordert.
  • Hinweis zur Leistung: Das Animieren von Boxmodell-Eigenschaften wie inline-size oder block-size löst eine Neuberechnung des Layouts aus, was rechenintensiv sein kann. Verwenden Sie calc-size()-Animationen hauptsächlich für layoutkritische Elemente, bei denen Alternativen ohne Layout nicht ausreichen.

Fallback-Strategien

calc-size() und interpolate-size sind progressive Verbesserungen. In Browsern, die sie nicht unterstützen, werden die Eigenschaften ignoriert und das Layout bleibt funktionsfähig. Animationen zu intrinsischen Keywords springen jedoch, anstatt einen Übergang zu zeigen. Geben Sie immer ein Standard-Keyword oder eine Standardlänge als Fallback an.

.element {
  /* Fallback for browsers that don't support calc-size() */
  inline-size: fit-content; 
  /* Modern browsers will override the fallback */
  inline-size: calc-size(fit-content, size + 2rem);
}

Fallbacks für Animationen und Übergänge

In Browsern, die calc-size() oder interpolate-size nicht unterstützen, können Übergänge mit intrinsischen Größen-Keywords nicht interpoliert werden.

  • Graduelle Fehlertoleranz: Der Standard-Fallback ist ein „sofortiger Sprung“ zwischen den Zuständen (z.B. von 0 zu auto). Das ist oft akzeptabel, da das Layout funktionsfähig bleibt.
  • Verbesserte Nutzererfahrung: Verwenden Sie @supports, um komplexe Layoutlogik oder zusätzliche Stile anzuwenden, die nur dann sinnvoll sind, wenn flüssige intrinsische Animationen möglich sind.
  • JS-basierte Messungen vermeiden: Sie können zwar JavaScript verwenden, um Elemente zu messen und ihre Abmessungen manuell zu animieren, dies ist jedoch oft unnötig und kann zu Layout-Thrashing führen. Die Verwendung des nativen „Sofortsprungs“ ist der empfohlene Fallback für moderne Webanwendungen.

Bei Animationen wird als Fallback-Variante sofort die endgültige Größe angezeigt. So erkennen Sie die Unterstützung in CSS oder JavaScript:

/* CSS Feature Detection */
@supports (inline-size: calc-size(auto, size + 0px)) {
  .element {
    /* Apply advanced logic only when supported */
  }
}
/* JavaScript Feature Detection */
if (CSS.supports('inline-size', 'calc-size(auto, size + 0px)')) {
  // Apply advanced sizing or animations
}