الانتقالات (Transitions) — CSS المتقدم
الانتقالات (Transitions)
بدون انتقال، تغيّر القيمة (عند المرور مثلاً) فوري ومفاجئ. الانتقال يجعل المتصفح يحسب القيم الوسيطة خلال مدة تحددها.
الصيغة
.btn {
background: hsl(224 71% 40%);
transition: background-color 200ms ease-out;
}
.btn:hover {
background: hsl(224 71% 32%);
}transition: <الخاصية> <المدة> <منحنى التوقيت> <التأخير>
أين تُكتب؟ على الحالة الأساسية
إذا كتبت transition داخل :hover فقط، يكون الدخول سلساً والخروج مفاجئاً (لأن الحالة الأساسية بلا انتقال). اكتبه على العنصر نفسه ليعمل في الاتجاهين.
عدة خصائص
.card {
transition:
translate 250ms ease-out,
box-shadow 250ms ease-out;
}
.card:hover {
translate: 0 -4px;
box-shadow: 0 12px 24px rgb(0 0 0 / 12%);
}تجنب transition: all: يحرّك خصائص لم تقصدها (وقد يحرك تغييرات التخطيط فيكون بطيئاً)، ويصعّب التنبؤ.
منحنيات التوقيت
| المنحنى | الإحساس | الاستخدام |
|---|---|---|
| ease | بداية سريعة ونهاية هادئة (الافتراضي) | عام |
| ease-out | يبدأ سريعاً ويتباطأ | عناصر تدخل الشاشة، استجابة للمستخدم |
| ease-in | يبدأ بطيئاً ويتسارع | عناصر تغادر |
| ease-in-out | بطيء-سريع-بطيء | حركة من مكان لمكان |
| linear | ثابت | الدوران المستمر، أشرطة التقدم |
| cubic-bezier(...) | مخصص (أدوات المطور فيها محرر) | ارتداد خفيف وغيره |
المدة المناسبة
- تفاعلات صغيرة (hover، أزرار): 150–250ms.
- عناصر أكبر (قوائم، نوافذ): 250–400ms.
- أطول من 500ms يشعر المستخدم بالبطء. الحركة يجب أن توضح ما حدث لا أن تؤخر المستخدم.
ما الذي يمكن تحريكه؟
الخصائص ذات القيم الوسيطة: الألوان، الأطوال، الشفافية، التحويلات، الظلال. أما display و font-family فتتغير فوراً. (المتصفحات الحديثة أضافت transition-behavior: allow-discrete و @starting-style لتحريك الظهور من display: none — دعمها يتحسن.)
خط سفلي متحرك للروابط (بأداء جيد)
.nav-link {
position: relative;
}
.nav-link::after {
content: "";
position: absolute;
inset-inline: 0;
bottom: -2px;
height: 2px;
background: currentColor;
scale: 0 1; /* بدل width: 0 */
transform-origin: inline-start; /* يبدأ من بداية السطر (اليمين في العربية) */
transition: scale 250ms ease-out;
}
.nav-link:hover::after,
.nav-link:focus-visible::after {
scale: 1 1;
}تحريك scale بدل width لا يعيد حساب التخطيط، والخصائص المنطقية تجعله يبدأ من الجهة الصحيحة في العربية.
احترم تفضيل تقليل الحركة
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
transition-duration: 0.01ms !important;
}
}تمرين
أضف انتقالات لأزرار صفحتك (لون الخلفية 200ms)، ولبطاقات المشاريع (ارتفاع وظل 250ms)، وخطاً سفلياً متحركاً لروابط القائمة يظهر عند المرور وعند التركيز بلوحة المفاتيح.
/* انتقال أساسي */
.button {
background: #3498db;
transition: background 0.3s ease;
}
.button:hover {
background: #2980b9;
}
/* انتقالات متعددة */
.card {
background: white;
transform: translateY(0);
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
transition:
transform 0.3s ease,
box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0,0,0,0.15);
}
/* timing functions مختلفة */
.linear-move {
transition: all 0.5s linear;
}
.ease-in-move {
transition: all 0.5s ease-in; /* بطيء ثم سريع */
}
.ease-out-move {
transition: all 0.5s ease-out; /* سريع ثم بطيء */
}
/* cubic-bezier مخصص */
.bounce {
transition: all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
/* تأخير */
.delayed {
transition: opacity 0.3s ease 0.5s; /* يبدأ بعد 0.5s */
}
/* Menu Animation */
.nav-link {
position: relative;
color: #333;
transition: color 0.3s;
}
.nav-link::after {
content: '';
position: absolute;
bottom: -2px;
left: 0;
width: 0;
height: 2px;
background: #3498db;
transition: width 0.3s ease;
}
.nav-link:hover {
color: #3498db;
}
.nav-link:hover::after {
width: 100%;
}اختبر فهمك