إطار Tailwind CSS

حالات التمرير والتركيز والمتغيرات

20 دقيقة الدرس 11 من 35

حالات التمرير والتركيز والمتغيرات في Tailwind CSS

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

حالات التفاعل الأساسية

أكثر متغيرات الحالة شيوعاً هي لتفاعلات الماوس. يجعل Tailwind من السهل تغيير الأنماط عندما يقوم المستخدمون بالتمرير فوق العناصر أو النقر عليها أو التركيز عليها.

حالة التمرير

يطبق معدل hover: الأنماط عندما يقوم المستخدم بتمرير الماوس فوق العنصر:

أمثلة التمرير الأساسية

<!-- تغيير الخلفية عند التمرير -->
<button class="bg-blue-500 hover:bg-blue-700 text-white px-4 py-2 rounded">
    مرر فوقي
</button>

<!-- تغيير لون النص عند التمرير -->
<a href="#" class="text-blue-600 hover:text-blue-800 underline">
    رابط التمرير
</a>

<!-- تأثيرات متعددة عند التمرير -->
<div class="bg-white hover:bg-gray-100 hover:shadow-lg transition-all p-4">
    مرر للحصول على تأثيرات متعددة
</div>

<!-- تأثير التكبير عند التمرير -->
<img src="image.jpg" class="hover:scale-110 transition-transform" alt="صورة">
ملاحظة: يعمل معدل hover: مع أي فئة أداة. يمكنك دمجه مع الألوان والمسافات والتحويلات والظلال والمزيد.

حالة التركيز

يطبق معدل focus: الأنماط عندما يحصل العنصر على التركيز من لوحة المفاتيح، وهو ضروري لإمكانية الوصول:

أمثلة حالة التركيز

<!-- حقل إدخال مع أنماط التركيز -->
<input
    type="text"
    class="border border-gray-300 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 px-4 py-2 rounded"
    placeholder="ركز علي"
>

<!-- زر مع حلقة التركيز -->
<button class="bg-green-500 text-white px-4 py-2 rounded focus:outline-none focus:ring-4 focus:ring-green-300">
    انقر علي
</button>

<!-- رابط مع أنماط التركيز -->
<a href="#" class="text-blue-600 focus:text-blue-800 focus:underline">
    اضغط Tab للتركيز
</a>
نصيحة إمكانية الوصول: قدم دائماً مؤشرات تركيز مرئية للتنقل بلوحة المفاتيح. أدوات focus:ring مثالية لهذا.

حالة النشاط

يطبق معدل active: الأنماط عندما يتم النقر على العنصر أو الضغط عليه:

أمثلة الحالة النشطة

<!-- زر مع حالة نشطة -->
<button class="bg-blue-500 hover:bg-blue-600 active:bg-blue-700 text-white px-6 py-3 rounded">
    اضغط علي
</button>

<!-- تصغير عند النقر -->
<button class="bg-green-500 active:scale-95 transition-transform px-4 py-2 rounded text-white">
    انقر للتصغير
</button>

<!-- حالات مدمجة -->
<button class="bg-purple-500 hover:bg-purple-600 active:bg-purple-800 focus:ring-4 focus:ring-purple-300 text-white px-4 py-2 rounded">
    جميع الحالات
</button>

متغيرات التركيز المتقدمة

التركيز داخلياً

يطبق معدل focus-within: الأنماط على العنصر الأب عندما يحصل أي من أطفاله على التركيز:

أمثلة التركيز داخلياً

<!-- حاوية نموذج تبرز عندما يكون أي إدخال مركزاً -->
<div class="border-2 border-gray-300 focus-within:border-blue-500 focus-within:shadow-lg p-4 rounded">
    <label class="block mb-2">الاسم</label>
    <input type="text" class="border px-3 py-2 rounded w-full">
</div>

<!-- حاوية البحث مع التركيز داخلياً -->
<div class="flex items-center bg-gray-100 focus-within:bg-white focus-within:ring-2 focus-within:ring-blue-300 rounded-lg px-4 py-2">
    <svg class="w-5 h-5 text-gray-400">...</svg>
    <input type="search" class="bg-transparent focus:outline-none ml-2" placeholder="بحث...">
</div>

التركيز المرئي

يطبق معدل focus-visible: الأنماط فقط عندما يحصل العنصر على تركيز لوحة المفاتيح، وليس تركيز النقر بالماوس:

أمثلة التركيز المرئي

<!-- يظهر حلقة التركيز فقط عند استخدام Tab، وليس عند النقر -->
<button class="bg-blue-500 text-white px-4 py-2 rounded focus:outline-none focus-visible:ring-4 focus-visible:ring-blue-300">
    اضغط Tab لرؤية الحلقة
</button>

<!-- رابط مع مؤشر تركيز لوحة المفاتيح فقط -->
<a href="#" class="text-blue-600 focus-visible:underline focus-visible:ring-2 focus-visible:ring-blue-300 rounded">
    تركيز لوحة المفاتيح فقط
</a>
ملاحظة: focus-visible: أفضل لتجربة المستخدم لأنه لا يظهر حلقات التركيز عند النقر بالماوس، لكنه لا يزال يوفرها لمستخدمي لوحة المفاتيح.

معدلات المجموعة والنظير

تمرير المجموعة

تسمح أدوات group و group-hover: بتنسيق العناصر الفرعية بناءً على حالة تمرير الأب:

أمثلة تمرير المجموعة

<!-- بطاقة مع تأثيرات تمرير المجموعة -->
<div class="group bg-white hover:bg-blue-50 p-6 rounded-lg shadow transition-all">
    <h3 class="text-gray-800 group-hover:text-blue-600 text-xl font-bold">
        عنوان البطاقة
    </h3>
    <p class="text-gray-600 group-hover:text-gray-800 mt-2">
        مرر فوق البطاقة لرؤية التغييرات
    </p>
    <button class="bg-blue-500 group-hover:bg-blue-600 text-white px-4 py-2 rounded mt-4">
        اعرف المزيد
    </button>
</div>

<!-- تنقل مع تمرير المجموعة -->
<a href="#" class="group flex items-center gap-3 p-3 rounded hover:bg-gray-100">
    <svg class="w-6 h-6 text-gray-400 group-hover:text-blue-600">...</svg>
    <span class="text-gray-700 group-hover:text-gray-900 group-hover:font-semibold">
        لوحة التحكم
    </span>
    <svg class="w-4 h-4 text-gray-400 group-hover:translate-x-1 transition-transform ml-auto">←</svg>
</a>

<!-- بطاقة صورة مع تراكب -->
<div class="group relative overflow-hidden rounded-lg">
    <img src="image.jpg" class="group-hover:scale-110 transition-transform duration-300" alt="صورة">
    <div class="absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-50 transition-all">
        <div class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity">
            <button class="bg-white text-gray-900 px-6 py-3 rounded-lg font-semibold">
                عرض التفاصيل
            </button>
        </div>
    </div>
</div>
نصيحة احترافية: تمرير المجموعة مثالي للبطاقات وعناصر التنقل وأي مكون تريد أن تستجيب فيه عناصر فرعية متعددة لتمرير الأب.

معدلات النظير

تسمح أدوات peer و peer-*: بتنسيق عنصر بناءً على حالة عنصر شقيق:

أمثلة معدلات النظير

<!-- إدخال تسمية عائمة -->
<div class="relative">
    <input
        type="text"
        id="email"
        class="peer w-full border-2 border-gray-300 focus:border-blue-500 px-4 py-3 rounded outline-none"
        placeholder=" "
    >
    <label
        for="email"
        class="absolute left-4 top-3 text-gray-500 peer-focus:text-blue-500 peer-focus:text-sm peer-focus:-top-6 peer-focus:left-0 transition-all peer-[:not(:placeholder-shown)]:text-sm peer-[:not(:placeholder-shown)]:-top-6 peer-[:not(:placeholder-shown)]:left-0"
    >
        عنوان البريد الإلكتروني
    </label>
</div>

<!-- خانة اختيار مع تنسيق النظير -->
<div class="flex items-center gap-3">
    <input type="checkbox" id="terms" class="peer w-5 h-5">
    <label for="terms" class="text-gray-600 peer-checked:text-blue-600 peer-checked:font-semibold">
        أوافق على الشروط والأحكام
    </label>
</div>

<!-- زر راديو مع تنسيق مخصص -->
<div class="flex items-start gap-3">
    <input type="radio" id="option1" name="option" class="peer sr-only">
    <label for="option1" class="flex items-center gap-3 p-4 border-2 border-gray-300 peer-checked:border-blue-500 peer-checked:bg-blue-50 rounded-lg cursor-pointer">
        <div class="w-6 h-6 rounded-full border-2 border-gray-300 peer-checked:border-blue-500 flex items-center justify-center">
            <div class="w-3 h-3 rounded-full bg-blue-500 hidden peer-checked:block"></div>
        </div>
        <div>
            <div class="font-semibold text-gray-900">الخيار 1</div>
            <div class="text-sm text-gray-600">وصف الخيار 1</div>
        </div>
    </label>
</div>
ملاحظة: تعمل معدلات النظير فقط مع الأشقاء. يجب أن يأتي عنصر النظير قبل العنصر الذي تريد تنسيقه في بنية HTML.

متغيرات الفئة الزائفة الهيكلية

الأول والأخير والفردي والزوجي

يوفر Tailwind متغيرات لتنسيق العناصر بناءً على موضعها داخل الأب:

أمثلة المتغيرات الهيكلية

<!-- قائمة مع تنسيق الأول والأخير -->
<ul class="divide-y divide-gray-200">
    <li class="py-3 first:pt-0 last:pb-0">العنصر الأول</li>
    <li class="py-3 first:pt-0 last:pb-0">العنصر الثاني</li>
    <li class="py-3 first:pt-0 last:pb-0">العنصر الثالث</li>
    <li class="py-3 first:pt-0 last:pb-0">العنصر الأخير</li>
</ul>

<!-- جدول مع ألوان صفوف فردية/زوجية -->
<table class="w-full">
    <tbody>
        <tr class="odd:bg-white even:bg-gray-50">
            <td class="px-4 py-3">الصف 1</td>
        </tr>
        <tr class="odd:bg-white even:bg-gray-50">
            <td class="px-4 py-3">الصف 2</td>
        </tr>
        <tr class="odd:bg-white even:bg-gray-50">
            <td class="px-4 py-3">الصف 3</td>
        </tr>
    </tbody>
</table>

<!-- شبكة مع عنصر أول مختلف -->
<div class="grid grid-cols-3 gap-4">
    <div class="first:col-span-3 first:row-span-2 bg-gray-200 p-4 rounded">
        العنصر المميز
    </div>
    <div class="bg-gray-100 p-4 rounded">العنصر 2</div>
    <div class="bg-gray-100 p-4 rounded">العنصر 3</div>
    <div class="bg-gray-100 p-4 rounded">العنصر 4</div>
</div>

متغيرات حالة النموذج

الحالة المعطلة

ينسق معدل disabled: عناصر النموذج عندما تكون معطلة:

أمثلة الحالة المعطلة

<!-- زر معطل -->
<button
    disabled
    class="bg-blue-500 disabled:bg-gray-300 disabled:text-gray-500 disabled:cursor-not-allowed text-white px-4 py-2 rounded"
>
    زر معطل
</button>

<!-- إدخال معطل -->
<input
    type="text"
    disabled
    value="إدخال معطل"
    class="border border-gray-300 disabled:bg-gray-100 disabled:text-gray-500 disabled:cursor-not-allowed px-4 py-2 rounded w-full"
>

<!-- معطل شرطياً -->
<button
    class="bg-green-500 hover:bg-green-600 disabled:bg-gray-300 disabled:hover:bg-gray-300 disabled:cursor-not-allowed text-white px-6 py-3 rounded transition-colors"
    disabled
>
    إرسال
</button>

الحالة المطلوبة

ينسق معدل required: عناصر النموذج المحددة كمطلوبة:

أمثلة الحالة المطلوبة

<!-- إدخال مطلوب مع مؤشر -->
<div class="relative">
    <input
        type="text"
        required
        class="border-2 border-gray-300 required:border-blue-300 focus:border-blue-500 px-4 py-2 rounded w-full"
    >
    <span class="absolute right-3 top-3 text-red-500 required:block hidden">*</span>
</div>

<!-- نموذج مع حقول مطلوبة -->
<form class="space-y-4">
    <div>
        <label class="block text-gray-700 mb-2">
            الاسم <span class="text-red-500">*</span>
        </label>
        <input
            type="text"
            required
            class="border border-gray-300 required:border-l-4 required:border-l-blue-500 focus:border-blue-500 px-4 py-2 rounded w-full"
        >
    </div>
</form>

حالة العنصر النائب

ينسق معدل placeholder: نص العنصر النائب في حقول الإدخال:

أمثلة حالة العنصر النائب

<!-- تنسيق مخصص للعنصر النائب -->
<input
    type="text"
    placeholder="أدخل بريدك الإلكتروني"
    class="border border-gray-300 focus:border-blue-500 placeholder:text-gray-400 placeholder:italic px-4 py-2 rounded w-full"
>

<!-- عنصر نائب مع لون مخصص -->
<input
    type="search"
    placeholder="بحث..."
    class="bg-gray-100 placeholder:text-gray-500 px-4 py-2 rounded-full w-full"
>

<!-- منطقة نص مع عنصر نائب منسق -->
<textarea
    placeholder="اكتب رسالتك هنا..."
    class="border border-gray-300 placeholder:text-gray-400 placeholder:text-sm focus:border-blue-500 px-4 py-2 rounded w-full h-32"
></textarea>

حالة إدخال الملف

ينسق معدل file: زر إدخال الملف:

أمثلة إدخال الملف

<!-- إدخال ملف منسق -->
<input
    type="file"
    class="block w-full text-sm text-gray-500
        file:mr-4 file:py-2 file:px-4
        file:rounded-full file:border-0
        file:text-sm file:font-semibold
        file:bg-blue-50 file:text-blue-700
        hover:file:bg-blue-100
        file:cursor-pointer cursor-pointer"
>

<!-- رفع ملفات متعددة -->
<input
    type="file"
    multiple
    class="block w-full text-sm text-gray-600
        file:mr-4 file:py-3 file:px-6
        file:rounded-lg file:border file:border-gray-300
        file:text-sm file:font-medium
        file:bg-white file:text-gray-700
        hover:file:bg-gray-50
        file:transition-colors"
>

متغيرات حالة الرابط

الحالة المزارة

ينسق معدل visited: الروابط التي تمت زيارتها:

أمثلة الحالة المزارة

<!-- روابط مع حالة مزارة -->
<a href="#page1" class="text-blue-600 visited:text-purple-600 hover:underline">
    الرابط 1 (يتغير اللون عند الزيارة)
</a>

<a href="#page2" class="text-blue-600 visited:text-gray-600 visited:line-through">
    الرابط 2 (يظهر كمقروء)
</a>

<!-- روابط المقالات -->
<ul class="space-y-2">
    <li>
        <a href="#article1" class="text-blue-600 visited:text-purple-700 visited:opacity-75 hover:underline">
            المقالة 1 - مقدمة إلى Tailwind
        </a>
    </li>
    <li>
        <a href="#article2" class="text-blue-600 visited:text-purple-700 visited:opacity-75 hover:underline">
            المقالة 2 - تقنيات متقدمة
        </a>
    </li>
</ul>

تكديس متغيرات الحالة

يمكنك دمج متغيرات حالة متعددة لإنشاء تفاعلات معقدة:

أمثلة الحالات المدمجة

<!-- زر مع جميع الحالات -->
<button class="
    bg-blue-500
    hover:bg-blue-600
    active:bg-blue-700
    focus:outline-none
    focus:ring-4
    focus:ring-blue-300
    disabled:bg-gray-300
    disabled:cursor-not-allowed
    disabled:hover:bg-gray-300
    text-white
    font-semibold
    px-6
    py-3
    rounded-lg
    transition-all
">
    زر تفاعلي
</button>

<!-- بطاقة مع حالات المجموعة والفردية -->
<div class="group relative bg-white hover:shadow-2xl transition-shadow rounded-lg overflow-hidden">
    <img
        src="image.jpg"
        class="w-full group-hover:scale-105 transition-transform duration-300"
        alt="بطاقة"
    >
    <div class="p-6">
        <h3 class="text-xl font-bold text-gray-900 group-hover:text-blue-600 transition-colors">
            عنوان البطاقة
        </h3>
        <p class="text-gray-600 mt-2 group-hover:text-gray-800">
            نص وصف البطاقة
        </p>
        <button class="
            mt-4
            bg-blue-500
            hover:bg-blue-600
            active:scale-95
            focus:ring-4
            focus:ring-blue-300
            text-white
            px-4
            py-2
            rounded
            transition-all
        ">
            اعرف المزيد
        </button>
    </div>
</div>

<!-- إدخال النموذج مع حالات متعددة -->
<input
    type="email"
    required
    placeholder="أدخل البريد الإلكتروني"
    class="
        w-full
        border-2
        border-gray-300
        focus:border-blue-500
        focus:ring-2
        focus:ring-blue-200
        invalid:border-red-500
        invalid:focus:ring-red-200
        disabled:bg-gray-100
        disabled:cursor-not-allowed
        placeholder:text-gray-400
        placeholder:italic
        px-4
        py-3
        rounded-lg
        outline-none
        transition-all
    "
>
أفضل ممارسة: عند تكديس متغيرات حالة متعددة، رتبها من الأكثر عمومية إلى الأكثر تحديداً. على سبيل المثال: hover:bg-blue-600 focus:bg-blue-700 active:bg-blue-800

تمرين 1: قائمة تنقل تفاعلية

أنشئ قائمة تنقل جانبية بالميزات التالية:

  • استخدم تمرير المجموعة لتسليط الضوء على العنصر بأكمله عند التمرير
  • تغيير لون الأيقونة عند تمرير المجموعة
  • أضف مؤشر منزلق يظهر عند التمرير
  • نسق الصفحة النشطة/الحالية بشكل مختلف
  • قم بتضمين حالات التركيز للتنقل بلوحة المفاتيح

تمرين 2: نموذج متقدم مع متغيرات الحالة

قم ببناء نموذج تسجيل يتضمن:

  • تسميات عائمة تتحرك عندما يكون الإدخال مركزاً أو يحتوي على محتوى
  • خانات اختيار مخصصة باستخدام معدلات النظير
  • ألوان حدود مختلفة للحالات المطلوبة والمركزة وغير الصالحة
  • زر إرسال معطل حتى يصبح النموذج صالحاً
  • زر رفع الملف المنسق

تمرين 3: شبكة بطاقات المنتج

أنشئ شبكة بطاقات منتج متجاوبة حيث كل بطاقة:

  • تكبر قليلاً عند التمرير مع انتقال سلس
  • تظهر تراكب مع زر "عرض سريع" عند التمرير
  • لها زر "أضف إلى السلة" يتغير عند التمرير والتركيز والحالات النشطة
  • تعرض شارة "تخفيض" على العنصر الأول فقط
  • تظهر الروابط المزارة بلون مختلف

الملخص

في هذا الدرس، تعلمت عن نظام متغيرات الحالة القوي في Tailwind:

  • حالات التفاعل الأساسية: hover، focus، active، visited
  • متغيرات التركيز المتقدمة: focus-within، focus-visible
  • معدلات المجموعة والنظير: التنسيق بناءً على حالة الأب أو الشقيق
  • المتغيرات الهيكلية: first، last، odd، even
  • حالات النموذج: disabled، required، placeholder، إدخال الملف
  • تكديس المتغيرات: دمج حالات متعددة للتفاعلات المعقدة

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