تُعدّ الحركة جزءًا أساسيًا من أي تجربة رقمية، إذ ترشد المستخدم من تفاعل إلى آخر. ولكن هناك بعض الفجوات في الرسومات المتحركة السلسة على منصة الويب. وتشمل هذه الميزات إمكانية إضافة صور متحركة بسهولة إلى مؤثرات الدخول والخروج، وإضافة صور متحركة بسلاسة إلى الطبقة العليا من العناصر التي يمكن إغلاقها، مثل مربّعات الحوار والنوافذ المنبثقة.
لسدّ هذه الفجوات، يتضمّن الإصداران 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
فريد لكل بطاقة تم إنشاؤها.
الخاتمة
تنقل ميزات المنصة الجديدة هذه خطوة أقرب إلى توفير صور متحركة سلسة للدخول والخروج على منصة الويب. لمزيد من المعلومات، يمكنك الاطّلاع على الروابط التالية: