Aby włączyć płynne przejścia i animacje z słów kluczowych z długością na słowa kluczowe z właściwościami rozmiaru, użyj właściwości interpolate-size
lub funkcji calc-size()
.
Opublikowano: 17 września 2024 r.
Wprowadzenie
Często żądaną funkcją CSS jest możliwość animacji do height: auto
. Nieznaczną odmianą tej prośby jest przejście na usługę width
zamiast height
lub na dowolną inną właściwą wielkość reprezentowaną przez słowa kluczowe takie jak min-content
, max-content
i fit-content
.
Na przykład w tym demo dobrze byłoby, gdyby etykiety płynnie animowały się do naturalnej szerokości po najechaniu na ikony.
Użyty kod 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 */
}
}
Mimo że transition
jest deklarowana jako element przejściowy w przypadku właściwości width
, a width: auto
jest deklarowana w przypadku :hover
, nie następuje płynne przejście. Zamiast tego zmiana jest gwałtowna.
Animacja słów kluczowych z uwzględnieniem rozmiaru bezwzględnego za pomocą interpolate-size
Właściwość CSS interpolate-size
pozwala określić, czy animacje i przejścia z użyciem kluczowych słów dotyczących rozmiaru domyślnego w CSS mają być dozwolone.
Wartość domyślna to numeric-only
, która nie umożliwia interpolacji. Gdy ustawisz tę właściwość na allow-keywords
, akceptujesz interpolację z długości na słowa kluczowe z domyślnym rozmiarem CSS w przypadkach, gdy przeglądarka może animować te słowa kluczowe.
numeric-only
: nie można interpolować wartości<intrinsic-size-keyword>
.allow-keywords
: można interpolować 2 wartości, jeśli jedna z nich jest wartością<intrinsic-size-keyword>
, a druga –<length-percentage>
. […]
Właściwość interpolate-size
jest dziedziczona, więc możesz ją zadeklarować w elementach :root
, aby umożliwić przejście z kluczowych słów z właściwościami rozmiaru bezwzględnego w przypadku całego dokumentu. To zalecane podejście.
/* Opt-in the whole page to interpolate sizes to/from keywords */
:root {
interpolate-size: allow-keywords; /* 👈 */
}
W tym pokazie reguła jest dodawana do kodu. W rezultacie animacje do i z width: auto
działają prawidłowo (w przeglądarkach, które obsługują tę funkcję):
Ogranicz zasięg zgody na udział, zawężając selektor
Jeśli chcesz ograniczyć allow-keywords
tylko do poddrzewa dokumentu, zmień selektor z :root
na element, który chcesz uwzględnić w kierowaniu. Jeśli na przykład <header>
na Twojej stronie jest niezgodny z tym typem przejść, możesz ograniczyć rejestrację do samego elementu <main>
i jego potomków w ten sposób:
main { /* 👈 Scope the opt-in to only <main> and its descendants */
interpolate-size: allow-keywords;
}
Dlaczego domyślnie nie zezwalać na animację i wymiar słów kluczowych?
W przypadku tego mechanizmu często słyszymy, że przeglądarki powinny domyślnie zezwalać na przejścia i animacje z użyciem słów kluczowych z właściwymi rozmiarami do długości domyślnie.
Opcja włączenia tego zachowania została zbadana podczas opracowywania funkcji. Grupa robocza odkryła, że włączenie tej opcji domyślnie nie jest zgodne z wsteczną kompatybilnością, ponieważ wiele arkuszy stylów zakłada, że nie można animować elementów z właściwymi rozmiarami (np. auto
lub min-content
). Szczegółowe informacje znajdziesz w tym komentarzu do odpowiedniego problemu w grupie roboczej CSS.
Dlatego usługa jest opcjonalna. Dzięki właściwości dziedziczenia włączenie w całym dokumencie jest tylko deklaracją interpolate-size: allow-sizes
w :root
, jak opisano wcześniej.
Animacja słów kluczowych z uwzględnieniem rozmiaru bezwzględnego za pomocą calc-size()
Innym sposobem włączenia interpolacji do i z słów kluczowych z własną wielkością jest użycie funkcji calc-size()
. Umożliwia ono bezpieczne i dobrze zdefiniowane wykonywanie obliczeń na podstawie rozmiarów wewnętrznych.
Funkcja ta przyjmuje 2 argumenty w kolejności:
- Obiekt typu calc-size, który może być obiektem typu
<intrinsic-size-keyword>
, ale też zagnieżdżonymcalc-size()
. - Obliczenie wielkości obliczeń, które umożliwia wykonywanie obliczeń na podstawie wielkości obliczeń. Aby odwołać się do podstawy calc-size, użyj słowa kluczowego
size
.
Oto przykłady:
width: calc-size(auto, size); // = the auto width, unaltered
width: calc-size(min-content, size); // = the min-content width, unaltered
Dodanie calc-size()
do oryginalnego dema powoduje, że kod wygląda tak:
nav a {
width: 80px;
overflow-x: clip;
transition: width 0.35s ease;
&:hover,
&:focus-visible {
width: calc-size(max-content, size); /* 👈 */
}
}
Wizualnie efekt jest dokładnie taki sam jak w przypadku użycia interpolate-size
. W tym konkretnym przypadku należy użyć interpolate-size
.
calc-size()
wyróżnia się możliwością wykonywania obliczeń, których nie można wykonać za pomocą 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
Jeśli na przykład chcesz, aby wszystkie akapity na stronie miały rozmiar zbliżony do wielokrotności wartości 50px
, możesz użyć tego kodu:
p {
width: calc-size(fit-content, round(up, size, 50px));
height: calc-size(auto, round(up, size, 50px));
}
Funkcja calc-size()
umożliwia też interpolację między 2 wartościami calc-size()
, gdy obie mają identyczne podstawy rozmiaru obliczeń. Tego też nie można osiągnąć za pomocą usługi interpolate-size
.
#element {
width: min-content; /* 👈 */
transition: width 0.35s ease;
&:hover {
width: calc-size(min-content, size + 10px); /* 👈 */
}
}
Dlaczego nie zezwolić na <intrinsic-size-keyword>
w calc()
?
Pytanie, które często pojawia się w związku z funkcją calc-size()
, brzmi, dlaczego grupa robocza CSS nie dostosowała funkcji calc()
, aby obsługiwała słowa kluczowe z własną wielkością.
Jednym z powodów jest to, że podczas wykonywania obliczeń nie można mieszać ze sobą słów kluczowych z domyślnym rozmiarem. Możesz na przykład chcieć napisać calc(max-content - min-content)
, co wygląda na prawidłowe, ale w rzeczywistości tak nie jest. Funkcja calc-size()
wymusza poprawność, ponieważ w przeciwieństwie do funkcji calc()
jako pierwszy argument przyjmuje tylko jedną wartość funkcji <intrinsic-size-keyword>
.
Innym powodem jest uwzględnianie kontekstu. Niektóre algorytmy układu działają w specyficzny sposób w przypadku określonych ściśle określonych rozmiarów słów kluczowych. Wartość calc-size()
jest zdefiniowana w sposób jednoznaczny, aby reprezentować rozmiar bezwzględny, a nie <length>
. Dzięki temu algorytmy mogą traktować calc-size(<intrinsic-size-keyword>, …)
jako <intrinsic-size-keyword>
, zachowując specjalne zachowanie tego słowa kluczowego.
Jakie podejście zastosować?
W większości przypadków należy zadeklarować interpolate-size: allow-keywords
w elementach :root
. Jest to najprostszy sposób włączenia animacji do i z wyszukiwania z użyciem rozmiaru domyślnego, ponieważ wymaga tylko jednej linii kodu.
/* Opt-in the whole page to animating to/from intrinsic sizing keywords */
:root {
interpolate-size: allow-keywords; /* 👈 */
}
Ten fragment kodu jest przyjemnym ulepszeniem, ponieważ przeglądarki, które go nie obsługują, nie będą używać przejść.
Jeśli potrzebujesz bardziej szczegółowej kontroli nad pewnymi działaniami, np. wykonywaniem obliczeń, lub chcesz użyć zachowania, które jest możliwe tylko dla calc-size()
, możesz użyć calc-size()
.
#specific-element {
width: 50px;
&:hover {
width: calc-size(fit-content, size + 1em); /* 👈 Only calc-size() can do this */
}
}
Jednak użycie w kodzie wartości calc-size()
wymaga uwzględnienia wartości zastępczych dla przeglądarek, które nie obsługują wartości calc-size()
. Możesz na przykład dodać deklaracje dodatkowych rozmiarów lub użyć funkcji wykrywania za pomocą atrybutu @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. */
Więcej wersji demonstracyjnych
Oto kilka demonstracji, które wykorzystują interpolate-size: allow-keywords
.
Powiadomienia
Poniższe demo jest pochodną tego demo @starting-style
. Kod został dostosowany, aby umożliwić dodawanie elementów o różnej wysokości.
Aby to osiągnąć, cała strona korzysta z interpolacji rozmiaru słowa kluczowego, a wartość height
w każdym elemencie .item
jest ustawiona na auto
. W pozostałych miejscach kod jest dokładnie taki sam jak przed utworzeniem gałęzi.
:root {
interpolate-size: allow-keywords; /* 👈 */
}
.item {
height: auto; /* 👈 */
@starting-style {
height: 0px;
}
}
Animowanie elementu <details>
Ten typ interpolacji jest zwykle używany do animowania widżetu wyświetlającego informacje lub ekskluzywnej harmonijki podczas jej otwierania. W HTML używasz do tego elementu <details>
.
Dzięki interpolate-size: allow-keywords
możesz osiągnąć wiele:
@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 */
}
}
}
Jak widać, animacja jest odtwarzana tylko podczas otwierania widżetu. Aby to umożliwić, pracujemy nad pseudonimem ::details-content
, który zostanie dodany do Chrome jeszcze w tym roku (omówimy go w jednym z kolejnych wpisów). Połączenie właściwości interpolate-size: allow-keywords
i ::details-content
umożliwia animację w obie strony: