Kodax

الانتقالات (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%;
}
اختبر فهمك