Gebruik de eigenschap interpolate-size
of de functie calc-size()
om vloeiende overgangen en animaties mogelijk te maken van lengtes naar trefwoorden voor intrinsieke grootte en terug.
Gepubliceerd: 17 september 2024
Invoering
Een veelgevraagde CSS-functie is de mogelijkheid om naar height: auto
. Een kleine variatie op dat verzoek is om de eigenschap width
over te zetten in plaats van de height
, of om over te stappen naar een van de andere intrinsieke grootten die worden weergegeven door trefwoorden zoals min-content
, max-content
en fit-content
.
In de volgende demo zou het bijvoorbeeld leuk zijn als de labels soepel zouden animeren naar hun natuurlijke breedte wanneer ze over de pictogrammen bewegen.
De gebruikte CSS is de volgende:
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 */
}
}
Hoewel een transition
is gedeclareerd om de width
eigenschap over te zetten, en width: auto
is gedeclareerd op :hover
, vindt er geen vloeiende overgang plaats. In plaats daarvan is de verandering abrupt.
Animeer van en naar zoekwoorden met intrinsieke grootte met interpolate-size
De eigenschap CSS interpolate-size
geeft u controle over de vraag of animaties en overgangen van zoekwoorden met intrinsieke CSS-grootte moeten worden toegestaan of niet.
De standaardwaarde is numeric-only
waardoor interpolatie niet mogelijk is. Wanneer u de eigenschap instelt op allow-keywords
, geeft u toestemming voor interpolaties van lengtes naar trefwoorden met CSS-intrinsieke grootte in de gevallen waarin de browser die trefwoorden kan animeren.
-
numeric-only
: Een<intrinsic-size-keyword>
kan niet worden geïnterpoleerd. -
allow-keywords
: Twee waarden kunnen worden geïnterpoleerd als een ervan een<intrinsic-size-keyword>
is en de andere een<length-percentage>
is. […]
Omdat de eigenschap interpolate-size
er een is die overerft, kunt u deze declareren op :root
om de overgang naar en van trefwoorden voor intrinsieke grootte voor het hele document mogelijk te maken. Dit is de aanbevolen aanpak.
/* Opt-in the whole page to interpolate sizes to/from keywords */
:root {
interpolate-size: allow-keywords; /* 👈 */
}
In de volgende demo wordt deze regel aan de code toegevoegd. Hierdoor werken de animaties van en naar width: auto
prima (in browsers met ondersteuning):
Beperk het bereik van de opt-in door de selector te verkleinen
Als u de opt-in allow-keywords
wilt beperken tot slechts een subboom van uw document, past u de selector aan van :root
naar alleen het element dat u wilt targeten. Als de <header>
van uw pagina bijvoorbeeld niet compatibel is met dit soort overgangen, kunt u de aanmelding als volgt beperken tot alleen het <main>
-element en de onderliggende elementen:
main { /* 👈 Scope the opt-in to only <main> and its descendants */
interpolate-size: allow-keywords;
}
Waarom staat u animatie van en naar de grootte van zoekwoorden niet standaard toe?
Een veelgehoorde feedback op dit opt-in-mechanisme is dat browsers standaard overgangen en animaties van intrinsieke grootte van trefwoorden naar lengtes zouden moeten toestaan.
De mogelijkheid om dit gedrag in te schakelen is onderzocht tijdens de ontwikkeling van de functie. De werkgroep ontdekte dat het standaard inschakelen hiervan niet achterwaarts compatibel is, omdat veel stijlbladen ervan uitgaan dat zoekwoorden met intrinsieke grootte (zoals auto
of min-content
) niet kunnen worden geanimeerd. U kunt de details vinden in dit commentaar op het relevante CSS Working Group-probleem .
Daarom is de woning een opt-in. Dankzij de overervingseigenschap is het kiezen voor een heel document slechts een interpolate-size: allow-sizes
declaratie op :root
, zoals eerder beschreven.
Animatie van en naar trefwoorden voor intrinsieke grootte met calc-size()
Een andere manier om interpolatie van en naar trefwoorden met intrinsieke grootte mogelijk te maken, is door de functie calc-size()
te gebruiken. Het maakt het mogelijk wiskunde op een veilige, goed gedefinieerde manier uit te voeren op intrinsieke groottes.
De functie accepteert twee argumenten, in de volgende volgorde:
- Een calc-size basis , die een
<intrinsic-size-keyword>
kan zijn, maar ook een genestcalc-size()
. - Een calc-size-berekening , waarmee u berekeningen kunt uitvoeren op basis van de calc-size-basis. Gebruik het sleutelwoord
size
om naar de basis van de calc-size te verwijzen.
Hier zijn enkele voorbeelden:
width: calc-size(auto, size); // = the auto width, unaltered
width: calc-size(min-content, size); // = the min-content width, unaltered
Door calc-size()
aan de originele demo toe te voegen, ziet de code er als volgt uit:
nav a {
width: 80px;
overflow-x: clip;
transition: width 0.35s ease;
&:hover,
&:focus-visible {
width: calc-size(max-content, size); /* 👈 */
}
}
Visueel is het resultaat precies hetzelfde als bij gebruik van interpolate-size
. In dit specifieke geval moet u dus interpolate-size
gebruiken.
Waar calc-size()
wel in uitblinkt, is de mogelijkheid om berekeningen uit te voeren, iets dat niet gedaan kan worden met interpolate-size
:
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
Als u bijvoorbeeld wilt dat alle alinea's op een pagina de grootte krijgen van het dichtstbijzijnde veelvoud van 50px
, kunt u het volgende gebruiken:
p {
width: calc-size(fit-content, round(up, size, 50px));
height: calc-size(auto, round(up, size, 50px));
}
Wat u met calc-size()
ook kunt doen, is interpoleren tussen twee calc-size()
-bestanden wanneer beide calc-size-bases identiek zijn. Ook dit is iets dat niet kan worden bereikt met interpolate-size
.
#element {
width: min-content; /* 👈 */
transition: width 0.35s ease;
&:hover {
width: calc-size(min-content, size + 10px); /* 👈 */
}
}
Waarom staat <intrinsic-size-keyword>
niet toe in calc()
?
Een vraag die vaak opduikt bij calc-size()
is waarom de CSS-werkgroep de functie calc()
niet heeft aangepast om zoekwoorden met intrinsieke grootte te ondersteunen.
Een van de redenen hiervoor is dat u bij het uitvoeren van berekeningen geen trefwoorden voor intrinsieke grootte mag combineren. U zou bijvoorbeeld in de verleiding kunnen komen om calc(max-content - min-content)
te schrijven, wat er geldig uitziet, maar dat in werkelijkheid niet is. calc-size()
dwingt correctheid af omdat het, in tegenstelling tot calc()
, slechts één enkel <intrinsic-size-keyword>
als eerste argument accepteert.
Een andere reden is contextbewustzijn. Sommige lay-outalgoritmen gedragen zich speciaal voor specifieke trefwoorden met intrinsieke grootte. calc-size()
is expliciet gedefinieerd om een intrinsieke grootte weer te geven, niet een <length>
. Dankzij dit kunnen deze algoritmen calc-size(<intrinsic-size-keyword>, …)
behandelen als het <intrinsic-size-keyword>
, waarbij het speciale gedrag voor dat trefwoord behouden blijft.
Welke aanpak gebruiken?
In de meeste gevallen declareert u interpolate-size: allow-keywords
op :root
. Het is de gemakkelijkste manier om animatie van en naar zoekwoorden met intrinsieke grootte mogelijk te maken, omdat het in wezen een oneliner is.
/* Opt-in the whole page to animating to/from intrinsic sizing keywords */
:root {
interpolate-size: allow-keywords; /* 👈 */
}
Dit stukje code is een mooie progressieve verbetering, omdat browsers die dit niet ondersteunen terugvallen op het gebruik van geen overgangen.
Als u meer gedetailleerde controle over zaken nodig heeft (zoals het uitvoeren van berekeningen) of als u een gedrag wilt gebruiken dat alleen calc-size()
kan uitvoeren, kunt u uw toevlucht nemen tot het gebruik van calc-size()
.
#specific-element {
width: 50px;
&:hover {
width: calc-size(fit-content, size + 1em); /* 👈 Only calc-size() can do this */
}
}
Als u calc-size()
in uw code gebruikt, moet u echter fallbacks opnemen voor browsers die calc-size()
niet ondersteunen. U kunt bijvoorbeeld extra groottedeclaraties toevoegen of terugvallen op functiedetectie met @supports
.
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. */
Meer demo's
Hier zijn nog enkele demo's die interpolate-size: allow-keywords
in hun voordeel gebruiken.
Meldingen
De volgende demo is een afsplitsing van deze @starting-style
demo . De code is aangepast zodat artikelen met verschillende hoogtes kunnen worden toegevoegd.
Om dit te bereiken kiest de hele pagina voor de grootte van trefwoordinterpolatie en wordt de height
van elk .item
element ingesteld op auto
. Anders is de code precies hetzelfde als vóór het forken.
:root {
interpolate-size: allow-keywords; /* 👈 */
}
.item {
height: auto; /* 👈 */
@starting-style {
height: 0px;
}
}
Animeer het <details>
-element
Een typisch gebruiksscenario waarbij u dit type interpolatie wilt gebruiken, is het animeren van een openbaarmakingswidget of een exclusieve accordeon terwijl deze wordt geopend. In HTML gebruik je hiervoor het <details>
element.
Met interpolate-size: allow-keywords
kun je behoorlijk ver komen:
@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 */
}
}
}
Zoals u echter kunt zien, wordt de animatie alleen uitgevoerd wanneer de openbaarmakingswidget wordt geopend. Om hieraan tegemoet te komen, werkt Chrome aan de ::details-content
pseudo die later dit jaar in Chrome zal verschijnen (en die in een toekomstige post zal worden behandeld). Door interpolate-size: allow-keywords
en ::details-content
te combineren, kun je een animatie in beide richtingen krijgen: