Maison  >  Article  >  interface Web  >  Animation d'éléments de dialogue et de popover avec CSS @starting-style

Animation d'éléments de dialogue et de popover avec CSS @starting-style

WBOY
WBOYoriginal
2024-07-31 02:28:13648parcourir

Écrit par Rahul Chhodde✏️

Les éléments de dialogue et de popover natifs ont leurs propres rôles bien définis dans le développement Web frontal moderne. Les éléments de dialogue sont connus pour communiquer avec l'utilisateur et collecter ses entrées, tandis que les popovers sont plus susceptibles de fournir des informations secondaires de faible priorité à l'utilisateur.

Dans un article précédent sur les boîtes de dialogue et les popovers, nous avons expliqué que ces deux éléments ont leurs API JavaScript dédiées qui nous permettent de tirer le meilleur parti de ces deux éléments.

Quand il s'agit d'ajouter des animations et de l'interactivité à ces éléments, les bibliothèques JavaScript sont préférées aux CSS. De tels éléments nécessitent généralement un minimum d'animations, et l'utilisation d'énormes bibliothèques d'animations simplement pour ajouter quelques effets simples peut augmenter considérablement la charge inutile sur votre application.

Pour remédier à cela, cet article vous aidera à coder des effets d'animation dans des boîtes de dialogue et des popovers en utilisant des techniques CSS pures. Nous aborderons les images clés CSS et la nouvelle règle at @starting-style, qui peuvent toutes deux être utilisées pour créer des animations subtiles avec des performances améliorées.

Le problème avec l'animation des éléments de superposition

Les boîtes de dialogue et les popovers sont des éléments de superposition, ce qui signifie qu'ils fonctionnent sur la couche supérieure rendue par le navigateur. Comme évoqué précédemment, ces éléments s’appuient également sur des API dédiées pour gérer leur affichage et/ou modalité.

Examinons les défis auxquels nous sommes confrontés lors de l'animation de boîtes de dialogue et de popovers à l'aide des techniques de transition CSS traditionnelles.

Dépendance à la propriété d'affichage

CSS en général ne vous permet pas de faire passer une propriété discrète comme l'affichage d'une valeur à l'autre. Cela signifie que l'approche standard d'opacité de zéro à 100 pour cent pour la création de transitions ne fonctionnera pas non plus, car la propriété d'affichage ne permet pas de délais entre les changements de valeur pour que les transitions se terminent.

Si vous inspectez la propriété d'affichage calculée des éléments de dialogue et de popover, vous remarquerez comment le navigateur la gère intelligemment sans aucun effort supplémentaire de notre part, sauf en utilisant les méthodes fournies par les API des éléments respectifs : Animating dialog and popover elements with CSS @starting-style  

Remarque : l'affichage calculé pour l'élément popover dans DevTools ne se met pas à jour automatiquement pour une raison quelconque. Vous devez sélectionner un autre nœud, puis resélectionner le nœud popover pour voir la valeur mise à jour.

Comme indiqué ci-dessus, la visibilité à l'écran des éléments de dialogue et de popover est gérée par le navigateur en interne à l'aide de la propriété d'affichage CSS.

La démo suivante illustre comment la dépendance des éléments de dialogue et de popover sur la propriété display rend les approches de transition CSS standard inefficaces pour eux :

Voir les transitions Pen Opacité/Visibilité ne fonctionnent pas avec les boîtes de dialogue et les popovers par Rahul (@_rahul) sur CodePen.

Avant de nous concentrer sur l'opacité et les transformations pour créer des transitions, nous devons d'abord considérer la propriété d'affichage, qui régit la façon dont les éléments associés sont affichés à l'écran.

Manque de styles initiaux avant le rendu

Un autre problème avec les éléments de superposition est le manque de styles initiaux, ce qui est crucial pour assurer une transition appropriée pour les éléments qui sont ajoutés dynamiquement au DOM ou dont la visibilité est contrôlée dynamiquement avec la propriété display.

Disons que notre élément doit apparaître en fondu lors de son affichage sur la page Web. Dans ce cas, nous devons définir l’opacité initiale de l’élément sur zéro, puis la faire passer à 100 % une fois qu’il est complètement affiché sur la page. Le seul état initial dont nous disposons généralement est l'état actuel des éléments, qui, s'il avait une opacité de zéro, ferait disparaître l'élément à l'écran.

Pour transformer cela en un effet fonctionnel, nous pouvons utiliser JavaScript pour ajouter des retards programmatiques, un changement de classe ou des animations d'images clés CSS pour émuler un effet de type transition.

Dans les prochaines sections, nous explorerons les moyens de remédier à l'incapacité de la propriété d'affichage à prendre en charge les transitions et au manque de styles d'éléments initiaux avant le rendu.

Transition des propriétés CSS discrètes

Comme indiqué ci-dessus, les éléments de dialogue et de popover dépendent de la propriété display pour leur visibilité à l'écran, ce qui les rend presque impossibles à animer à l'aide de transitions CSS.

La propriété d'affichage est de nature discrète, ce qui signifie qu'elle change brusquement entre les valeurs. Par exemple, il peut passer de block à none sans tenir compte du délai défini dans la durée de transition. En effet, il n’existe pas d’états intermédiaires logiques entre ces valeurs, comme nous le voyons avec les propriétés acceptant des valeurs additives telles que l’opacité, la largeur, la hauteur, etc.

Pour rendre les propriétés discrètes compatibles avec les transitions CSS, une nouvelle propriété de transition appelée transition-behaviour a été introduite qui vous permet de faire en sorte que les transitions se comportent d'une certaine manière, en particulier pour les éléments discrets qui n'ont pas de valeurs additives sous forme numérique, pixels ou pourcentages.

Au lieu d'une transition fluide entre les valeurs, le comportement d'autorisation discrète reporte le changement d'une valeur discrète à une autre jusqu'à ce que la durée de transition spécifiée soit écoulée :

.dynamic-display {
  transition: opacity 0.5s, translate ..., display 0.5s allow-discrete;
  ...
}

Dans l'extrait ci-dessus, le comportement d'autorisation discrète garantit que les valeurs d'affichage attendront une demi-seconde, comme spécifié par la durée de transition, au lieu de changer brusquement.

Ce délai dans la commutation des valeurs discrètes permet aux transitions pour d'autres propriétés avec des valeurs additives suffisamment de temps pour terminer leur travail :

Voir le comportement de transition discret autorisé par Pen en action par Rahul (@_rahul) sur CodePen.

Avec le comportement de transition autoriser-discrète, on comprend désormais comment les transitions de sortie peuvent être ajoutées aux éléments dont le rendu ou l'affichage est géré dynamiquement. Cependant, la transition d'entrée ne fonctionnera pas en l'absence de styles de pré-rendu. Les prochaines sections exploreront quelques techniques pour ajouter des transitions d'entrée.

Animation de boîtes de dialogue et de popovers avec des images clés CSS

Jusqu'à présent, nous avons appris à incorporer des transitions de sortie aux éléments ajoutés et gérés dynamiquement, et nous allons maintenant appliquer la même technique aux boîtes de dialogue et aux popovers.

Commençons par déclarer les animations d'entrée et de sortie et examinons comment les images clés CSS peuvent être efficaces pour ajouter une sorte de point d'entrée pour les transitions vers n'importe quel élément, quel que soit son affichage.

Ajout d'une animation d'entrée avec des images clés CSS

Utiliser des images clés CSS pour imiter les styles de départ des éléments est simple. Nous commencerons par ajouter des animations d'entrée et de sortie pour les éléments ainsi que la toile de fond de l'élément de dialogue.

Ajoutons quelques images clés CSS pour créer une animation subtile de fondu d'entrée et de sortie pour les éléments. Notez que nous devons définir séparément les images clés des éléments et leur toile de fond respective (pseudo-élément) :

/* 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%) }
}

Nous pouvons désormais utiliser les images clés d'animation ci-dessus dans différentes parties de nos éléments. Nous pouvons également cibler l'état ouvert de nos boîtes de dialogue et popovers avec l'attribut [open] et la pseudo-classe :popover-open comme indiqué dans l'extrait de code suivant :

.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;
  }
}

Si nous combinons les extraits de code ci-dessus et les utilisons dans une boîte de dialogue et un élément popover, le résultat ressemblera à la démonstration partagée ci-dessous. Cette technique est idéale pour l'animation d'entrée, mais elle ignore complètement la partie animation de sortie :

Voir la boîte de dialogue Pen HTML5 et l'animation d'entrée popover avec images clés CSS par Rahul (@_rahul) sur CodePen.

Si vous êtes attentif aux micro-interactions, vous remarquerez que l'animation d'entrée en fondu fonctionne bien lors de l'ouverture de la boîte de dialogue, mais lors de sa fermeture ou de son annulation, l'animation de sortie en fondu ne semble pas travail. Voyons pourquoi dans la section suivante.

Ajout d'animations de sortie aux boîtes de dialogue et popovers

La raison pour laquelle l'animation de sortie ne fonctionne pas dans la démo ci-dessus est le changement brusque dans l'affichage calculé des éléments en raison des API de popover et de dialogue. Nous avons déjà expliqué comment la propriété transition-behaviour nous aide à gérer les propriétés CSS discrètes parallèlement aux transitions. Essayons d'utiliser la propriété transition-behavior dans ce scénario pour voir si elle résout le problème.

Voir la boîte de dialogue Pen HTML5 et les animations d'entrée et de sortie popover avec images clés CSS par Rahul (@_rahul) sur CodePen.

Heureusement, l'ajout du comportement Allow-Discrete aux propriétés d'affichage et de superposition a résolu le problème de l'animation de sortie. Les animations d'entrée et de sortie fonctionnent désormais correctement.

En production, cette approche aboutit à un code beaucoup plus volumineux avec deux à trois variantes spécifiques au fournisseur pour chaque bloc de déclaration d'animation. Les effets que nous avons implémentés ici ne sont pas trop complexes et auraient pu être obtenus à l'aide de transitions CSS sans les éléments de dialogue et de popover.

Les images clés CSS sont mieux destinées à créer des animations d'images clés, mais elles n'offrent pas d'optimisation avant le rendu, même si elles semblent le faire. Cependant, avec la nouvelle règle at @starting-style, nous pouvons obtenir des effets basés sur la transition sans utiliser d'animations d'images clés CSS.

Qu'est-ce que la règle at @starting-style en CSS ?

Plus tôt, nous avons expliqué comment les éléments dépendants du DOM nécessitent un point de départ pour la transition des styles initiaux, et c'est exactement ce que propose la nouvelle règle at CSS @starting-style.

La règle at @starting-style est une fonctionnalité CSS Transition Niveau 2 utilisée pour déclarer les valeurs de départ des propriétés sur un élément en transition, à partir de sa première mise à jour de style.

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.

Dialog and popover transitions using @starting-style

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: Animating dialog and popover elements with CSS @starting-style  

Advanced dialog animations with @starting-style

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.

Rotating-in-out dialogs

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:

  • Zero percent opacity to make it initially transparent
  • A translation of -50 percent along the x-axis to shift the dialog from the center to the left
  • A translation of -100 percent along the y-axis to move the dialog outside the visible viewport
  • A rotation of -180 degrees to prepare it for positive rotation when opened

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.

Bouncing in-out dialogs

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.

Sliding and bouncing dialogs

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.

Subtle popover animations with @starting-style

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.

Rising-sinking popover

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.

Growing and shrinking popover

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.

The toast popover

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.

Conclusion

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.

Is your frontend hogging your users' CPU?

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 Signup

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.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:Icônes CSS avec exemplesArticle suivant:Icônes CSS avec exemples