تُعدّ الحركة جزءًا أساسيًا من أي تجربة رقمية، إذ ترشد المستخدم من تفاعل إلى آخر. ولكن هناك بعض الفجوات في الرسومات المتحركة السلسة على منصة الويب. وتشمل هذه الميزات القدرة على تحريك الرسوم المتحركة للإدخال والخروج بسهولة، بالإضافة إلى التحريك بسلاسة من وإلى الطبقة العلوية للعناصر القابلة للتجاهل، مثل مربّعات الحوار والنوافذ المنبثقة.
لملء هذه الفجوات، يتضمّن الإصداران 116 و117 من Chrome أربع ميزات جديدة لمنصّة الويب، ما يتيح استخدام الرسوم المتحرّكة والانتقالات السلسة للمواقع المنفصلة.
تشمل هذه الميزات الأربعة الجديدة ما يلي:
- إمكانية إضافة رسوم متحركة إلى
display
وcontent-visibility
على مخطط زمني للإطارات الرئيسية (بدءًا من الإصدار 116 من Chrome) - سمة
transition-behavior
التي تحتوي على الكلمة الرئيسيةallow-discrete
لتفعيل عمليات النقل بين المواقع المنفصلة، مثلdisplay
(من الإصدار 117 من Chrome) - القاعدة
@starting-style
لتحريك تأثيرات الإدخال منdisplay: none
إلى الطبقة العلوية (من Chrome 117) - سمة
overlay
للتحكّم في سلوك الطبقة العليا أثناء عرض صورة متحركة (من Chrome 117)
عرض الصور المتحركة في الإطارات الرئيسية
اعتبارًا من الإصدار 116 من Chrome، يمكنك استخدام display
وcontent-visibility
في قواعد اللقطات الرئيسية. وسيتم تبديلها بعد ذلك في وقت تسجيل الإطار الرئيسي. لا يلزم استخدام قيم جديدة إضافية لإتاحة هذا الخيار:
.card {
animation: fade-out 0.5s forwards;
}
@keyframes fade-out {
100% {
opacity: 0;
display: none;
}
}
يعرض المثال السابق تأثيرًا متحركًا لمعدل الشفافية إلى 0 على مدار مدة 0.5 ثانية، ثم يضبط العرض على "بدون". بالإضافة إلى ذلك، تضمن الكلمة الرئيسية forwards
بقاء الحركة في حالتها النهائية، بحيث يظل العنصر الذي يتم تطبيقها عليه display: none
وopacity: 0
.
هذا مثال بسيط يحاكي ما يمكنك فعله باستخدام انتقال (راجِع العرض الترويجي في قسم الانتقال). ومع ذلك، لا يمكن للانتقالات إنشاء صور متحركة أكثر تعقيدًا، مثل المثال التالي:
.card {
animation: spin-and-delete 1s ease-in forwards;
}
@keyframes spin-and-delete {
0% {
transform: rotateY(0);
filter: hue-rotate(0);
}
80% {
transform: rotateY(360deg);
filter: hue-rotate(180deg);
opacity: 1;
}
100% {
opacity: 0;
display: none;
}
}
الحركة spin-and-delete
هي صورة متحركة عند الخروج. أولاً، ستدور البطاقة على محور y، وستتم إعادة ترتيب تدرّج الألوان، ثم في 80%
على المخطط الزمني، ستتم إزالة الشفافية من 1 إلى 0. أخيرًا، يتم تبديل البطاقة من display: block
إلى display: none
.
بالنسبة إلى الرسوم المتحركة للخروج، بدلاً من تطبيقها مباشرةً على عنصر، يمكنك إعداد مشغل للصور المتحركة. على سبيل المثال، من خلال إرفاق أداة معالجة أحداث بزر يؤدي إلى تنشيط فئة لتطبيق الصورة المتحركة، على النحو التالي:
.spin-out {
animation: spin-and-delete 1s ease-in forwards;
}
document.querySelector('.delete-btn').addEventListener('click', () => {
document.querySelector('.card').classList.add('spin-out');
})
يحتوي المثال أعلاه الآن على حالة نهاية display:none
. هناك العديد من الحالات التي قد تحتاج فيها إلى مزيد من الخطوات وإزالة عقدة DOM مع مهلة للسماح بإنهاء الحركة أولاً.
نقل الصور المتحركة المنفصلة
على عكس الرسوم المتحركة للخصائص المنفصلة باستخدام الإطارات الرئيسية، عليك استخدام وضع سلوك النقل allow-discrete
لنقل الخصائص المنفصلة.
سمة transition-behavior
يُتيح وضع allow-discrete
إجراء التحولات المنفصلة، وهو قيمة لسمة transition-behavior
. تقبل الدالة transition-behavior
قيمتَين: normal
وallow-discrete
.
.card {
transition: opacity 0.25s, display 0.25s;
transition-behavior: allow-discrete; /* Note: be sure to write this after the shorthand */
}
.card.fade-out {
opacity: 0;
display: none;
}
يحدّد الاختصار transition
هذه القيمة أيضًا، لذا يمكنك حذف السمة واستخدام الكلمة الرئيسية allow-discrete
في نهاية الاختصار transition
لكل انتقال بدلاً من ذلك.
.card {
transition: opacity 0.5s, display 0.5s allow-discrete;
}
.card.fade-out {
opacity: 0;
display: none;
}
إذا كنت تضيف تأثيرًا متحركًا إلى عدة عناصر منفصلة، عليك تضمين allow-discrete
بعد كل عنصر تريد إضافة تأثير متحرك إليه. على سبيل المثال:
.card {
transition: opacity 0.5s, display 0.5s allow-discrete, overlay 0.5s allow-discrete;
}
.card.fade-out {
opacity: 0;
display: none;
}
قاعدة @starting-style
للصور المتحركة عند الدخول
حتى الآن، غطّت هذه المقالة الرسوم المتحرّكة للخروج، ولإنشاء الرسوم المتحرّكة للدخول، عليك استخدام القاعدة @starting-style
.
استخدِم @starting-style
لتطبيق نمط يمكن للمتصفّح البحث عنه قبل فتح العنصر على الصفحة. هذه هي حالة "قبل الفتح" (حيث تبدأ الصورة المتحركة).
/* 0. IS-OPEN STATE */
/* The state at which the element is open + transition logic */
.item {
height: 3rem;
display: grid;
overflow: hidden;
transition: opacity 0.5s, transform 0.5s, height 0.5s, display 0.5s allow-discrete;
}
/* 1. BEFORE-OPEN STATE */
/* Starting point for the transition */
@starting-style {
.item {
opacity: 0;
height: 0;
}
}
/* 2. EXITING STATE */
/* While it is deleting, before DOM removal in JS, apply this
transformation for height, opacity, and a transform which
skews the element and moves it to the left before setting
it to display: none */
.is-deleting {
opacity: 0;
height: 0;
display: none;
transform: skewX(50deg) translateX(-25vw);
}
لديك الآن حالة دخول وخروج لعناصر قائمة "المهام التي يجب إكمالها" هذه:
إضافة تأثيرات متحركة إلى العناصر ونقلها من الطبقة العليا
لإضافة تأثيرات متحركة للعناصر من الطبقة العليا وإليها، حدِّد الرمز @starting-style
في الحالة "مفتوح" لإعلام المتصفّح من أين يبدأ تأثير الحركة. بالنسبة إلى مربّع الحوار، يتم تحديد الحالة المفتوحة باستخدام السمة [open]
. بالنسبة إلى النافذة المنبثقة، استخدِم الفئة الزائفة :popover-open
.
يمكن أن يظهر مثال بسيط لمربّع حوار على النحو التالي:
/* 0. IS-OPEN STATE */
dialog[open] {
translate: 0 0;
}
/* 1. BEFORE-OPEN STATE */
@starting-style {
dialog[open] {
translate: 0 100vh;
}
}
/* 2. EXIT STATE */
dialog {
transition: translate 0.7s ease-out, overlay 0.7s ease-out allow-discrete, display 0.7s ease-out allow-discrete;
translate: 0 100vh;
}
في المثال التالي، يختلف تأثيرا الدخول والخروج. يمكنك الدخول من خلال تحريك الصورة المتحركة للأعلى من أسفل إطار العرض، والخروج من التأثير إلى أعلى إطار العرض. ويتم أيضًا كتابتها باستخدام CSS متداخلة لمزيد من الحِزم المرئية.
عند إضافة تأثيرات متحركة إلى نافذة منبثقة، استخدِم الفئة الزائفة :popover-open
بدلاً من السمة open
المستخدَمة سابقًا.
.settings-popover {
&:popover-open {
/* 0. IS-OPEN STATE */
/* state when popover is open, BOTH:
what we're transitioning *in* to
and transitioning *out* from */
transform: translateY(0);
opacity: 1;
/* 1. BEFORE-OPEN STATE */
/* Initial state for what we're animating *in* from,
in this case: goes from lower (y + 20px) to center */
@starting-style {
transform: translateY(20px);
opacity: 0;
}
}
/* 2. EXIT STATE */
/* Initial state for what we're animating *out* to ,
in this case: goes from center to (y - 50px) higher */
transform: translateY(-50px);
opacity: 0;
/* Enumerate transitioning properties,
including display and allow-discrete mode */
transition: transform 0.5s, opacity 0.5s, display 0.5s allow-discrete;
}
overlay
الموقع الإلكتروني
أخيرًا، لإخفاء popover
أو dialog
من الطبقة العليا، أضِف السمة overlay
إلى قائمة الانتقالات. يتخطى popover
وdialog
المقاطع وتحويلات الأصل، ويتم أيضًا وضع المحتوى في الطبقة العلوية. إذا لم تنقل العنصر overlay
، سيعود إلى القطع والتحويل والتغطية على الفور، ولن ترى عملية النقل تحدث.
[open] {
transition: opacity 1s, display 1s allow-discrete;
}
بدلاً من ذلك، يمكنك تضمين overlay
في الانتقال أو الحركة لتحريك overlay
مع بقية الميزات والتأكّد من بقائها في الطبقة العليا عند تحريكها. سيبدو هذا الإجراء أكثر سلاسة.
[open] {
transition: opacity 1s, display 1s allow-discrete, overlay 1s allow-discrete;
}
بالإضافة إلى ذلك، عندما يكون لديك عناصر متعددة مفتوحة في الطبقة العليا، يساعدك التراكب في التحكّم في الانتقال السلس من الطبقة العليا والعكس. يمكنك معرفة الفرق في هذا المثال البسيط. إذا لم تكن تطبّق overlay
على النافذة المنبثقة الثانية عند نقلها للخارج، ستنتقل أولاً من الطبقة العليا، وستقفز خلف النافذة المنبثقة الأخرى، قبل بدء عملية النقل. هذا التأثير ليس سلسًا جدًا.
ملاحظة حول عمليات النقل في العرض
إذا كنت تُجري تغييرات على نموذج DOM، مثل إضافة عناصر وإزالتها من نموذج DOM، يمكنك استخدام عمليات انتقال العرض كحلّ آخر رائع للرسوم المتحركة السلسة. في ما يلي مثالان من الأمثلة أعلاه تم إنشاؤهما باستخدام انتقالات العرض.
في هذا العرض التوضيحي الأول، ستعالج انتقالات العرض عملية النقل، بدلاً من إعداد @starting-style
وعمليات تحويل CSS الأخرى. يتم إعداد انتقال العرض على النحو التالي:
أولاً، في CSS، امنح كل بطاقة view-transition-name
فرديًا.
.card-1 {
view-transition-name: card-1;
}
.card-2 {
view-transition-name: card-2;
}
/* etc. */
بعد ذلك، في JavaScript، عليك لفّ عملية تغيير DOM (في هذه الحالة، إزالة البطاقة) في عملية انتقال عرض.
deleteBtn.addEventListener('click', () => {
// Check for browser support
if (document.startViewTransition) {
document.startViewTransition(() => {
// DOM mutation
card.remove();
});
}
// Alternative if no browser support
else {
card.remove();
}
})
أما الآن، فيمكن للمتصفح التعامل مع التلاشي للخارج والتغير في كل بطاقة إلى موضعها الجديد.
ويمكنك الاستفادة من هذه الميزة أيضًا في عرض إضافة/إزالة عناصر القائمة. وفي هذه الحالة، عليك إضافة view-transition-name
فريد لكل بطاقة يتم إنشاؤها.
الخاتمة
تنقلُنا ميزات المنصة الجديدة هذه خطوةً أقرب إلى إضافة مؤثرات متحركة سلسة للدخول والخروج على منصة الويب. لمزيد من المعلومات، راجع الروابط التالية: