検索
ホームページウェブフロントエンドCSSチュートリアルカスタムプロパティとキュービックベジエ()を使用して複雑なCSS遷移を構築する

Build Complex CSS Transitions using Custom Properties and cubic-bezier()

I recently illustrated how we can achieve complex CSS animations using cubic-bezier() and how to do the same when it comes to CSS transitions. I was able to create complex hover effect without resorting to keyframes. In this article, I will show you how to create even more complex CSS transitions.

This time, let’s use the @property feature. It’s only supported on Chrome-based browsers for now but we can still play with it and demonstrate how it, too, and can be used to build complex animations.

I highly recommend reading my previous article because I will be referring to a few concepts I explained in detail there. Also, please note that the demos in this article are best viewed in Chromium-based browsers while @property support is still limited.

Let’s start with a demo:

Click on the button (more than once) and see the “magic” curve we get. It may look trivial at first glance because we can achieve such effect using some complex keyframes. But the trick is that there is no keyframe in there! That animation is done using only a transition.

Awesome right? And this is only the beginning, so let’s dig in!

The main idea

The trick in the previous example relies on this code:

@property --d1 {
  syntax: '<number>';
  inherits: false;
  initial-value: 0;
}
@property --d2 {
  syntax: '<number>';
  inherits: false;
  initial-value: 0;
}

.box {
  top: calc((var(--d1) + var(--d2)) * 1%);
  transition:
    --d1 1s cubic-bezier(0.7, 1200, 0.3, -1200),
    --d2 1s cubic-bezier(0.5, 1200, 0.5, -1200);
}
.box:hover {
  --d1: 0.2;
  --d1: -0.2;
}</number></number>

We’re defining two custom properties, --d1 and --d2. Then, we declare the top property on a .box element using the sum of both those properties. Nothing overly complex yet—just calc() applied to two variables.

The two properties are defined as and I multiply those values by 1% to convert them into a percentage. We could define these as right away to avoid the multiplication. But I’ve chosen numbers instead in favor of more flexibility for more complex operations later.

Notice that we apply a different transition to each variable—more precisely, a different timing-function with the same duration. It’s actually a different sinusoidal curve for both variables which is something I get deep into in my previous article.

From there, the property values change when the .box is hovered, triggering the animation. But why do we get the result we see in the demo?

It’s all about math. We are adding two functions to create a third one. For --d1, we have a function (let’s call it F1); for --d2 , we have another one (let’s call it F2). That means the value of top is F1 + F2.

An example to better illustrate:

The first two transitions illustrate each variable individually. The third one is the sum of them. Imagine that at in each step of the animation we take the value of both variables and we add them together to get each point along the final curve.

Let’s try another example:

This time, we combine two parabolic curve to get a… well, I don’t know its name it but it’s another complex curve!

This trick is not only limited to the parabolic and sinusoidal curve. It can work with any kind of timing function even if the result won’t always be a complex curve.

This time:

  • --d1 goes from 0 to 30 with an ease-in timing function
  • --d2 goes from 0 to -20 with an ease-out timing function

The result? The top value goes from 0 to 10 (30-20) with a custom timing function (the sum of ease-in and ease-out).

We are not getting a complex transition in this case—it’s more to illustrate the fact that it’s a generic idea not only limited to cubic-bezier().

I think it’s time for an interactive demo.

All you have to do is to adjust a few variables to build your own complex transition. I know cubic-bezier() may be tricky, so consider using this online curve generator and also refer to my previous article.

Here are some examples I made:

As you can see, we can combine two different timing functions (created using cubic-bezier() ) to create a third one, complex enough to achieve a fancy transition. The combinations (and possibilities) are unlimited!

In that last example, I wanted to demonstrate how adding two opposite functions lead to the logical result of a constant function (no transition). Hence, the flat line.

Let’s add more variables!

You thought we’d stop at only two variables? Certainly not! We can extend the logic to N variables. There is no restriction—we define each one with a timing function and sum them up.

An example with three variables:

In most cases, two variables are plenty to create a fancy curve, but it’s neat to know that the trick can be extended to more variables.

Can we subract, multiply and divide variables?

Of course! We can also extend the same idea to consider more operations. We can add, subtract, multiply, divide—and even perform a complex formula between variables.

Here, we’re multiplying values:

We can also use one variable and multiply it by itself to get a quadratic function!

Let’s add more fun in there by introducing min()/max() to simulate an abs() function:

Notice that in the second box we will never get higher than the center point on the y-axis because top is always a positive value. (I added a margin-top to make the center of box the reference for 0.)

I won’t get into all the math, but you can imagine the possibilities we have to create any kind of timing function. All we have to do is to find the right formula either using one variable or combining multiple variables.

Our initial code can be generalized:

@property --d1 { /* we do the same for d2 .. dn */
  syntax: '<number>';
  inherits: false;
  initial-value: i1; /* the initial value can be different for each variable */
}

.box {
  --duration: 1s; /* the same duration for all */
  property: calc(f(var(--d1),var(--d2), .. ,var(--dn))*[1UNIT]);
  transition:
    --d1 var(--duration) cubic-bezier( ... ),
    --d2 var(--duration) cubic-bezier( ... ),
    /* .. */
    --dn var(--duration) cubic-bezier( ... );
}
.box:hover {
  --d1:f1;
  --d2:f2;
  /* .. */
  --dn:f3;
}</number>

This is pseudo-code to illustrate the logic:

  1. We use @property to define numeric custom properties, each with an initial value.
  2. Each variable has its own timing function but the same duration.
  3. We define an f function that is the formula used between the variables. The function provides a number that we use to multiply the relevant unit. All this runs in calc() applied to the property.
  4. We update the value of each variable on hover (or toggle, or whatever).

Given this, the property transitions from f(i1,i2,…,in) to f(f1,f2,..,fn) with a custom timing function.

Chaining timing functions

We’ve reached the point where we were able to create a complex timing function by combining basic ones. Let’s try another idea that allow us to have more complex timing function: chaining timing functions together.

The trick is to run the transitions sequentially using the transition-delay property. Let’s look back at the interactive demo and apply a delay to one of the variables:

We are chaining timing functions instead of adding them together for yet another way to create more complex timing functions! Mathematically, it’s still a sum, but since the transitions do not run at the same time, we will be summing a function with a constant, and that simulates the chaining.

Now imagine the case with N variables that we are incrementally delayed. Not only can we create complex transitions this way, but we have enough flexibility to build complex timelines.

Here is a funny hover effect I built using that technique:

You will find no keyframes there. A small action scene is made entirely using one element and a CSS transition.

Here is a realistic pendulum animation using the same idea:

Or, how about a ball that bounces naturally:

Or maybe a ball rolling along a curve:

See that? We just created complex animations without a single keyframe in the code!

That’s a wrap!

I hope you took three key points away from this article and the previous one:

  1. We can get parabolic and sinusoidal curves using cubic-bezier() that allow us to create complex transitions without keyframes.
  2. We can create more curves by combining different timing functions using custom properties and calc().
  3. We can chain the curves using the transition-delay to build a complex timeline.

Thanks to these three features, we have no limits when it comes to creating complex animations.

以上がカスタムプロパティとキュービックベジエ()を使用して複雑なCSS遷移を構築するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
「ポッドキャストにサブスクライブ」リンクはどこにすべきですか?「ポッドキャストにサブスクライブ」リンクはどこにすべきですか?Apr 16, 2025 pm 12:04 PM

しばらくの間、iTunesはポッドキャストの大きな犬だったので、「ポッドキャストにサブスクライブ」をリンクした場合:

ブラウザエンジンの多様性ブラウザエンジンの多様性Apr 16, 2025 pm 12:02 PM

彼らが2013年にChromeに行ったとき、私たちはオペラを失いました。今年初めにChromeになったとき、Edgeと同じ取引。マイク・テイラーはこれらの変更を「減少させて」と呼びました

Web共有に関するUXの考慮事項Web共有に関するUXの考慮事項Apr 16, 2025 am 11:59 AM

Trashy ClickBaitサイトから出版物の最大の8月まで、共有ボタンは長い間ウェブ全体でユビキタスでした。それでも、これらは議論の余地があります

毎週のプラットフォームニュース:AppleはWebコンポーネント、プログレッシブHTMLレンダリング、自己ホストの重要なリソースを展開しています毎週のプラットフォームニュース:AppleはWebコンポーネント、プログレッシブHTMLレンダリング、自己ホストの重要なリソースを展開していますApr 16, 2025 am 11:55 AM

今週のラウンドアップでは、AppleはWebコンポーネント、InstagramがどのようにInsta-Loadingスクリプトであるか、自己ホストの重要なリソースのための考えのための食べ物に入ります。

git pathspecsとそれらの使用方法git pathspecsとそれらの使用方法Apr 16, 2025 am 11:53 AM

gitコマンドのドキュメントを調べていたとき、それらの多くが選択肢があることに気付きました。私は当初、これはただのものだと思っていました

製品画像のカラーピッカー製品画像のカラーピッカーApr 16, 2025 am 11:49 AM

難しい問題のように聞こえます。私たちはしばしば、何千もの色で製品ショットを持っていないので、withをひっくり返すことができます。私たちもそうしません

ReactとThemeproviderを使用した暗いモードの切り替えReactとThemeproviderを使用した暗いモードの切り替えApr 16, 2025 am 11:46 AM

ウェブサイトにダークモードオプションがあるときが好きです。ダークモードにより、ウェブページが読みやすくなり、目がリラックスしているように感じます。を含む多くのウェブサイト

HTMLダイアログ要素を使用したいくつかの実践HTMLダイアログ要素を使用したいくつかの実践Apr 16, 2025 am 11:33 AM

これは私が初めてHTML要素を見ていることです。私はしばらくの間それを知っていましたが、まだスピンしていませんでした。かなりクールです

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。