إذا طبّقنا بضعة انتقالات (transitions) على عناصر الصفحة فقد تؤدي إلى نتيجة رائعة إذا خططنا لها جيدًا، وسنتعلم في هذا المقال كيف نستخدم الانتقالات لدب الحياة في محتوى الصفحة، وسنخطط ونبني تأثيرات مرور الفأرة فوق العناصر لتبدو بأجمل مظهر.
الانتقالات أم الحركات
الانتقالات (transitions) رائعة للانتقال بسلاسة من حالة إلى أخرى (والعودة إلى الحالة الأصلية مجددًا) في المتصفح، وقد تبدو أنها بديلٌ أبسط من الحركات (animation) التي تستعمل keyframes
و animation
، لكن لكلٍ ميزاتها وفوائدها.
فمثلًا، لن تستفيد من الانتقالات إذا كنت تريد حدوث حركة عند تحميل الصفحة، أو إذا أردتَ أن تستمر الحركة طوال الوقت؛ أما إذا كانت لديك حالتين وأردتَ التحريك بينهما بسهولة فستستفيد حينئذٍ من الانتقالات. إذا كنتَ مهتمًا بالفروقات بين الانتقالات والحركات فأنصحك بمراجعة هذه المقالة.
سنبني في هذا الدرس مشهدًا من الفضاء وسنضيف إليه تأثير مرور الفأرة فوقه لعرض بعض المعلومات الإضافية عن الكوكب، وسنفِّكر بحالتَي العناصر وما هي الخاصيات التي سنستخدمها للحصول على انتقال سلس وجميل. يمكنك الاطلاع على المثال الكامل لأخذ فكرة عن ما سنفعله.
ضبط الحالتين
أكثر الأمور التي تأخذ وقتًا وجهدًا عند إنشاء الانتقالات هي الحالة الأولية والحالة النهائية للعنصر، فيجب أن نُفكِّر كيف سيبدو العنصر قبل تطبيق الانتقال وماذا يجب أن يتغيّر في مظهره بعد حدوث الانتقال.
عندما أُنشِئ الانتقالات المعقدة نسبيًا فلا أهتم بالحركة نفسها إلى أن يعجبني مظهر العناصر في الحالتين، ومن هذا المنطلق فسنهتم بالخاصيات التي سنستخدمها في حالة hover
لأن هذه الخاصيات ستخضع إلى حركة.
قبل الخوض في موضوع الانتقالات فلنضبط الحالتين أولًا.
حالة البداية
سيكون كوكب الأرض في منتصف المشهد بدايةً، وسيدور القمر حوله.
شيفرة HTML تتضمن عنصر article الذي نضع فيه عنصرَي earth
و moon
، لاحظ أنَّ عنصر moon
موجود داخل حاوية باسم moon-container
لأنها ستساعدنا بموضع القمر لاحقًا.
<article class="earth-demo"> <div class="earth"> <img src="https://cssanimation.rocks/images/random/earth.png"> </div> <div class="moon-container"> <div class="moon"> <img src="https://cssanimation.rocks/images/random/moon.png"> </div> </div> </article>
هذه هي أنماط CSS التي سنستخدمها، سنجعل موضع العنصر earth
مساويًا للقيمة absolute
وسنستخدم الدالة calc
لتوسيط الأرض رأسيًا وأفقيًا.
.earth { position: absolute; top: calc(50% - 100px); left: calc(50% - 100px); }
وسنُحدِّد موضع الصورة ونعطيها طولًا وعرضًا:
.earth img { height: 200px; position: absolute; top: 0; left: 0; width: 200px; }
وسنفعل المثل تقريبًا للقمر، إذ سنبدأ بوضع الحاوية في منتصف الشاشة:
.moon-container { position: absolute; top: calc(50% - 25px); left: calc(50% - 25px); }
ثم سنضبط أبعاد القمر ونُطبِّق الحركة spin
عليه (والتي سنعرِّفها لاحقًا)، وهذا ما سيجعل القمر يدور حول الأرض.
.moon { animation: spin 20s linear infinite; background: none; height: 50px; pointer-events: none; transform-origin: 25px; width: 50px; }
عند هذه المرحلة سيكون القمر متموضعًا في منتصف الشاشة وفوق الأرض، لذا لنستخدم الخاصية transform
لتحريك القمر إلى خارج الحاوية الخاصة بعيدًا عن الأرض.
.moon img { height: 50px; transform: translateX(-160px) translateY(-160px); width: 50px; }
هذا يعني أنَّ عنصر moon
سيدور فوق الأرض، لكن الصورة ستدور حول الأرض.
لنضف الآن حواف مدورة للعنصر لكي تظهر حواف الأرض والقمر بدقة وسنستعمل الخاصية box-shadow
لإعطائهما توهجًا أزرقًا:
.earth img, .moon img { border-radius: 50%; box-shadow: 0 0 12em 1em rgba(110, 140, 200, .6); }
في النهاية، سنُعرِّف الحركة spin
لتدوير القمر، وهذه الحركة بسيطة، إذ سندوِّر القمر حول المحور Z بزاوية 360 درجة.
@keyframes spin { to { transform: rotateZ(360deg); } }
هذا هو ناتج هذه المرحلة:
عرض المزيد من المعلومات
نريد أن نظهر معلومات مفيدة حول كوكب الأرض عند مرور الفأرة فوقه، ربما ستساعد هذه المعلومات الفضائيين في معرفة بعض الأمور الأساسية عن كوكبنا قبل أن يزورونا :-) .
علينا قبل ضبط حالة hover
أن نضيف هذه المعلومات، وسنبدأ بإضافة عنصر div
ذي المعرِّف more-info
الذي يحتوي على بعض النصوص:
<article class="earth-demo"> <div class="earth"> <div class="more-info"> <h1>Earth</h1> <ul> <li>Third planet from the Sun</li> <li>Atmosphere: 21% oxygen</li> <li>Liquid water on surface</li> <li>Only planet that has life (that we know of)</li> </ul> </div> <img src="https://cssanimation.rocks/images/random/earth.png"> </div> <div class="moon-container"> <div class="moon"> <img src="https://cssanimation.rocks/images/random/moon.png"> </div> </div> </article>
أضفنا هذه المعلومات داخل حاوية earth
لأننا نريد جعلها جزءًا من التأثير، أي عند مرور الفأرة فوق النص فسيبقى على الشاشة.
سنضيف بعض أنماط CSS إلى عنصر more-info
:
.earth .more-info { background-image: linear-gradient(to bottom, rgba(10,10,10,1), black); border-radius: 1em; color: #fff; opacity: 0; padding: 1em; transform-origin: 0 0; transform: scale(.8); width: 400px; } .earth .more-info h1 { margin: 0 0 1em; text-align: right; }
ضبطنا هنا لون الخلفية والحواف المنحنية والحاشية وعرض العنصر، وغيّرنا قياسه قليلًا باستخدام transform
وضبطنا transform-origin
إلى الزاوية العليا اليسرى لكي يتغيّر قياسه بدءًا من تلك النقطة.
خاصية opacity
للعنصر more-info
تساوي الصفر أي أنَّ العنصر شفاف تمامًا ولن يكون مرئيًا، وقد نضيف الخاصية visibility
لكي نضمن أنَّ المحتوى لا يتداخل مع بقية العناصر، لكننا لن نفعل ذلك في مثالنا هذا.
إنشاء انتقال للخاصيات المطلوبة
عندما نضبط تأثير الانتقال فمن المهم أن نأخذ الأداء بالحسبان، فبعض الخاصيات مثل الارتفاع والحاشية (padding) وحجم الخط و background-position
لن يكون أداؤها جيدًا إذا أجرينا تأثير الانتقال عليها، والسبب وراء ذلك هو أنَّها تجعل المتصفح يُعيد حساب الكثير من التفاصيل في تخطيط الصفحة عندما تتغير.
لذا من الأفضل استخدام الخاصيتين opacity
و transform
عند إجراء حركات لأن أداءها جيد ولا تسبب «تعليق» في المتصفح.
سنستخدم في هذا المثال الخاصيتين opacity
و transform
إذ سيُصغَّر العنصر more-info
قليلًا باستخدام transform
وكان شفافًا تمامًا (قيمة opacity
تساوي الصفر).
أما في حالة hover
فسنغيّر شفافية العنصر more-info
لكي يصبح مرئيًا وسنزيح الكوكب إلى الجانب.
حالة مرور الفأرة فوق العناصر
لنبدأ بضبط حالة .earth:hover
، إذا كنتَ ستستخدم Sass فيمكنك اختصار الكثير من الشيفرات التي سنكتبها، لكنني سأستخدم CSS في هذا الدرس.
لنحرِّك الكوكب جانبًا بادئ الأمر:
.earth:hover img { transform: translateX(-75px) translateY(-75px) scale(.5); }
خاصية transform
السابقة ستدفع الكوكب إلى اليسار بمقدار 75 بكسل وستصغره إلى 50% من حجمه.
لنقم بشيءٍ مشابه إلى القمر:
.earth:hover ~ .moon-container { transform: translateX(-75px) translateY(-75px) scale(.5); } .earth:hover ~ .moon-container img { transform: translateX(-140px) translateY(-140px); }
نفّذنا خدعةً هنا إلى صورة القمر ألا وهي استخدام transform
لتقريبه إلى الأرض. لنُظهِر الآن العنصر more-info
:
.earth:hover .more-info { opacity: 1; transform: none; }
ضبطنا الشفافية إلى 1 وهذا يعني أنَّ العنصر أصبح ظاهرًا، وضبطنا الخاصية transform
إلى none
وهذا يعني أنَّ العنصر سيعود إلى حجمه الطبيعي.
هذه هي النتيجة الحالية، مرر الفأرة فوق الكوكب لتشاهد مربع المعلومات.
تطبيق تأثير الانتقال
لقد أنجزنا الأمور الصعبة، وكل ما بقي علينا لنفعل هو إخبار المتصفح كيف سيتنقل بين الحالتين. ولحسن الحظ لن نحتاج إلى كتابة شيفرات طويلة، وإنما يمكن فعل ذلك بخاصية CSS وحيدة:
.earth-demo * { transition: all 4s cubic-bezier(0,1.5,.3,1); }
لنشرح القاعدة السابقة بالتفصيل. تُطبَّق القاعدة السابقة على كل العناصر الموجودة داخل عنصر earth-demo
(وذلك باستخدام رمز النجمة *
).
ثم سنطبِّق تأثير الانتقال transition
لجميع الخاصيات بمدة 4 ثواني وباستخدام دالة التوقيت cubic-bezier
، وهذه الدالة ستبدأ بسرعة ثم تتباطأ حتى النهاية، وفي النهاية ستتخطى القيم المُحدَّدة في الحالة hover
ثم ستعود إلى القيم التي ضبطناها.
وقبل أن ننظر إلى النتيجة النهائية، فدعنا نضيف تأخيرًا بسيطًا إلى عناصر القائمة، فمن الجميل أن تظهر عناصر القائمة تلو بعضها بتأثيرٍ حركيٍ جميل. يمكننا فعل ذلك باستخدام الخاصية transition-delay
.
تأخير تأثير الانتقال
سنضبط بدايةً شفافية تلك العناصر إلى الصفر، أي سيكونوا غير مرئيين قبل أن يبدأ تأثير الانتقال.
.earth-demo h1, li { opacity: 0; }
وعندما يبدأ الحدث hover
فسنُظهرهم جميعًا:
.earth-demo:hover h1, li { opacity: 0; }
علينا الآن تأثير ظهور عناصر القائمة الأربعة، وذلك باستخدام المُحدِّد nth-child
:
.earth-demo:hover li:nth-child(1) { transition-delay: 0s; } .earth-demo:hover li:nth-child(2) { transition-delay: 0.2s; } .earth-demo:hover li:nth-child(3) { transition-delay: 0.4s; } .earth-demo:hover li:nth-child(4) { transition-delay: 0.6s; }
الشيفرة السابقة ستُضيف تأخيرًا إلى كل عنصرٍ من عناصر القائمة، ولأننا استخدمنا المُحدِّد *
فيما سبق فهذا يعني أنَّ كل عنصر من هذه العناصر سيُطبَّق عليه تأثير الانتقال، وكل ما علينا تحديده هو زمن التأخير.
هذه هي النتيجة النهائية:
لقد فعلناها! حركة معقدة نسبيًا أنجزناها باستخدام خاصية transition
وحيدة.
تعلمنا في هذا الدرس كيف نخطط ونبني مثالًا متكاملًا يستخدم الانتقالات لإنشاء حركات معقدة، وحرصنا أن تكون الانتقالات سلسلة وتبدو بشكلٍ جميل.
الخلاصة
الخدع البسيطة التي نقوم بها عبر الحركات والانتقالات هي التي تجعل موقعنا مميزًا وجميلًا
ترجمة –وبتصرّف– للمقال Transitions in space لصاحبه Donovan Hutchinson
أفضل التعليقات
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.