دروس متقدمة في CSS

الرسوم المتحركة animations في CSS

هل تصدق أن بإمكانك إنشاء تطبيقات متحركة بإستخدام CSS فقط ؟!

تقديم

كتب هذا المقال أشرف عبدالدايم مطور واجهة المستخدم في TieLabs سابقاً، 95% من كود CSS الموجود في قالب جنة من كتابة أشرف :)

قبل إضافة الخاصية animation للغة CSS كانت جميع عناصر صفحة الويب تظهر بشكل ثابت بدون أي حركة، وكنا عندما نريد إضافة حركة لبعض عناصر الصفحة نلجأ دائماً لإستخدام لغة Javascript (إحدى التقنيات الثلاثة الأساسية للويب – HTML / CSS / Javascript) ويتم هذا بربط احدى مكتبات Javascript في صفحة الويب (من أشرهم على الإطلاق مكتبة jQuery) أو أحدى المكتبات الأخرى المتخصصة في حركة العناصر. وفي كل حال مزيد من الملفات المربوطة بصفحة الويب، ومزيد من الأكواد، يعني زيادة في وقت تحميل الصفحة، وهذا ما نسعى دائماً لتحسينه.

بعد إضافة خاصية animation للغة CSS أصبح من الممكن الإستغناء عن لغة Javascript (فيما يخص الجزء المتعلق بحركة العناصر فقط، فلغة Javascript لها العديد من الوظائف الأخرى التي يجعل من الصعب استغناء صفحة الويب عنها، فهي لغة البرمجة الأكثر استخداماً الآن).

عقل الإنسان دائماً ما يعطي إنتباه زائد للأجزاء المتحركة. وبسبب هذا الإنعكاس الطبيعي لملاحظة الحركة، فإن إضافة حركة للأجزاء الهامة في صحفة الويب هو بمثابة طريقة قوية لجذب إنتباه زوار موقعك لهذة الأجزاء.

عند إضافة تأثيرات الحركة لموقعك بشكل جيد، ستقوم بإضافة تفاعل قيم بين صفحة الويب وزوار موقعك، وهذا ما يجعل زائر الصفحة يشعر وكأنه يتعامل مع شخص أخر يتفاعل معه لا صفحة ويب جامدة. في الحقيقة الأجزاء المتحركة في صفحة الويب تضفي معنى من الحياة لهذة الصفحة.

في مقال سابق تحدثنا عن الخاصية transition وهي أيضاً متعلقة بحركة العناصر، فما الفرق بينها وبين الخاصية animation؟

الخاصية transition هي طريقة لتحريك العناصر من حالة لأخرى (من حالة البداية إلى حالة النهاية) إذا فهي نوع محدد من الخاصية animation، حيث:

  • لديها حالتين فقط، حالة البداية وحالة النهاية.
  • لا يمكنك تكرار الحركة.
  • لا يمكنك التحكم في الحالات البينة بين حالة البداية وحالة النهاية إلإ بإستخدام دالة نوع الحركة Timing Function فقط.

لكن ماذا لو كنت تريد:

  • التحكم في حركة الحالات البينية؟ أي عندما تكون الحركة في المنتصف مثلاً نقوم بتغير خصائص معينة للعنصر، ليس فقط في بداية الحركة أو نهايتها.
  • تكرار حركة العنصر، والتحكم في عدد مرات التكرار؟
  • حركات مختلفة لنفس العنصر؟
  • أنواع حركات مختلفة Timing Functions لخصائص مخلتفة؟

كل هذة الأشياء وأكثر يمكن للخاصية animation تحقيقها بكل سهولة، لك أن تتخيل أن الخاصيةanimation عبارة عن فيلم قصير، وأنت مخرج هذا الفيلم الذي يقوم بإعطاء الأوامر (CSS Rules) للمثلين (عناصر HTML) لتنفيذ المشاهد المختلفة (keyframes).

في هذا المقال سنقوم بتوضيح المفاهيم الأساسية لتأثير الحركة في CSS من خلال شرح الخصائص المتعلقة بالخاصية animation

بناء الرسوم المتحركة

بناء الرسوم المتحركة في CSS يتكون من جزئين أساسين:

  1. القاعدة @keyframes : تتحكم في مراحل الحركة والخصائص التي سيتم تحريكها.
  2. خصائص الحركة Animation Properties: بإضافة إسم القاعدة @keyframes لعنصر محدد وتحديد كيفية إتمام الحركة.

دعنا نلقي نظرة على كل منهما على حده.

الجزء الاول: القاعدة @keyframes

القاعدة @keyframes هي أساس الرسوم المتحركة في CSS، فهي تحدد كيف ستبدو الحركة في كل مرحلة في الخط الزمني للحركة، كل قاعدة @keyframes تتكون من:

  1. إسم الحركة: اسم وصفي للحركة، على سبيل المثال bouncing.
  2. مراحل الحركة: كل مرحلة من مراحل الحركة يتم تمثيلها بالنسبة المئوية، 0% تعني بداية الحركة، 50% تعني منتصف الخط الزمني للحركة، 100% تعني نهاية الحركة، ويمكنك إضافة مراحل بينية كما تشاء.
  3. خصائص العنصر: خصائص CSS التي سيتم إضافتها لكل مرحلة من الحركة على الخط الزمني للحركة.

دعنا نلقي نظرة على كيفية استخدام القاعدة @keyframes، قمنا بتسميتها بالإسم bouncing على سبيل المثال، وهذة القاعدة لديها ثلاثة مراحلة، المرحلة الأولى ( 0% ) ، يكون العنصر بدرجة شفافية صفر (غير مرئي) وتم تقليص حجمة لعشر حجمه الأصلي بإستخدام التصريح transfrom: scale(0.1). المرحلة الثانية ( 60% ) سيظهر العنصر بشكل تدريجي (fade) لتصبح درجة الشفافية ١ (أي مرئي بشكل كامل) وزيادة ججمة بنسبة ١.٢ من حجمه الأصلي، في المرحلة الثالثة والأخيرة ( 100% )  سيتم تقليصه مرة ثانية لحجمه الأصلي.

يتم إضافة القاعدة @keyframes إلى ملف التنسيق لديك، كالتالي:

See the Pen animation #1 by Ashraf Reda (@ashrafreda) on CodePen.

لاحظ أن العنصر إلى الآن يظهر بشكل ثابت، دعنا ننتقل للجزء التالي لنتعرف على كيفية ربط القاعدة @keyframes بباقي خصائص الحركة.

إذا لم تكن على دراية بالخاصية transfrom يمكنك مراجعة المقال الخاص بها من هنا.حيث أن استخدام الخاصية transfrom مع الرسوم المتحركة في CSS يعطينا نتائج رائعة.

الجزء الثاني: خصائص الحركة Animation Properties

بعد أن قمت بتعين القاعدة @keyframes، إذا يجب إضافة خصائص الحركة لكي تعمل الرسوم المتحركة، خصائص الحركة تقوم بوظيفتين:

  1. تقوم بتعيين إسم القاعدة @keyframes التي قمنا بتعريفها من قبل وسنقوم بإستخدامها على العنصر المُراد تطبيق الحركة عليه.
  2. تقوم بتحديد كيفية إتمام هذة الحركة (مدة الحركة، مدة الإنتظار، منحنى الحركة، عدد مرات التكرار، وهكذا..).

هناك العديد من الخصائص المتعلقة بالرسوم المتحركة، لكن يجب عليك بشكل إلزامي إضافة هاتين الخاصيتين كي تعمل الحركة:

  1. خاصية إسم الحركة animation-name : إسم الحركة الذي تم تعينه مع القاعدة @keyframes.
  2. خاصية مدة الحركة animation-duration : مدة الحركة بالثانية (مثل 5s) أو المللي ثانية (مثل 5000ms).

وإتماماً للمثال السابق، نريد تطبيق الحركة المسماه بـ bouncing على العنصر <h1>، سنقوم بإضافة الخصائص الإلزامية animation-name و animation-duration للعنصر كالتالي:

أو بالخاصية المختصرة animation كالتالي:

بإضفة القاعدة @keyframes وخصائص الحركة، ستكون النتيجة كالتالي: (حيث أن الحركة لا تتكرر، إضغط على الزر Return لإعادة تشغيلها مرةً ثانية)

See the Pen animation #2 by Ashraf Reda (@ashrafreda) on CodePen.

مثل الخاصية transition، فإن الخاصية animation عبارة عن اختصار لمجموعة متعددة من خواص الحركة الأخرى:

  • animation-name : إسم الحركة.
  • animation-duration : إلى متى ستستمر الحركة (مدة الحركة).
  • animation-timing-function : كيف سيتم حساب الحالات البينية (نوع أو شكل الحركة خلال خط الزمن).
  • animation-delay : عندما تريد بداية الحركة بعد مدة زمنية محددة (فترة إنتظار).
  • animation-iteration-count : عدد مرات تكرار الحركة.
  • animation-direction : يحدد إتجاة الحركة (في أي اتجاة سيتم قراءة المراحل داخل القاعدة @keyframes ).
  • animation-fill-mode : أي التنسيقات سيتم تطبيقها قبل بداية الحركة وبعد نهايتها.

الخاصية animation المختصرة

يمكنك استخدام كل خاصية من خصائص الحركة بكشل منفرد، لكن من أجل الإختصار والسرعة في كتابة الأكواد يفضل دائماً إستخدام الخصائص المختصرة، يمكنك دمج كل خصائص الحركة في الخاصية animation المختصرة هكذا:

ولكي تعمل الحركة يجيب ترتيب الخواص هكذا، وتعيين قيم أول خاصيتين على الأقل.

مثال

تخيل زر التحميل التالي:

See the Pen animation #3 by Ashraf Reda (@ashrafreda) on CodePen.


تخيل شكل الزر في المثال السابق! زر ثابت، لا يوحي بأي معنى سوى كلمة “تحميل…” ماذا لو قمنا بتطبيق نوع من الحركة يوحي بأنه زر تحميل، هكذا:

See the Pen animation #4 by Ashraf Reda (@ashrafreda) on CodePen.


لقد اختلف الأمر كثيراً، لقد أضفى تأثر الحركة نوع من الحياة على العنصر، لقد جذب المزيد من الإنتباه.

في المثال السابق، قمنا باستخدام الخاصية المختصرة animation التي تتضمن الخصائص التالية:

  • animation-name : إسم الحركة، في هذا المثال bouncing
  • animation-duration : نصف ثانية 0.5s
  • animation-timing-function : الدالة  cubic-bezier(0.1,0.25,0.1,1) 
  • animation-delay : بدون انتظار 0s
  • animation-iteration-count : تكرار إلى ما لا نهاية infinite
  • animation-direction : ذات القيمة alternate وتعني الحركة بطريقة سلسه ذهاباً وإياباً.
  • animation-fill-mode : ذات القيمة both.

تتكون الحركة في هذا المثال على مرحلتين فقط، المرحلة الأولى ( 0% ) بُعد العنصر عن الحافة السفلى لمكانة الأصلي هو صفر، وتعين ظل للزر بمقدار 5px، المرحلة الثانية، نقوم بجذب العنصر لأعلى عن مكانه الأصلي بمقدار 30px باستخدام الخاصية bottom وزيادة الظل للمقدار 50px.

مثال آخر

في المثال التالي سنقوم بإضافة تأثير التساقط على النص، ليظهر بالشكل التالي:

See the Pen animation #5 by Ashraf Reda (@ashrafreda) on CodePen.

تتكون الحركة في المثال السابق من ستة مراحل (يمكنك استخدام نفس الخصائص لأكثر من مرحلة بفصل المراحل بفاصلة):

  • المرحلة الأولى (البداية from ) والمرحلة الثانية ( 15% ): تعيين درجة دوران العنصر 0 ومقدار تحريكة على المحور X جهة اليسار 0.
  • المرحلة الثالثة ( 50% ) والمرحلة الرابعة ( 60% ): تعيين درجة الدوران 90deg في عكس اتجاه عقارب الساعة، ومقدار تحركه على المحور X لجهة اليسار 0.
  • المرحلة الخامسة ( 85% ) والمرحلة السادسة ( النهاية to ): الإستمرار بدرجة الدوران 90deg في عكس اتجاه عقارب الساعة، ومقدار تحركه على المحور X لجهة اليسار 200px (لاحظ أن العنصر تم دورانه بمقدار ٩٠ درجة أي أنه سيتحرك للأسفل بدلاً من اليسار).

 

١- الخاصية animation-name

الخاصية animation-name تستخدم على الأقل مرتين، عند كتابة أكواد الحركة بإستخدام القاعدة @keyframes وعند تعيين اسم الحركة للعنصر المُراد تحريكه بإستخدام الخاصية animation-name أو الخاصية المختصرة animation.

القيمة الإفتراضية لها none وهذا يعني أنه في حالة عدم تعيين إسم الحركة يسظهر العنصر بدون حركة.

مثل أسماء الكلاسس في CSS فإن إسم الحركة يجب أن يحتوي فقط على الأحرف (من a إلى z) الأرقام (من 0 إلى 9) الشرطة السفلية (_) الشرطة العادية (-) ولا يمكن أن تبدأ برقم أو شرطتين (–).

٢- الخاصية animation-duration

تماماً مثل الخاصية transition-duration تمكنك من تحديد المدة الزمنية للحركة، بالثانية s أو المللي ثانية ms

القيمة الإفتراضية لها 0s وهذا يعني أن العنصر سيظهر بدون حركة.

٣- الخاصية animation-timing-function

أيضاً مثل الخاصية transition-timing-function  تقوم بتحديد منحنى السرعة أو كيفية الحركة من مرحلة لآخرى، يمكنك تحديد قيمة الخاصية بواحدة من إحدى القيم المُعرفة مسبقاً ( ease, linear, ease-in, ease-out, ease-in-out, inherit ) أو بإستخدام الدالة cubic-bezier لإنشاء منحنيات مخصصة بخيارات متقدمة.

See the Pen animation #6 by Ashraf Reda (@ashrafreda) on CodePen.

القيمة الإفتراضية (في حالة عدم تعين قيمة أخرى) هي ease حيث تبدأ الحركة بسرعة بطيئة، ثم تزداد، ثم تنتهي ببطئ كما بدأت، يمكنك الإطلاع على كيفية عمل كل قيمة من القيم المُعرف مسبقاً للخاصية  transition-timing-function  من هنا.

يمكنك تعيين قيمة الخاصية منفرده هكذا:

أو من خلال الخاصية المختصرة animation هكذا:

٤- الخاصية animation-delay

تمكنك الخاصية animation-delay من تحديد متى ستبدأ الحركة (أو متى سيبدأ جزء معين من الحركة)، أي ستحدد فترة الإنتظار قبل بدء الحركة.

إذا تم تعيين قيمة موجبة ( مثلاً 2s ) سيتم الإنتظار ثانيتن قبل بدء الحركة، أي أن العنصر سيظل بدون حركة حتى إنتهاء مدة الإنتظار (2s). وإذا تم تعيين قيمة سالبة ( مثل -2s ) سيتم بدء الحركة على الفور، لكن ستبدأ بعد ثانيتن من بدء الحركة.

See the Pen animation #7 by Ashraf Reda (@ashrafreda) on CodePen.

يمنكك مشاهدة هذا المثال التطبيقي على شبكة مطورين موزيلا، وتكون صيغتها كالتالي:

أو من خلال القيمة المختصر animation:

٥- الخاصية animation-iteration-count

تقوم الخاصية animation-iteration-count بتحديد عدد مرات تكرار الحركة، وتكون القيمة واحدة من التالي:

  • رقم صحيح (القيمة الإفتراضية هي 1)
  • القيمة infinite أي أن الحركة سيتم تكرارها إلى ما لا نهاية.
  • القيمة initial لتعين القيمة الإفتراضية.
  • القيمة inherit لوراثة القيمة من العنصر الأب.

See the Pen animation iteration count by Ashraf Reda (@ashrafreda) on CodePen.


وتكون الصيغة كالتالي:

أو من خلال القيمة المختصرةanimation:

٦- الخاصية animation-direction

تحدد الخاصية animation-direction في أي ترتيب سيتم قراءة قاعدة @keyframes، وبالتالي ستحدد اتجاه الحركة:

  • normal : تبدأ من 0% وتنتهي عند 100% ثم بتدأ ثانية من 0%.
  • reverse : (عكس القيمة normal) تبدأ من 100% وتنتهي عند 0% ثم بتدأ ثانية من 100%.
  • alternate : تبدأ من 0% متجهه إلى 100% ثم تتجه ثانية إلى 0%.
  • alternate-reverse : (عكس القيمة alternate) تبدأ من 100% متجهه إلى 0% ثم تتجه ثانية إلى 100%.

دعنا نلقي نظرة على المثال التالي ليتضح الأمر جيداً:

See the Pen animation direction by Ashraf Reda (@ashrafreda) on CodePen.


وتكون الصيغة كالتالي:

أو من خلال القيمة المختصرة animation:

٧- الخاصية animation-fill-mode

تحدد الخاصية animation-fill-mode ماذا سيحدث قبل بداية الحركة وبعد أن تنتهي.

عندما تقوم بتعيين القاعدة @keyframes تحدد داخلها قواعد CSS لكل مرحلة من مراحل الحركة، الآن قواعد CSS هذة يمكنها الإشتباك مع التنسيق الإفتراضي للعنصر.

دعنا نتخيل أن لدينا الزر التالي:

  • لونه أحمر بشكل إفتراضي.
  • نقوم بتغير لونه للون الأزرق عند بداية الحركة.
  • نقوم بتغير لونه للون الأخضر عند نهاية الحركة.

عند تطبيق الخاصية animation-fill-mode مع حركة الزر، يتغير لون الزر طبقاً للجدول التالي مع كل قيمة من قيم الخاصية:

إليك المثال التالي (قم بالضغط على الزر Return لإعادة تشغيل الحركة)

See the Pen animation fill mode by Ashraf Reda (@ashrafreda) on CodePen.

لاحظ الحركة فور الضغط على الزر return

قارن العناصر بالجدول بالإعلى بالعناصر في المثال، ستجد أن العنصر الأول يظهر قبل بداية الحركة باللون الإفتراضي (الأحمر) ثم يتحول إلى اللون (الأزرق) عند بداية الحركة ثم يتحول إلى (الأخضر) عند نهاية الحركة ثم يعود مرةً ثانية للون الإفترضي (الأحمر) بعد نهاية الحركة.

٨- الخاصية animation-play-state

بإستخدام الخاصيةanimation-play-state يمكنك تشغيل الحركة (إذا كانت في وضع التوقف paused ) أو إيقافها مؤقتاً (إذا كانت في وضع التشغيل playing ). ولها قيمتين:

  • القيمة playing : الرسوم المتحركة قيد التشغيل حالياً.
  • القيمة paused : الرسوم المتحركة متوقفه مؤقتاً حالياً.
عند إيقاف الحركةpaused ، يحتفظ العنصر بجميع خصائصة والتنسيقات المُطبقة عليه قبل إيقاف الحركة مباشرةً، أي أن العنصر سيتوقف عن الحركة في الوضع الأخير له مهما كانت القيمة التي وصلت إليها الحركة. ويمكنك ملاحظة أن كلمةpaused تعني إيقاف مؤقت، أي عندما تقوم بتشغيل الحركة مرةً ثانية سُكمل العنصر حركته من أخر وضع توقف عليه.

إليك المثال التالي:

See the Pen Animation Play State by Ashraf Reda (@ashrafreda) on CodePen.

عند تمرير المؤشر على الساعة، ستتوقف الساعة مؤقتاً، ثم تُعاود الدوران عند إبعاد المؤشر عن الساعة من أخر حركة توقفت عندها ( لو توقف مؤشر الثواني عند الثانية ٣٠ مثلاً، سيكمل الدوران بعد ذلك من الثانية ٣٠ أيضاً.

لاحظ كيف استخدمنا الخاصية animation-play-state لإقاف دوران عقارب الساعة في حالة مرور المؤشر على الساعة :hover

تطبيق أكثر من حركة على نفس العنصر Multiple Animations

لإضافة حركات متعدد لنفس العنصر، قم بالفصل بين الحركات المتعددة بعلامة الفصلة ( , ) مثال لذلك:

في هذا المثال سيتم تطبيق حركتين منفصلتين في نفس الوقت:

  • الحركة الأولى: إسم الحركة animX وتستغرق مدة 4s وباقي الخصائص يتم استخدام القيم الإفتراضية لها.
  • الحركة الثانية: إسم الحركة animY وتستغرق مدة 4s وباقي الخصائص يتم استخدام القيم الإفتراضية لها.

See the Pen CSS Multiple Animations by Ashraf Reda (@ashrafreda) on CodePen.

ملاحظات وتوضيحات

لاحظ أن كثير من الخصائص التي تم إضافتها في الإصدار الثالث من CSS يختلف دعمها من متصفح لآخر، وكل متصفح يستخدم لاحقة Prefix خاصة به، وكي نضمن تطبيق الخاصية على جميع المتصفحات يجب تكررار الخاصية بلاحقة كل متصفح. لكن على سبيل التبسيط سنقوم باستخدام الخاصية القياسية فقط. ويمكنك معرفة، هذة قائمة بلاواحق المتصفحات المختلفة

  • المتصفح Chrome : اللاحقة -webkit-
  • المتصفح Safari : اللاحقة -webkit-
  • المتصفح Firefox : اللاحقة -moz-
  • المتصفح Internet Explorer : اللاحقة -ms-
  • المتصفح Opera : اللاحقة -o-

وتستخدم كالتالي:

هذا الموقع يوضح الخواص التي مازالت تحتاج إلى لواحق والخصائص التي أصبحت قياسية على جميع المتصفحات ويمكنك استخدامها بدون لواحق.

لاحظ أنه في حالة استخدام اللواحق مع القاعدة @keyframes ستكون صيغتها كالتالي:

أشرف عبدالدايم

مصري، أب، مطور واجهة المستخدم في TieLabs سابقاً، أحب كتابة المقالات التعليمة وأشعر أنها واجب على كل المهتمين بالمجال، حتى يتم توفير محتوى عربي لائق يساهم بشكل فعال في بناء جيل من المطورين والمبرمجين والمصميمن تعلّم بطريقة صحيحة منذ بداية رحلته التعليمية.
زر الذهاب إلى الأعلى
إغلاق