Animating dialog and popover elements with CSS @starting-style

WBOY
Release: 2024-07-31 02:28:13
Original
605 people have browsed it

Written by Rahul Chhodde✏️

Native dialog and popover elements have their own well-defined roles in modern-day frontend web development. Dialog elements are known to communicate with the user and collect their inputs, while popovers are more apt in providing low-priority secondary info to the user.

In a previous article about dialogs vs.popovers, we discussed that both these elements have their dedicated JavaScript APIs that allow us to make the most out of these two elements.

When it comes to adding animations and interactivity to these elements, JavaScript libraries are preferred over CSS. Such elements typically require minimal animations, and using huge animation libraries merely to add a few simple effects can significantly increase the unnecessary load on your app.

To remedy that, this article will help you code animation effects into dialogs and popovers using pure CSS techniques. We'll cover CSS keyframes and the newly introduced @starting-style at-rule, both of which can be used to create subtle animations with improved performance.

The problem with animating overlay elements

Dialogs and popovers are overlay elements, which means they operate on the topmost layer rendered by the browser. As discussed previously, these elements also rely on dedicated APIs to manage their display and/or modality.

Let’s look at the challenges we face when animating dialogs and popovers using traditional CSS transition techniques.

Dependence on the display property

CSS in general doesn’t allow you to transition a discrete property like display from one value to the other. This means that the standard opacity zero to 100 percent approach for creating transitions won't work either, as the display property does not permit delays between value switches for transitions to complete.

If you inspect the computed display property of the dialog and popover elements, you’ll notice how the browser intelligently manages it without any additional effort on our part, except for using the methods provided by APIs of the respective elements:Animating dialog and popover elements with CSS @starting-style

Note: The computed display for popover element in DevTools doesn’t update automatically for some reason. You have to select a different node and then reselect the popover node to see the updated value.

As displayed above, the on-screen visibility of the dialog and popover elements is handled by the browser internally using the CSS display property.

The following demo illustrates how the dependency of the dialog and popover elements on the display property makes the standard CSS transition approaches ineffective for them:

See the Pen Opacity/Visibility transitions doesn't work with dialogs and popovers by Rahul (@_rahul) on CodePen.

Before concentrating on opacity and transformations to create transitions, we should consider the display property first, which governs how the associated elements are displayed on the screen.

Lack of initial styles before rendering

Another problem with overlay elements is the lack of initial styles, which is crucial to ensure proper transition for elements that are dynamically added to the DOM or have their visibility controlled dynamically with the display property.

Let’s say our element should fade in while it renders on the web page. In this case, we need to set the element’s initial opacity to zero, and then transition it to 100 percent once it completely renders on the page. The only initial state we usually have available to us is the present state of the elements, which if provided an opacity of zero, would make the element disappear on screen.

To turn this into a functional effect, we can use JavaScript to add programmatic delays, class switching, or CSS keyframe animations to emulate a transition-like effect.

In the upcoming sections, we will explore ways to address the display property’s inability to support transitions and the lack of initial element styles before rendering.

Transitioning discrete CSS properties

As discussed above, dialog and popover elements rely on the display property for their visibility on the screen, making them nearly impossible to animate using CSS transitions.

The display property is of discrete nature, which means it changes abruptly between values. For example, it might change from block to none without considering the delay defined in the transition-duration. This is because there are no logical intermediate states between such values, as we see with properties accepting additive values like opacity, width, height, and others.

為了使離散屬性與CSS過渡相容,引入了一個名為transition-behavior的新過渡屬性,它允許您使過渡以某種方式表現,特別是對於沒有數位形式、像素等附加價值的離散元素,或百分比。

允許離散行為不是在值之間平滑轉換,而是推遲從一個離散值到另一個離散值的更改,直到指定的轉換持續時間過去:

雷雷

在上面的程式碼片段中,允許離散行為確保顯示值將等待半秒(如轉換持續時間指定),而不是突然切換。

切換離散值的延遲允許具有附加價值的其他屬性的轉換有足夠的時間來完成其工作:

查看 CodePen 上 Rahul (@_rahul) 的 Pen 允許離散轉換行為。

透過允許離散過渡行為,我們現在了解如何將退出過渡添加到動態管理渲染或顯示的元素。但是,如果沒有預先渲染樣式,入口轉換將無法運作。接下來的幾節將探討一些添加入口過渡的技術。

使用 CSS 關鍵影格動畫對話框和彈出窗口

到目前為止,我們已經學習瞭如何將退出轉換合併到動態新增和管理的元素中,現在我們將相同的技術應用於對話方塊和彈出視窗。

讓我們先聲明進入和退出動畫,並檢查 CSS 關鍵影格如何有效地為任何元素(無論其顯示如何)添加某種過渡入口點。

使用 CSS 關鍵影格新增進入動畫

使用 CSS 關鍵影格來模仿元素的起始樣式很簡單。我們將從添加元素的進入和退出動畫以及對話方塊元素的背景開始。

讓我們加入一些 CSS 關鍵影格來為元素創建微妙的淡入和淡出動畫。請注意,我們需要分別定義元素及其各自背景(偽元素)的關鍵影格:

雷雷

我們現在可以在元素的不同部分使用上述動畫關鍵影格。我們也可以使用 [open] 屬性和 :popover-open 偽類別來定位對話方塊和彈出視窗的開啟狀態,如以下程式碼片段所示:

雷雷

如果我們組合上述程式碼片段並在對話框和彈出框元素中使用它們,結果將類似於下面共享的演示。這種技術對於進入動畫來說非常有用,但它完全跳過了退出動畫部分:

查看 CodePen 上 Rahul (@_rahul) 的 Pen HTML5 對話方塊和帶有 CSS 關鍵影格的彈出視窗輸入動畫。

如果您關注微交互,您會發現淡入進入動畫在打開對話框時效果很好,但在關閉或取消對話框時,淡出退出動畫似乎不起作用。讓我們在下一節中了解原因。

在對話方塊和彈出視窗中新增退出動畫

退出動畫在上面的示範中不起作用的原因是由於彈出視窗和對話方塊 API 導致元素的計算顯示發生突然變化。我們之前討論了過渡行為屬性如何幫助我們管理離散的 CSS 屬性和過渡。讓我們嘗試在這種情況下使用過渡行為屬性,看看它是否可以解決問題。

查看 CodePen 上 Rahul (@_rahul) 的 Pen HTML5 對話框以及帶有 CSS 關鍵幀的彈出視窗進入和退出動畫。

幸運的是,在顯示和疊加屬性中添加允許離散行為已經解決了退出動畫問題。進入和退出動畫現在都可以正常工作。

在生產中,這種方法最終會產生更大的程式碼,每個動畫聲明區塊都有兩到三個特定於供應商的變體。我們在這裡實現的效果並不太複雜,如果沒有對話框和彈出框元素,可以使用 CSS 過渡來實現。

CSS 關鍵影格最適合建立關鍵影格動畫,但它們不提供預渲染最佳化,儘管看起來似乎如此。然而,透過新引入的@starting-style at-rule,我們可以在不使用CSS關鍵影格動畫的情況下實現基於過渡的效果。

CSS中的@starting-style at-rule是什麼?

之前我們討論了依賴 DOM 的元素如何需要一個初始樣式進行轉換的起點,而這正是新的 @starting-style CSS at-rule 所提供的。

@starting-style at-rule 是 CSS Transition Level 2 功能,用於宣告過渡元素上屬性的起始值,從第一次樣式更新開始。

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; ... } }
Copy after login

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; } }
Copy after login

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%); } }
Copy after login

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%); }
Copy after login

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; } }
Copy after login

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; }
Copy after login

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; } }
Copy after login

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; }
Copy after login

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; }
Copy after login

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; }
Copy after login

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; } }
Copy after login

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; }
Copy after login

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; } }
Copy after login

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.

The above is the detailed content of Animating dialog and popover elements with CSS @starting-style. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!