calc-size()
Experimentell: Dies ist eine experimentelle Technologie
Überprüfen Sie die Browser-Kompatibilitätstabelle sorgfältig, bevor Sie diese produktiv verwenden.
Die calc-size()
CSS-Funktion ermöglicht die Durchführung von Berechnungen bei Intrinsische Größe-Werten wie auto
, fit-content
und max-content
; dies wird von der regulären calc()
-Funktion nicht unterstützt.
Die Rückgabewerte von calc-size()
können auch interpoliert werden, was ermöglicht, dass Schlüsselwortwerte für die Größe in Animationen und Übergängen verwendet werden. Tatsächlich wird beim Einfügen von calc-size()
in einen Eigenschaftswert automatisch interpolate-size: allow-keywords
auf die Auswahl angewendet.
Beachten Sie jedoch, dass interpolate-size
vererbt wird. Daher ermöglicht das Anwenden auf ein Element die Interpolation von Schlüsselwörtern für intrinsische Größen bei jeder Eigenschaft, die auf dieses Element und seine Kinder angewendet wird. Daher ist interpolate-size
die bevorzugte Lösung, um Animationen von intrinsischen Größen zu ermöglichen. Sie sollten calc-size()
nur verwenden, um Animationen von intrinsischen Größen zu ermöglichen, wenn auch Berechnungen erforderlich sind.
Syntax
/* Pass a value through calc-size() */
calc-size(auto, size)
calc-size(fit-content, size)
/* Perform a calculation */
calc-size(min-content, size + 100px)
calc-size(fit-content, size / 2)
/* Calculation including a function */
calc-size(auto, round(up, size, 50px))
Parameter
Die Syntax der Funktion calc-size()
ist wie folgt:
calc-size(<calc-size-basis>, <calc-sum>)
Die Parameter sind:
<calc-size-basis>
-
Der Wert (meistens eine intrinsische Größe), auf den Sie eine Berechnung durchführen möchten.
<calc-sum>
-
Ein Ausdruck, der die Berechnung definiert, die auf
<calc-size-basis>
durchgeführt werden soll.
Rückgabewert
Gibt einen Wert zurück, der gleich dem durch den Ausdruck <calc-sum>
modifizierten <calc-size-basis>
ist. Da der <calc-size-basis>
ein Wert für intrinsische Größen ist, ist der Rückgabewert ein modifizierter Wert für intrinsische Größen, der sich wie der in die Funktion eingegebene intrinsische Größenwert verhält.
Beschreibung
Bestimmte Browser-Layout-Algorithmen haben spezielle Verhaltensweisen für Schlüsselwörter von intrinsischen Größen. Die Funktion calc-size()
ist explizit definiert, um eine intrinsische Größe darzustellen und nicht eine <length-percentage>
, wodurch die Korrektheit erzwungen wird. calc-size()
ermöglicht es, Berechnungen bei intrinsischen Größenwerten auf eine sichere, gut definierte Weise durchzuführen.
Gültige Werte für das erste Argument (<calc-size-basis>
)
Das erste Argument von calc-size()
kann einer der folgenden intrinsischen Werte sein:
auto
min-content
max-content
fit-content
content
(für Container, die mitflex-basis
dimensioniert werden).
Es gibt auch einige spezielle Werte, die dieses Argument haben kann:
-
Ein verschachtelter
calc-size()
-Wert. Dies ist nicht etwas, das Sie sehr häufig tun würden, aber es ist verfügbar, um sicherzustellen, dass das Verwenden einer CSS-Variable als<calc-size-basis>
immer funktioniert, vorausgesetzt, die Variable ist ein gültiger Wert für die Eigenschaft, auf diecalc-size()
eingestellt wird. Zum Beispiel funktioniert dies:csssection { height: calc-size(calc-size(max-content, size), size + 2rem); }
Ebenso funktioniert dies:
css:root { --intrinsic-size: calc-size(max-content, size); } section { height: calc-size(var(--intrinsic-size), size + 2rem); }
-
Ein weiteres
<calc-sum>
, mit den gleichen Einschränkungen wie das für das zweite Argument angegebene<calc-sum>
, außer dass das Schlüsselwortsize
nicht enthalten sein kann. Wahrscheinlich werden Sie dies nicht tun, da Sie keine Berechnung mehr bei einem intrinsischen Größenwert durchführen, aber wenn der Wert einer benutzerdefinierten Eigenschaft ein<calc-sum>
ist, funktioniert die Funktion dennoch. Zum Beispiel funktioniert dies direkt oder wenn Sie eine benutzerdefinierte Eigenschaft mit einem Wert von300px + 2rem
verwenden:csssection { height: calc-size(300px + 2rem, size / 2); }
-
Das Schlüsselwort
any
, das eine nicht spezifizierte definitive Größe darstellt. In diesem Fall kann das Schlüsselwortsize
nicht im zweiten Argument enthalten sein, undcalc-size()
gibt das Ergebnis der Berechnung des zweiten Arguments zurück. Zum Beispiel:csssection { height: calc-size(any, 300px * 1.5); /* Returns 450px */ }
Das Mischen verschiedener intrinsischer Größen in der gleichen Berechnung funktioniert nicht. Zum Beispiel ergibt max-content - min-content
keinen Sinn. calc-size()
erlaubt nur einen einzigen intrinsischen Größenwert in jeder Berechnung, um dieses Problem zu vermeiden.
Gültige Werte für das zweite Argument (<calc-sum>
)
Das zweite Argument calc-size()
ist ein <calc-sum>
-Ausdruck.
In diesem Ausdruck:
- Das Schlüsselwort
size
repräsentiert den<calc-size-basis>
, der als erstes Argument angegeben wurde. - Operanden können
size
enthalten und alle Werttypen, die im Kontext Sinn machen. - Die Operatoren
+
,-
,*
und/
können enthalten sein. - Andere mathematische Funktionen können enthalten sein wie
round()
,max()
, oder sogar ein verschachteltescalc-size()
. - Der Gesamtausdruck muss
<length-percentage>
entsprechen und zu einem<length>
auflösen.
Aktivieren der Animation von intrinsischen Größenwerten
calc-size()
-Rückgabewerte können interpoliert werden, was Animationen zwischen einem <length-percentage>
-Wert und einem calc-size()
-Rückgabewert für intrinsische Größen ermöglicht.
Hinweis: Sie sollten vermeiden, Boxenmodell-Eigenschaften zu animieren, wenn möglich, um Layout-Ereignisse zu reduzieren und die daraus resultierenden Auswirkungen auf die Leistung zu mildern (siehe Critical rendering path > Layout).
Zum Beispiel könnten Sie einen Übergang verwenden, um die width
eines Containers zwischen 0
und auto
folgendermaßen zu animieren:
section {
width: 0;
transition: width ease 1s;
}
section:hover,
section:focus {
width: calc-size(auto, size);
}
Im obigen Fall berechnen wir nichts — wir setzen auto
in calc-size()
und geben es unverändert zurück. Die Eigenschaft interpolate-size
macht Animationen wie die oben genannten in den meisten Fällen einfacher zu implementieren, insbesondere wenn mehrere Animationen zu berücksichtigen sind. Sie ist geerbt, und daher muss sie nur einmal auf einer Vorfahreneigenschaft deklariert werden, was bedeutet, dass wir ohne die Verwendung von calc-size()
zwischen 0
und auto
übergehen könnten.
Die Funktion calc-size()
sollte nur verwendet werden, um Animationen von intrinsischen Größen zu ermöglichen, wenn auch Berechnungen erforderlich sind. Zum Beispiel animieren wir im folgenden Fall die Breite und führen eine Berechnung beim Endzustand der intrinsischen Größe durch:
section {
width: 0;
transition: width ease 1s;
}
section:hover,
section:focus {
width: calc-size(auto, size + 2rem);
}
Ein Fall, in dem calc-size()
nützlich ist, ist, wenn Sie zwischen einer intrinsischen Größe und einer modifizierten Version derselben intrinsischen Größe animieren möchten. Dies ist mit interpolate-size
und calc()
nicht möglich. Zum Beispiel animiert die folgende @keyframes
-Definition die width
eines Containers zwischen fit-content
und 70% von fit-content
.
@keyframes narrower {
from {
width: fit-content;
}
to {
width: calc-size(fit-content, size * 0.7);
}
}
Hinweis: Beachten Sie, dass calc-size()
nicht das Animieren zwischen zwei verschiedenen intrinsischen Größenwerten ermöglicht.
Formaler Syntax
<calc-size()> =
calc-size( <calc-size-basis> , <calc-sum> )
<calc-size-basis> =
<intrinsic-size-keyword> |
<calc-size()> |
any |
<calc-sum>
<calc-sum> =
<calc-product> [ [ '+' | '-' ] <calc-product> ]*
<calc-size()> =
calc-size( <calc-size-basis> , <calc-sum> )
<calc-product> =
<calc-value> [ [ '*' | '/' ] <calc-value> ]*
<calc-value> =
<number> |
<dimension> |
<percentage> |
<calc-keyword> |
( <calc-sum> )
<calc-keyword> =
e |
pi |
infinity |
-infinity |
NaN
Beispiele
Grundlegende calc-size
-Verwendung
Dieses Beispiel zeigt die grundlegende Dimensionierung eines Containers mit calc-size()
.
HTML
Das HTML enthält ein einzelnes <section>
-Element, das einige untergeordnete Inhalte enthält.
<section>
<h2>Favorite quote</h2>
<p>
Fashion is something so ugly it has to be changed every fifteen minutes.
</p>
</section>
CSS
Im CSS verwenden wir Flexbox, um die untergeordneten Elemente im <section>
zu zentrieren, und setzen die width
und height
des <section>
auf calc-size()
-Funktionen. Die width
wird auf fit-content
plus 6rem
gesetzt. Die height
wird auf auto
multipliziert mit zwei gesetzt.
section {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: calc-size(fit-content, size + 6rem);
height: calc-size(auto, size * 2);
}
Der Rest des CSS wurde der Kürze halber ausgeblendet.
Ergebnis
Wir haben etwas horizontalen und vertikalen Raum für die zentrierte Darstellung des Textes geschaffen, ohne Polsterung zu verwenden.
Grundlegende calc-size
-Animationen
Dieses Beispiel zeigt, wie calc-size()
verwendet wird, um zwischen einer bestimmten Größe und einer intrinsischen Größe zu animieren. Das Demo zeigt ein Charakterabzeichen/„Namensschild“, das durch Hovern oder Fokussieren informationen über den Charakter offenbart. Das Offenlegen wird durch einen height
-Übergang zwischen einer festen Länge und max-content
behandelt.
HTML
Das HTML enthält ein einzelnes <section>
-Element mit tabindex="0"
, damit es den Tastaturfokus erhalten kann. Das <section>
enthält <header>
- und <main>
-Elemente, jeweils mit ihren eigenen untergeordneten Inhalten.
<section tabindex="0">
<header>
<h2>Chris Mills</h2>
</header>
<main>
<p>Chris is the silent phantom of MDN.</p>
<ul>
<li><strong>Height</strong>: 3.03m</li>
<li><strong>Weight</strong>: 160kg</li>
<li><strong>Tech Fu</strong>: 7</li>
<li><strong>Bad Jokes</strong>: 9</li>
</ul>
</main>
</section>
CSS
Im CSS setzen wir die height
des <section>
auf 2.5rem
und overflow
auf hidden
, sodass standardmäßig nur der <header>
angezeigt wird, dann geben wir einen Übergang
an, der die height
des <section>
während Zustandsänderungen über 1 Sekunde animiert. Schließlich setzen wir die height
des <section>
auf einen calc-size()
-Funktionsaufruf bei :hover
und :focus
. Der Rückgabewert der Funktion entspricht max-content
+ 2rem
.
section {
height: 2.5rem;
overflow: hidden;
transition: height ease 1s;
}
section:hover,
section:focus {
height: calc-size(max-content, size + 2rem);
}
Der Rest des CSS wurde der Kürze halber ausgeblendet.
Ergebnis
Versuchen Sie, über das <section>
zu fahren oder es über die Tastatur zu fokussieren — es wird animieren, um seine volle Höhe + 2rem zu erreichen und den gesamten Inhalt mit 2rems zusätzlichem Raum am Boden zu zeigen.
Anpassung der Lesebreite basierend auf fit-content
Dieses Beispiel zeigt einen Container mit Text darin und einen Button, der geklickt werden kann, um die Containerbreite je nach Lesepräferenz schmaler oder breiter zu machen.
HTML
Das HTML enthält ein einzelnes <section>
-Element mit untergeordneten Textinhalten sowie einen <button>
, um die <section>
-Breite zu ändern.
<section class="easy-reader">
<h2>Easy reader</h2>
<p>
Eius velit aperiam ipsa. Deleniti eum excepturi ut magni maxime maxime
beatae. Dicta aperiam est laudantium ut illum facere qui officiis. Sunt
deleniti quam id. Quis sunt voluptatem praesentium minima dolorum autem
consequatur velit.
</p>
<p>
Vitae ab incidunt velit aspernatur deleniti distinctio rerum. Et natus sed
et quos mollitia quia quod. Quae officia ex ea. Ducimus ut voluptatem et et
debitis. Quidem provident laboriosam exercitationem similique deleniti.
Temporibus vel veniam mollitia magni unde a nostrum.
</p>
<button class="width-adjust">Narrower</button>
</section>
CSS
Im CSS setzen wir die width
des <section>
auf einen Standardwert von fit-content
. Wir definieren dann zwei Sätze von @keyframes
, narrower
, das von fit-content
auf 70% von fit-content
animiert wird (berechnet mit calc-size()
), und wider
, das dieselben Werte in umgekehrter Richtung animiert. Schließlich fügen wir diese Animationen zwei Klassen zu — .narrower
und .wider
. Jede Animation ist so definiert, dass sie eine Sekunde dauert und den endgültigen Zustand einmal angewendet hält, sobald sie beendet ist.
section {
width: fit-content;
}
@keyframes narrower {
from {
width: fit-content;
}
to {
width: calc-size(fit-content, size * 0.7);
}
}
@keyframes wider {
from {
width: calc-size(fit-content, size * 0.7);
}
to {
width: fit-content;
}
}
.narrower {
animation: narrower 1s ease forwards;
}
.wider {
animation: wider 1s ease forwards;
}
Der Rest des CSS wurde der Kürze halber ausgeblendet.
JavaScript
Das JavaScript bietet einen Schmaler/Breiter-Umschalter, der die relevante Klasse auf die <section>
anwendet, wenn der Button angeklickt wird:
const widthAdjustBtn = document.querySelector(".width-adjust");
const easyReader = document.querySelector(".easy-reader");
widthAdjustBtn.addEventListener("click", () => {
if (easyReader.classList.length === 1) {
easyReader.classList.add("narrower");
widthAdjustBtn.textContent = "Wider";
} else if (easyReader.classList.contains("wider")) {
easyReader.classList.replace("wider", "narrower");
widthAdjustBtn.textContent = "Wider";
} else if (easyReader.classList.contains("narrower")) {
easyReader.classList.replace("narrower", "wider");
widthAdjustBtn.textContent = "Narrower";
}
});
Ergebnis
Versuchen Sie, den <button>
einige Male zu klicken, um die <section>
zwischen der weiten und schmalen Lesebreite zu ändern, indem die width
auf Basis des fit-content
-Werts manipuliert wird.
Verwendung einer Funktion innerhalb der calc-size()
-Funktion
Wie bereits erwähnt, ist es möglich, eine andere Funktion innerhalb von calc-size()
zu verwenden. Dieses Beispiel setzt field-sizing: content
auf <input>
-Elemente, um sie so breit wie den eingegebenen Inhalt zu machen. Dann wird eine max()
-Funktion innerhalb von calc-size()
verwendet, um sicherzustellen, dass die <input>
s mindestens eine Mindestgröße haben und erst wachsen, wenn der eingegebene Text größer als diese Größe wird — indem sie auf fit-content
plus 20px
gesetzt werden.
HTML
Das HTML enthält ein <form>
-Element mit drei textuellen <input>
-Typen. Jedes <input>
hat ein <label>
, um das Formular zugänglich zu machen, und ein maxlength
, um zu verhindern, dass eingegebene Werte so lang werden, dass das Formularlayout gebrochen wird.
<form>
<div>
<label for="name">Name:</label>
<input type="text" id="name" name="name" maxlength="48" />
</div>
<div>
<label for="email">Email:</label>
<input type="email" id="email" name="email" maxlength="48" />
</div>
<div>
<label for="address">Address:</label>
<input type="text" id="address" name="address" maxlength="60" />
</div>
</form>
CSS
Im CSS setzen wir die width
der <label>
-Elemente auf 100px
. Wir setzen field-sizing: content
auf die <input>
-Elemente, um sie so breit wie den eingegebenen Inhalt zu machen — standardmäßig hätten sie keine Breite, weil nichts in sie eingegeben würde. Um dies auszugleichen, setzen wir ihre width
-Werte auf calc-size(fit-content, max(100px, size + 20px))
. Das bedeutet, dass sie mindestens 100px
breit sind, selbst wenn kein Wert eingegeben wird. Wenn ein eingegebener Wert breiter als 100px
wird, ändert sich ihre width
zu fit-content
plus 20px
, was bedeutet, dass sie mit der Inhaltsgröße wachsen, sich aber einen 20px
-Abstand auf der rechten Seite behalten.
label {
width: 100px;
}
input {
field-sizing: content;
width: calc-size(fit-content, max(100px, size + 20px));
}
Der Rest des CSS wurde der Kürze halber ausgeblendet.
Ergebnis
Versuchen Sie, ein bisschen Text in die Formulareingaben einzugeben und sehen Sie, wie sie wachsen, wenn die Werte anfangen, so breit wie die minimale Breite zu werden, die durch die max()
-Funktion erzwungen wird.
Spezifikationen
Specification |
---|
CSS Values and Units Module Level 5 # calc-size |
Browser-Kompatibilität
BCD tables only load in the browser
Siehe auch
interpolate-size
calc()
round()
- Animate to height: auto; (and other intrinsic sizing keywords) in CSS auf developer.chrome.com (2024)