Geschrieben von Rahul Chhodde✏️
Native Dialog- und Popover-Elemente haben in der modernen Frontend-Webentwicklung ihre eigenen, klar definierten Rollen. Es ist bekannt, dass Dialogelemente mit dem Benutzer kommunizieren und dessen Eingaben sammeln, während Popovers eher dazu geeignet sind, dem Benutzer sekundäre Informationen mit niedriger Priorität bereitzustellen.
In einem früheren Artikel über Dialoge vs. Popovers haben wir besprochen, dass beide Elemente über eigene JavaScript-APIs verfügen, die es uns ermöglichen, das Beste aus diesen beiden Elementen herauszuholen.
Wenn es darum geht, diesen Elementen Animationen und Interaktivität hinzuzufügen, werden JavaScript-Bibliotheken gegenüber CSS bevorzugt. Solche Elemente erfordern normalerweise nur minimale Animationen, und die Verwendung riesiger Animationsbibliotheken, nur um ein paar einfache Effekte hinzuzufügen, kann die unnötige Belastung Ihrer App erheblich erhöhen.
Um dem abzuhelfen, hilft Ihnen dieser Artikel dabei, Animationseffekte mithilfe reiner CSS-Techniken in Dialoge und Popovers zu programmieren. Wir behandeln CSS-Keyframes und die neu eingeführte @starting-style at-rule, die beide zum Erstellen subtiler Animationen mit verbesserter Leistung verwendet werden können.
Dialoge und Popovers sind Overlay-Elemente, was bedeutet, dass sie auf der obersten vom Browser gerenderten Ebene ausgeführt werden. Wie bereits erwähnt, sind diese Elemente auch auf dedizierte APIs angewiesen, um ihre Anzeige und/oder Modalität zu verwalten.
Sehen wir uns die Herausforderungen an, denen wir bei der Animation von Dialogen und Popovers mit herkömmlichen CSS-Übergangstechniken gegenüberstehen.
CSS erlaubt es Ihnen im Allgemeinen nicht, eine diskrete Eigenschaft wie die Anzeige von einem Wert auf den anderen zu übertragen. Dies bedeutet, dass der standardmäßige Ansatz mit einer Deckkraft von 0 bis 100 Prozent zum Erstellen von Übergängen ebenfalls nicht funktioniert, da die Anzeigeeigenschaft keine Verzögerungen zwischen Wertwechseln für den Abschluss von Übergängen zulässt.
Wenn Sie die berechnete Anzeigeeigenschaft der Dialog- und Popover-Elemente untersuchen, werden Sie feststellen, wie der Browser sie intelligent verwaltet, ohne dass wir dafür zusätzliche Anstrengungen unternehmen müssten, mit Ausnahme der Verwendung der von den APIs der jeweiligen Elemente bereitgestellten Methoden:
Hinweis: Die berechnete Anzeige für Popover-Elemente in DevTools wird aus irgendeinem Grund nicht automatisch aktualisiert. Sie müssen einen anderen Knoten auswählen und dann den Popover-Knoten erneut auswählen, um den aktualisierten Wert anzuzeigen.
Wie oben dargestellt, wird die Sichtbarkeit der Dialog- und Popover-Elemente auf dem Bildschirm vom Browser intern mithilfe der CSS-Anzeigeeigenschaft verwaltet.
Die folgende Demo zeigt, wie die Abhängigkeit der Dialog- und Popover-Elemente von der Anzeigeeigenschaft die standardmäßigen CSS-Übergangsansätze für sie unwirksam macht:
Siehe, dass die Stift-Deckkraft-/Sichtbarkeitsübergänge nicht mit Dialogen und Popovers von Rahul (@_rahul) auf CodePen funktionieren.
Bevor wir uns auf die Deckkraft und Transformationen zum Erstellen von Übergängen konzentrieren, sollten wir uns zunächst mit der Anzeigeeigenschaft befassen, die bestimmt, wie die zugehörigen Elemente auf dem Bildschirm angezeigt werden.
Ein weiteres Problem bei Overlay-Elementen ist das Fehlen anfänglicher Stile, die entscheidend sind, um einen ordnungsgemäßen Übergang für Elemente sicherzustellen, die dynamisch zum DOM hinzugefügt werden oder deren Sichtbarkeit dynamisch mit der Anzeigeeigenschaft gesteuert wird.
Nehmen wir an, unser Element soll eingeblendet werden, während es auf der Webseite gerendert wird. In diesem Fall müssen wir die anfängliche Deckkraft des Elements auf Null setzen und sie dann auf 100 Prozent umstellen, sobald es vollständig auf der Seite gerendert wird. Der einzige Ausgangszustand, der uns normalerweise zur Verfügung steht, ist der aktuelle Zustand der Elemente, der bei einer Deckkraft von Null dazu führen würde, dass das Element auf dem Bildschirm verschwindet.
Um dies in einen funktionalen Effekt umzuwandeln, können wir JavaScript verwenden, um programmgesteuerte Verzögerungen, Klassenwechsel oder CSS-Keyframe-Animationen hinzuzufügen, um einen übergangsähnlichen Effekt zu emulieren.
In den kommenden Abschnitten werden wir Möglichkeiten untersuchen, wie wir die Unfähigkeit der Anzeigeeigenschaft, Übergänge zu unterstützen, und das Fehlen anfänglicher Elementstile vor dem Rendern beheben können.
Wie oben erläutert, sind Dialog- und Popover-Elemente für ihre Sichtbarkeit auf dem Bildschirm auf die Anzeigeeigenschaft angewiesen, was es nahezu unmöglich macht, sie mithilfe von CSS-Übergängen zu animieren.
Die Anzeigeeigenschaft ist diskreter Natur, das heißt, sie ändert sich abrupt zwischen Werten. Es könnte beispielsweise von „Block“ zu „Keine“ wechseln, ohne die in der Übergangsdauer definierte Verzögerung zu berücksichtigen. Dies liegt daran, dass es zwischen solchen Werten keine logischen Zwischenzustände gibt, wie wir es bei Eigenschaften sehen, die additive Werte wie Deckkraft, Breite, Höhe und andere akzeptieren.
Um diskrete Eigenschaften mit CSS-Übergängen kompatibel zu machen, wurde eine neue Übergangseigenschaft namens „transition-behavior“ eingeführt, mit der Sie festlegen können, dass sich Übergänge auf eine bestimmte Weise verhalten, insbesondere für diskrete Elemente, die keine additiven Werte in numerischer Form haben. Pixel oder Prozentsätze.
Anstatt einen reibungslosen Übergang zwischen Werten zu ermöglichen, verschiebt das Verhalten „Diskretes Zulassen“ den Wechsel von einem diskreten Wert zu einem anderen, bis die angegebene Übergangsdauer abgelaufen ist:
.dynamic-display { transition: opacity 0.5s, translate ..., display 0.5s allow-discrete; ... }
Im obigen Snippet stellt das „allow-discrete“-Verhalten sicher, dass die Anzeigewerte eine halbe Sekunde warten, wie durch die Übergangsdauer angegeben, anstatt abrupt zu wechseln.
Diese Verzögerung beim Umschalten diskreter Werte gibt Übergängen für andere Eigenschaften mit additiven Werten genügend Zeit, ihre Aufgabe abzuschließen:
Sehen Sie sich das Pen-Zulassungsdiskrete-Übergangsverhalten in Aktion von Rahul (@_rahul) auf CodePen an.
Mit dem Verhalten diskreter Zulassen-Übergänge verstehen wir nun, wie die Ausgangsübergänge zu Elementen hinzugefügt werden können, deren Rendering oder Anzeige dynamisch verwaltet wird. Der Eingangsübergang funktioniert jedoch nicht, wenn keine Pre-Render-Stile vorhanden sind. In den nächsten Abschnitten werden einige Techniken zum Hinzufügen von Eintragsübergängen erläutert.
Bisher haben wir gelernt, wie man Exit-Übergänge in dynamisch hinzugefügte und verwaltete Elemente integriert, und jetzt werden wir dieselbe Technik auf Dialoge und Popovers anwenden.
Beginnen wir mit der Deklaration der Eingangs- und Ausgangsanimationen und untersuchen wir, wie CSS-Keyframes effektiv sein können, um eine Art Einstiegspunkt für Übergänge zu jedem Element hinzuzufügen, unabhängig von seiner Anzeige.
Die Verwendung von CSS-Keyframes zur Nachahmung der Startstile für Elemente ist einfach. Wir beginnen mit dem Hinzufügen von Ein- und Ausstiegsanimationen sowohl für die Elemente als auch für den Hintergrund für das Dialogelement.
Fügen wir einige CSS-Keyframes hinzu, um eine subtile Ein- und Ausblendanimation für die Elemente zu erstellen. Beachten Sie, dass wir die Keyframes für die Elemente und ihren jeweiligen Hintergrund (Pseudoelement) separat definieren müssen:
/* Keyframes for dialog and popover elements */ @keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } } @keyframes fadeOut { from { opacity: 1 } to { opacity: 0 } } /* Keyframes for the backdrop pseudo-element */ @keyframes backdropFadeIn { from { background: hsl(0 0% 0% / 0%) } to { background: hsl(0 0% 0% / 50%) } } @keyframes backdropFadeOut { from { background: hsl(0 0% 0% / 50%) } to { background: hsl(0 0% 0% / 0%) } }
Wir können jetzt die oben genannten Animations-Keyframes in verschiedenen Teilen unserer Elemente verwenden. Wir können den offenen Zustand unserer Dialoge und Popovers auch mit dem Attribut [open] und der Pseudoklasse :popover-open anvisieren, wie im folgenden Codeausschnitt gezeigt:
.my-dialog { animation: fadeOut 0.5s forwards; &::backdrop { animation: backdropFadeOut 0.5s forwards; } &[open] { animation: fadeIn 0.5s forwards; &::backdrop { animation: backdropFadeIn 0.5s forwards; } } } .my-popover { animation: fadeOut 0.5s forwards; &:popover-open { animation: fadeIn 0.5s forwards; } }
Wenn wir die oben genannten Codeausschnitte kombinieren und sie in einem Dialog und einem Popover-Element verwenden, ähnelt das Ergebnis der unten gezeigten Demonstration. Diese Technik eignet sich hervorragend für die Eingangsanimation, überspringt jedoch den Teil der Ausgangsanimation vollständig:
Sehen Sie sich den Pen-HTML5-Dialog und die Popover-Eintragsanimation mit CSS-Keyframes von Rahul (@_rahul) auf CodePen an.
Wenn Sie ein Auge für Mikrointeraktionen haben, werden Sie feststellen, dass die Einblend-Animation beim Öffnen des Dialogfelds gut funktioniert, beim Schließen oder Abbrechen jedoch die Ausblend-Animation beim Verlassen nicht zu funktionieren scheint arbeiten. Warum das so ist, erfahren Sie im nächsten Abschnitt.
Der Grund, warum die Exit-Animation in der obigen Demo nicht funktioniert, ist die abrupte Änderung in der berechneten Anzeige der Elemente aufgrund der Popover- und Dialog-APIs. Wir haben zuvor besprochen, wie die Eigenschaft „transition-behavior“ uns dabei hilft, diskrete CSS-Eigenschaften neben Übergängen zu verwalten. Versuchen wir in diesem Szenario, die Eigenschaft „transition-behavior“ zu verwenden, um zu sehen, ob das Problem dadurch behoben wird.
Sehen Sie sich den Pen-HTML5-Dialog und Popover-Animationen zum Ein- und Aussteigen mit CSS-Keyframes von Rahul (@_rahul) auf CodePen an.
Glücklicherweise wurde das Problem mit der Exit-Animation durch das Hinzufügen des „allow-discrete“-Verhaltens zu den Anzeige- und Overlay-Eigenschaften behoben. Sowohl die Ein- als auch die Ausstiegsanimationen funktionieren jetzt korrekt.
In der Produktion führt dieser Ansatz zu einem viel größeren Code mit zwei bis drei herstellerspezifischen Variationen für jeden Block der Animationsdeklaration. Die hier implementierten Effekte sind nicht allzu komplex und hätten mithilfe von CSS-Übergängen erzielt werden können, wenn es nicht die Dialog- und Popover-Elemente gegeben hätte.
CSS-Keyframes eignen sich am besten zum Erstellen von Keyframe-Animationen, bieten jedoch keine Optimierung vor dem Rendern, auch wenn es den Anschein hat. Mit der neu eingeführten @starting-style at-rule können wir jedoch übergangsbasierte Effekte erzielen, ohne CSS-Keyframe-Animationen zu verwenden.
Zuvor haben wir besprochen, dass DOM-abhängige Elemente einen Ausgangspunkt für den Übergang von Anfangsstilen benötigen, und genau das liefert die neue @starting-style CSS at-rule.
Die @starting-style at-rule ist eine CSS-Übergangsebene-2-Funktion, die zum Deklarieren von Startwerten für Eigenschaften eines Übergangselements ab dessen erster Stilaktualisierung verwendet wird.
The following syntax allows you to specify a starting point for the styles of a given element from which the transition will pick up and operate. The properties included within the selectors of this at-rule should be the ones that will be involved in the associated transitions:
@starting-style { .selector { opacity: 0; ... } }
Try re-rendering the element dynamically in the below demo by pressing the trigger button, and see how straightforward it is to create an entry point for the transitions with @starting-style before the associated elements are rendered:
See the Pen HTML5 Dialog and popover entry & exit animations w/ CSS keyframes by Rahul (@_rahul) on CodePen.
The @starting-style feature is expected to gain solid support across major web browsers, and currently, it is well-supported on Chromium and Webkit-based browsers. See the latest support here.
Following the pattern above, we can add subtle animations to dialog and popover elements using the allow-discrete transition behavior and @starting-style.
Before moving ahead, let’s first ensure that we use the allow-discrete behavior for the transition of display and overlay properties. This can be done explicitly by defining the transition-behavior property inside the selectors, or you can combine it in the transition property alongside other transitions as shown below:
.my-dialog, .my-popover { transition: opacity 0.5s, translate 0.5s, overlay 0.5s allow-discrete, display 0.5s allow-discrete; &::backdrop { transition: background 0.5s, overlay 0.5s allow-discrete, display 0.5s allow-discrete; } }
To handle the initial styles for the open state, we should add a @starting-style block and add the properties that are responsible for our transition effect. You don't need to include the display and overlay properties here, as those are already managed by the dialog and popover APIs behind the scenes:
@starting-style { .my-dialog[open], .my-popover:popover-open { opacity: 0; transform: translateY(-1em); } .my-dialog[open]::backdrop { background-color: hsl(0 0 0 / 0%); } }
With dialogs and popovers, we have the API advantage to ourselves, which means we can use certain attributes and pseudo-classes like dialog[open] and :popover-open to target the open states:
.my-dialog[open], .my-popover:popover-open { opacity: 1; transform: translateY(0); } .my-dialog[open]::backdrop { background-color: hsl(0 0 0 / 10%); }
Lastly, you can give the original elements styles that correspond to a closing transition, which is basically the closing state. In other words, keep the dialog element faded out and slid up by default:
.my-dialog, .my-popover { opacity: 0; translate: 0 -1em; } .my-dialog { &::backdrop { background-color: transparent; } }
The following demo reflects the outcomes of applying allow-discrete behavior to transitions, defining initial styles with @starting-style, and styling for both open and closed states. Now both the entry and exit animations work smoothly with our dialog and popover elements, and we used less code compared to CSS keyframes:
See the Pen HTML5 Dialog and popover entry & exit animations w/ @starting-style by Rahul (@_rahul) on CodePen.
If you want to remember this sequence of states we covered when constructing the above example, refer to the below graphic which visually illustrates the changes and communication between states:
Let’s take it one step further by implementing different animations for dialog elements. The baseline remains the same: only the properties related to transformations and transitions will change.
The idea behind creating a stylish rotating dialog box involves playing with the opacity and a couple of CSS transformation properties:
.my-dialog { transition: opacity 0.5s, translate 0.5s, rotate 0.5s, overlay 0.5s allow-discrete, display 0.5s allow-discrete; }
The starting styles for the open state of the dialog include the following:
Here’s the code:
@starting-style { .my-dialog[open] { opacity: 0; translate: -50% -100%; rotate: -180deg; } }
The closed state resembles the starting styles but with altered translations and rotations to reflect an opposite movement when exiting the dialog element:
.my-dialog { /* Previous styles */ opacity: 0; translate: 50% 100%; rotate: 180deg; }
The dialog element in the open state has 100 percent opacity, no translation on either axis, and no rotation, effectively positioning it at the center of the screen:
.my-dialog[open] { opacity: 1; translate: 0 0; rotate: 0deg; }
The final output looks something like below:
See the Pen HTML5 Dialog and popover rotating animation by Rahul (@_rahul) on CodePen.
To create a bouncing effect without using CSS keyframe animations, we can utilize a Bezier curve as the transition-timing function for the transformation and opacity transitions of our dialog. We’ll use the scale transformation for this effect.
Feel free to experiment with different x1, y1, x2, and y2 values for the Bezier curve, and implement them in your animation projects:
.my-dialog { transition: opacity 0.4s cubic-bezier(0.4, 1.6, 0.4, 0.8), scale 0.4s cubic-bezier(0.4, 1.6, 0.4, 0.8), overlay 0.4s allow-discrete, display 0.4s allow-discrete; }
Now we can easily determine the starting styles and the open and closed states. The initial styles for the open and closed states will be the same — the dialog box will be scaled down to zero and completely transparent.
In the open state, the dialog box will have 100 percent opacity and be scaled to one. The rest of the transition effects will be handled by the Bezier curve-powered transitions:
@starting-style { .my-dialog[open] { opacity: 0; scale: 0; } } .my-dialog { opacity: 0; scale: 0; &[open] { opacity: 1; scale: 1; } }
Here’s how this looks in action:
See the Pen HTML5 Dialog and popover bouncing animation by Rahul (@_rahul) on CodePen.
We will use the same Bezier curve in this animation to keep things simple, but the effect will be different compared to the previous one. The idea is to translate the dialogue along the y-axis instead of scaling it, as we did with the last effect:
.my-dialog { transition: opacity 0.5s cubic-bezier(0.4, 1.6, 0.4, 0.8), translate 0.5s cubic-bezier(0.4, 1.6, 0.4, 0.8), overlay 0.5s allow-discrete, display 0.5s allow-discrete; }
The idea is to keep the dialog way up the viewport on the y-axis initially. Then, we will transform the dialog to zero when it is opened and finally translate it down the axis:
@starting-style { .my-dialog[open] { opacity: 0; translate: 0 -200%; } } .my-dialog { opacity: 0; translate: 0 200%; &[open] { opacity: 1; translate: 0 0; } }
Instead of applying a 100 percent positive or negative translation, I doubled it to create the impression of urgency in the dialog box. See it in action below:
See the Pen HTML5 Dialog and popover slide-up-down bouncing animation by Rahul (@_rahul) on CodePen.
The above effects suit the dialog elements well, but they won’t look great with the popover elements. This section is dedicated to some nice popover animation effects, which make the popover look like popovers and nothing more.
This effect resembles the popover effect we created initially. In that example, the popover appeared from the top and slide-fading down the y-axis, which isn’t what you’d expect from a popup in the bottom-right corner of the viewport.
Let’s rectify that by adding the same translation on the y-axis for the starting styles and the close state. Everything else remains unchanged:
See the Pen Rising up and down popover animation by Rahul (@_rahul) on CodePen.
The process of creating a growing and shrinking effect is simple and involves the use of scale transformation with a twist.
By setting the transformation origin to the absolute bottom-right, we can ensure that the popover expands from the right, aligning with its current position at the bottom-right.
See the Pen Growing and shrinking popover animation by Rahul (@_rahul) on CodePen.
This technique is commonly used to create animations for notification toasts. To achieve this effect, you simply need to translate the popover element 100 percent to the right, putting it out of the viewport. Then, in the open state, you can translate it back to zero to complete the effect.
See the Pen Slide in out from right popover animation by Rahul (@_rahul) on CodePen.
We learned about incorporating CSS transition-based animations in dialog and popover elements using pure CSS. We discussed the complexities and issues of traditional transitioning with overlay elements, and then we addressed these problems one by one using CSS keyframes and, more importantly, the @starting-style at-rule, which is specially developed for transitions.
However, the @starting-style feature is fairly new and not yet available globally. Consequently, using CSS keyframes and the Web Animation API is an option that makes sense in production and provides more granular control over adding animation effects.
Having said that, I recommend the @starting-style approach once it gets adopted widely to keep things simple and lightweight with CSS transition applications.
As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording everything that happens in your web app, mobile app, or website. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.
Modernize how you debug web and mobile apps — start monitoring for free.
Das obige ist der detaillierte Inhalt vonAnimieren von Dialog- und Popover-Elementen mit CSS @starting-style. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!