Mit der Eigenschaft interpolate-size
oder der Funktion calc-size()
können Sie fließende Übergänge und Animationen von Längen zu Keywords für die intrinsische Größenanpassung und zurück ermöglichen.
Veröffentlicht: 17. September 2024
Einführung
Eine häufig angefragte CSS-Funktion ist die Möglichkeit, height: auto
zu animieren. Eine kleine Abwandlung dieser Anfrage besteht darin, die Property width
anstelle von height
zu verwenden oder zu einer der anderen intrinsischen Größen zu wechseln, die durch Keywords wie min-content
, max-content
und fit-content
dargestellt werden.
In der folgenden Demo wäre es beispielsweise schön, wenn die Labels beim Bewegen des Mauszeigers auf die Symbole reibungslos auf ihre natürliche Breite animiert würden.
Hier ist das verwendete CSS:
nav a {
width: 80px;
overflow-x: clip;
transition: width 0.35s ease; /* 👈 Transition the width */
&:hover,
&:focus-visible {
width: max-content; /* 👈 Doesn't work with transitions */
}
}
Obwohl eine transition
für die Umstellung der width
-Eigenschaft deklariert und width: auto
auf :hover
deklariert ist, erfolgt keine reibungslose Umstellung. Stattdessen ist die Veränderung abrupt.
Mit interpolate-size
von und zu Keywords für die intrinsische Größenanpassung animieren
Mit der CSS-Eigenschaft interpolate-size
können Sie festlegen, ob Animationen und Übergänge von CSS-internen Größen-Keywords zulässig sein sollen.
Der Standardwert ist numeric-only
, wodurch keine Interpolation aktiviert wird. Wenn Sie die Eigenschaft auf allow-keywords
festlegen, aktivieren Sie Interpolationen von Längen zu CSS-internen Größen-Keywords, wenn der Browser diese Keywords animieren kann.
Gemäß Spezifikation:
numeric-only
: Ein<intrinsic-size-keyword>
kann nicht interpoliert werden.allow-keywords
: Zwei Werte können interpoliert werden, wenn einer von ihnen ein<intrinsic-size-keyword>
und der andere ein<length-percentage>
ist. […]
Da die interpolate-size
-Eigenschaft übernommen wird, können Sie sie für :root
deklarieren, um den Übergang zu und von Keywords für die intrinsische Größenanpassung für das gesamte Dokument zu ermöglichen. Dies ist der empfohlene Ansatz.
/* Opt-in the whole page to interpolate sizes to/from keywords */
:root {
interpolate-size: allow-keywords; /* 👈 */
}
In der folgenden Demo wird diese Regel dem Code hinzugefügt. Daher funktionieren die Animationen zu und von width: auto
in Browsern mit Unterstützung einwandfrei:
Reichweite der Einwilligung einschränken, indem Sie die Auswahl eingrenzen
Wenn Sie die Einwilligung für allow-keywords
auf einen untergeordneten Knoten Ihres Dokuments beschränken möchten, passen Sie die Auswahl von :root
auf das Element an, auf das Sie das Targeting vornehmen möchten. Wenn das <header>
-Element Ihrer Seite beispielsweise nicht mit diesen Übergängen kompatibel ist, können Sie die Aktivierung auf das <main>
-Element und seine untergeordneten Elemente beschränken. Gehen Sie dazu so vor:
main { /* 👈 Scope the opt-in to only <main> and its descendants */
interpolate-size: allow-keywords;
}
Warum wird die Animation von und zu Größen-Keywords nicht standardmäßig zugelassen?
Häufig wird uns gesagt, dass Browser standardmäßig Übergänge und Animationen von Keywords für die benutzerdefinierte Textgröße zu Längen zulassen sollten.
Die Option zum Aktivieren dieses Verhaltens wurde während der Entwicklung der Funktion untersucht. Die Arbeitsgruppe hat festgestellt, dass die Standardaktivierung nicht abwärtskompatibel ist, da in vielen Stylesheets davon ausgegangen wird, dass Keywords für die intrinsische Größenänderung (z. B. auto
oder min-content
) nicht animiert werden können. Weitere Informationen finden Sie in diesem Kommentar zum entsprechenden Problem der CSS-Arbeitsgruppe.
Daher ist die Property optional. Dank der Vererbungseigenschaft ist die Aktivierung eines gesamten Dokuments lediglich eine interpolate-size: allow-sizes
-Erklärung für :root
, wie bereits beschrieben.
Mit calc-size()
von und zu Keywords für die intrinsische Größenanpassung animieren
Eine weitere Möglichkeit, die Interpolation zwischen und von Keywords für die intrinsische Größenanpassung zu aktivieren, ist die Verwendung der calc-size()
-Funktion. So können mathematische Berechnungen auf intrinsische Größen auf sichere und klar definierte Weise angewendet werden.
Die Funktion akzeptiert zwei Argumente:
- Eine calc-size-Basis, die eine
<intrinsic-size-keyword>
oder auch eine verschachteltecalc-size()
sein kann. - Eine Berechnung vom Typ „calc-size“, mit der Sie Berechnungen anhand der Basis „calc-size“ durchführen können. Verwenden Sie das Schlüsselwort
size
, um auf die Basis für die Berechnung der Größe zu verweisen.
Hier einige Beispiele:
width: calc-size(auto, size); // = the auto width, unaltered
width: calc-size(min-content, size); // = the min-content width, unaltered
Wenn wir der ursprünglichen Demo calc-size()
hinzufügen, sieht der Code so aus:
nav a {
width: 80px;
overflow-x: clip;
transition: width 0.35s ease;
&:hover,
&:focus-visible {
width: calc-size(max-content, size); /* 👈 */
}
}
Visuell ist das Ergebnis genau das gleiche wie bei der Verwendung von interpolate-size
. In diesem Fall sollten Sie also interpolate-size
verwenden.
calc-size()
eignet sich hervorragend für Berechnungen, was mit interpolate-size
nicht möglich ist:
width: calc-size(auto, size - 10px); // = The auto width minus 10 pixels
width: calc-size(min-content, size + 1rem); // = The min-content width plus 1rem
width: calc-size(max-content, size * .5); // = Half the max-content width
Wenn Sie beispielsweise möchten, dass alle Absätze auf einer Seite auf das nächste Vielfache von 50px
skaliert werden, können Sie Folgendes verwenden:
p {
width: calc-size(fit-content, round(up, size, 50px));
height: calc-size(auto, round(up, size, 50px));
}
Mit calc-size()
können Sie auch zwischen zwei calc-size()
s interpolieren, wenn beide Basen der berechneten Größe identisch sind. Auch das ist mit interpolate-size
nicht möglich.
#element {
width: min-content; /* 👈 */
transition: width 0.35s ease;
&:hover {
width: calc-size(min-content, size + 10px); /* 👈 */
}
}
Warum ist <intrinsic-size-keyword>
in calc()
nicht zulässig?
Eine häufig gestellte Frage zu calc-size()
ist, warum die CSS Working Group die calc()
-Funktion nicht so angepasst hat, dass sie Keywords zur benutzerdefinierten Größenänderung unterstützt.
Ein Grund dafür ist, dass Sie bei Berechnungen keine Keywords zur benutzerdefinierten Größenanpassung kombinieren dürfen. Sie könnten beispielsweise versucht sein, calc(max-content - min-content)
zu schreiben, was zwar gültig aussieht, in Wirklichkeit aber nicht ist. calc-size()
erzwingt die Korrektheit, da sie im Gegensatz zu calc()
nur eine einzelne <intrinsic-size-keyword>
als erstes Argument akzeptiert.
Ein weiterer Grund ist die Kontextsensitivität. Einige Layoutalgorithmen haben ein spezielles Verhalten für bestimmte Keywords zur benutzerdefinierten Größenanpassung. calc-size()
ist explizit als intrinsische Größe definiert, nicht als <length>
. So können diese Algorithmen calc-size(<intrinsic-size-keyword>, …)
als <intrinsic-size-keyword>
behandeln und das spezielle Verhalten für dieses Keyword beibehalten.
Welchen Ansatz verwenden?
In den meisten Fällen sollten Sie interpolate-size: allow-keywords
auf :root
deklarieren. Das ist die einfachste Möglichkeit, die Animation von und zu Keywords für die intrinsische Größenanpassung zu aktivieren, da es sich im Grunde um einen Einzeiler handelt.
/* Opt-in the whole page to animating to/from intrinsic sizing keywords */
:root {
interpolate-size: allow-keywords; /* 👈 */
}
Dieser Code ist eine gute progressive Verbesserung, da Browser, die ihn nicht unterstützen, keine Übergänge verwenden.
Wenn Sie eine detailliertere Kontrolle über bestimmte Dinge benötigen, z. B. Berechnungen, oder ein Verhalten verwenden möchten, das nur calc-size()
bietet, können Sie calc-size()
verwenden.
#specific-element {
width: 50px;
&:hover {
width: calc-size(fit-content, size + 1em); /* 👈 Only calc-size() can do this */
}
}
Wenn Sie calc-size()
in Ihrem Code verwenden, müssen Sie jedoch Fallbacks für Browser einschließen, die calc-size()
nicht unterstützen. Sie können beispielsweise zusätzliche Größendeklarationen hinzufügen oder mit @supports
auf die Feature-Erkennung zurückgreifen.
width: fit-content;
width: calc-size(fit-content, size + 1em);
/* 👆 Browsers with no calc-size() support will ignore this second declaration,
and therefore fall back to the one on the line before it. */
Weitere Demos
Hier sind einige weitere Demos, in denen interpolate-size: allow-keywords
genutzt wird.
Benachrichtigungen
Die folgende Demo ist eine Fork von dieser @starting-style
Demo. Der Code wurde angepasst, damit Elemente mit unterschiedlichen Höhen hinzugefügt werden können.
Dazu wird die Keyword-Interpolation für die gesamte Seite aktiviert und die height
in jedem .item
-Element auf auto
festgelegt. Andernfalls ist der Code genau derselbe wie vor der Fork.
:root {
interpolate-size: allow-keywords; /* 👈 */
}
.item {
height: auto; /* 👈 */
@starting-style {
height: 0px;
}
}
<details>
-Element animieren
Ein typischer Anwendungsfall für diese Art der Interpolation ist die Animation eines Offenlegungs-Widgets oder eines ausschließlichen Akkordeons beim Öffnen. In HTML verwenden Sie dazu das Element <details>
.
Mit interpolate-size: allow-keywords
können Sie ziemlich weit kommen:
@supports (interpolate-size: allow-keywords) {
:root {
interpolate-size: allow-keywords;
}
details {
transition: height 0.5s ease;
height: 2.5rem;
&[open] {
height: auto;
overflow: clip; /* Clip off contents while animating */
}
}
}
Wie Sie sehen, wird die Animation jedoch nur ausgeführt, wenn das Widget geöffnet wird. Aus diesem Grund wird in Chrome an dem Pseudonym ::details-content
gearbeitet, das später in diesem Jahr in Chrome eingeführt wird. Weitere Informationen dazu folgen in einem weiteren Beitrag. Wenn Sie interpolate-size: allow-keywords
und ::details-content
kombinieren, können Sie eine Animation in beide Richtungen erhalten: