ارتقِ بمهاراتك في Tailwind CSS عبر إتقان تكديس المعدِّلات. تعلم كيفية دمج معدِّلات الاستجابة والحالة والمجموعة لبناء واجهات مستخدم معقدة وديناميكية بسهولة.
إطلاق العنان لقوة Tailwind: فن تكديس المعدِّلات لتركيبات الأدوات المعقدة
لقد غيّر Tailwind CSS بشكل أساسي الطريقة التي يتعامل بها العديد من المطورين مع تصميم الأنماط للويب. تسمح فلسفته القائمة على الأدوات أولاً (utility-first) بالنماذج الأولية السريعة وبناء تصميمات مخصصة دون مغادرة ملف HTML الخاص بك. في حين أن تطبيق أدوات فردية مثل p-4
أو text-blue-500
أمر مباشر، فإن القوة الحقيقية لـ Tailwind تُطلق عندما تبدأ في إنشاء واجهات مستخدم معقدة، ذات حالة، ومتجاوبة. ويكمن السر في هذا في مفهوم قوي وبسيط في نفس الوقت: تكديس المعدِّلات (modifier stacking).
يشعر العديد من المطورين بالراحة مع استخدام معدِّلات فردية مثل hover:bg-blue-500
أو md:grid-cols-3
. ولكن ماذا يحدث عندما تحتاج إلى تطبيق نمط فقط عند التمرير (hover)، على شاشة كبيرة، و عند تمكين الوضع الداكن؟ هنا يأتي دور تكديس المعدِّلات. إنها تقنية ربط عدة معدِّلات معًا لإنشاء قواعد تصميم محددة للغاية تستجيب لمجموعة من الشروط.
سيأخذك هذا الدليل الشامل في رحلة عميقة إلى عالم تكديس المعدِّلات. سنبدأ بالأساسيات ونتدرج تدريجيًا إلى التركيبات المتقدمة التي تشمل الحالات، ونقاط التوقف، وgroup
، وpeer
، وحتى المتغيرات الاعتباطية. بحلول النهاية، ستكون مجهزًا لبناء أي مكون واجهة مستخدم يمكنك تخيله، كل ذلك بالأناقة التعريفية لـ Tailwind CSS.
الأساس: فهم المعدِّلات الفردية
قبل أن نتمكن من التكديس، يجب أن نفهم وحدات البناء. في Tailwind، المعدِّل هو بادئة تُضاف إلى فئة أداة لتحديد متى يجب تطبيق تلك الأداة. إنها في الأساس تطبيق قائم على الأدوات للفئات الزائفة في CSS، واستعلامات الوسائط (media queries)، وغيرها من القواعد الشرطية.
يمكن تصنيف المعدِّلات على نطاق واسع:
- معدِّلات الحالة (State Modifiers): تطبق هذه الأنماط بناءً على الحالة الحالية للعنصر، مثل تفاعل المستخدم. تشمل الأمثلة الشائعة
hover:
،focus:
،active:
،disabled:
، وvisited:
. - معدِّلات نقاط التوقف للاستجابة (Responsive Breakpoint Modifiers): تطبق هذه الأنماط عند حجم شاشة معين وما فوق، متبعة نهج "الجوال أولاً". الإعدادات الافتراضية هي
sm:
،md:
،lg:
،xl:
، و2xl:
. - معدِّلات تفضيلات النظام (System Preference Modifiers): تستجيب هذه لإعدادات نظام التشغيل أو المتصفح للمستخدم. أبرزها هو
dark:
للوضع الداكن، ولكن هناك أخرى مثلmotion-reduce:
وprint:
مفيدة للغاية أيضًا. - معدِّلات الفئات الزائفة والعناصر الزائفة (Pseudo-class & Pseudo-element Modifiers): تستهدف هذه خصائص هيكلية محددة أو أجزاء من عنصر، مثل
first:
،last:
،odd:
،even:
،before:
،after:
، وplaceholder:
.
على سبيل المثال، قد يستخدم زر بسيط معدِّل حالة مثل هذا:
<button class="bg-sky-500 hover:bg-sky-600 ...">Click me</button>
هنا، hover:bg-sky-600
يطبق لون خلفية أغمق فقط عندما يكون مؤشر المستخدم فوق الزر. هذا هو المفهوم الأساسي الذي سنبني عليه.
سحر التكديس: دمج المعدِّلات لواجهات مستخدم ديناميكية
تكديس المعدِّلات هو عملية ربط هذه البادئات معًا لإنشاء شرط أكثر تحديدًا. الصيغة بسيطة وبديهية: ما عليك سوى وضعها واحدة تلو الأخرى، مفصولة بنقطتين رأسيتين.
الصيغة: modifier1:modifier2:utility-class
الترتيب مهم. يطبق Tailwind المعدِّلات من اليسار إلى اليمين. على سبيل المثال، الفئة md:hover:text-red-500
تُترجم تقريبًا إلى كود CSS التالي:
@media (min-width: 768px) {
.md\:hover\:text-red-500:hover {
color: red;
}
}
تعني هذه القاعدة: "عند نقطة التوقف المتوسطة (medium) وما فوق، وعندما يتم التمرير فوق هذا العنصر، اجعل لون نصه أحمر". دعنا نستكشف بعض الأمثلة العملية من العالم الحقيقي.
مثال 1: دمج نقاط التوقف والحالات
أحد المتطلبات الشائعة هو جعل العناصر التفاعلية تتصرف بشكل مختلف على الأجهزة التي تعمل باللمس مقابل الأجهزة التي تعتمد على المؤشر. يمكننا تقريب ذلك عن طريق تغيير تأثيرات التمرير عند نقاط توقف مختلفة.
لنأخذ مكون بطاقة يرتفع بمهارة عند التمرير عليه على سطح المكتب، ولكنه لا يحتوي على تأثير تمرير على الجوال لتجنب حالات التمرير "اللزجة" عند اللمس.
<div class="... transition-transform duration-300 md:hover:scale-105 md:hover:-translate-y-1">...</div>
التفصيل:
transition-transform duration-300
: يقوم هذا بإعداد انتقال سلس لأي تغييرات في التحويل (transform).md:hover:scale-105
: عند نقطة التوقف المتوسطة (768 بكسل) وما فوق، عند التمرير فوق البطاقة، قم بتكبيرها بنسبة 5٪.md:hover:-translate-y-1
: عند نقطة التوقف المتوسطة وما فوق، عند التمرير فوق البطاقة، قم بتحريكها للأعلى قليلاً.
على الشاشات التي يقل عرضها عن 768 بكسل، يمنع المعدِّل md:
تطبيق تأثيرات التمرير، مما يوفر تجربة أفضل لمستخدمي الجوال.
مثال 2: إضافة طبقة الوضع الداكن مع التفاعلية
لم يعد الوضع الداكن ميزة متخصصة؛ بل هو توقع من المستخدم. يتيح لك التكديس تحديد أنماط التفاعل الخاصة بكل نظام ألوان.
دعنا نصمم رابطًا له ألوان مختلفة لحالاته الافتراضية وعند التمرير في كل من الوضع الفاتح والداكن.
<a href="#" class="text-blue-600 underline hover:text-blue-800 dark:text-cyan-400 dark:hover:text-cyan-200">اقرأ المزيد</a>
التفصيل:
text-blue-600 hover:text-blue-800
: في الوضع الفاتح (الافتراضي)، يكون النص أزرق ويصبح أغمق عند التمرير.dark:text-cyan-400
: عند تنشيط الوضع الداكن، يتغير لون النص الافتراضي إلى السماوي الفاتح.dark:hover:text-cyan-200
: عند تنشيط الوضع الداكن و التمرير فوق الرابط، يصبح النص بلون سماوي أفتح.
يوضح هذا كيف يمكنك إنشاء مجموعة كاملة من الأنماط المتوافقة مع السمة لعنصر ما في سطر واحد.
مثال 3: الثلاثية - تكديس معدِّلات الاستجابة، الوضع الداكن، والحالة
الآن، دعنا نجمع المفاهيم الثلاثة في قاعدة واحدة قوية. تخيل حقل إدخال يحتاج إلى الإشارة إلى أنه في حالة التركيز (focused). يجب أن تكون التغذية الراجعة المرئية مختلفة على سطح المكتب مقابل الجوال، ويجب أن تتكيف مع الوضع الداكن.
<input type="text" class="border-gray-300 dark:border-gray-600 dark:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 md:dark:focus:ring-yellow-400" />
دعنا نركز على الفئة الأكثر تعقيدًا هنا: md:dark:focus:ring-yellow-400
.
التفصيل:
md:
: تنطبق هذه القاعدة فقط عند نقطة التوقف المتوسطة (768 بكسل) وأعرض.dark:
: ضمن نقطة التوقف هذه، تنطبق فقط إذا كان المستخدم قد مكّن الوضع الداكن.focus:
: ضمن نقطة التوقف ووضع الألوان هذا، تنطبق فقط عندما يكون عنصر الإدخال في حالة التركيز.ring-yellow-400
: عند استيفاء جميع الشروط الثلاثة، قم بتطبيق حلقة تركيز صفراء.
تمنحنا فئة الأداة الواحدة هذه سلوكًا محددًا بشكل لا يصدق: "على الشاشات الكبيرة، في الوضع الداكن، قم بتمييز حقل الإدخال هذا عند التركيز عليه بحلقة صفراء". وفي الوقت نفسه، تعمل الفئة الأبسط focus:ring-blue-500
كنمط تركيز افتراضي لجميع السيناريوهات الأخرى (وضع الجوال الفاتح/الداكن، ووضع سطح المكتب الفاتح).
ما بعد الأساسيات: التكديس المتقدم مع `group` و `peer`
يصبح التكديس أكثر قوة عند إدخال معدِّلات تنشئ علاقات بين العناصر. يسمح لك معدِّلا group
و peer
بتصميم عنصر بناءً على حالة عنصر أب أو شقيق، على التوالي.
التأثيرات المنسقة مع `group-*`
معدِّل group
مثالي عندما يجب أن يؤثر التفاعل مع عنصر أب على واحد أو أكثر من أبنائه. بإضافة الفئة group
إلى عنصر أب، يمكنك بعد ذلك استخدام group-hover:
، group-focus:
، وما إلى ذلك، على أي عنصر ابن.
دعنا ننشئ بطاقة يتغير لون عنوانها ويتحرك رمز سهم عند التمرير فوق أي جزء منها. يجب أن يكون هذا أيضًا متوافقًا مع الوضع الداكن.
<a href="#" class="group block p-6 bg-white dark:bg-slate-800 rounded-lg shadow-md">
<h3 class="text-slate-900 group-hover:text-blue-600 dark:text-white dark:group-hover:text-blue-400">عنوان البطاقة</h3>
<p class="text-slate-500 dark:text-slate-400">محتوى البطاقة يوضع هنا.</p>
<span class="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">→</span>
</a>
تفصيل المعدِّل المكدس:
dark:group-hover:text-blue-400
علىh3
: عند تنشيط الوضع الداكن و التمرير فوق العنصر الأبgroup
، قم بتغيير لون نص العنوان. هذا يتجاوز لون الوضع الداكن الافتراضي ولكنه لا يؤثر على نمط التمرير في الوضع الفاتح.group-hover:translate-x-1
علىspan
: عند التمرير فوق العنصر الأبgroup
(في أي وضع)، قم بتحريك رمز السهم إلى اليمين.
تفاعلات الأشقاء الديناميكية مع `peer-*`
صُمم معدِّل peer
لتصميم العناصر الشقيقة. عندما تضع علامة على عنصر بالفئة peer
، يمكنك بعد ذلك استخدام معدِّلات مثل peer-focus:
، peer-invalid:
، أو peer-checked:
على عنصر شقيق تالي لتصميمه بناءً على حالة النظير (peer).
حالة استخدام كلاسيكية هي حقل إدخال في نموذج وتسميته (label). نريد أن يتغير لون التسمية عند التركيز على حقل الإدخال، ونريد أيضًا ظهور رسالة خطأ إذا كان الإدخال غير صالح. يجب أن يعمل هذا عبر نقاط التوقف وأنظمة الألوان.
<div>
<label for="email" class="text-sm font-medium text-gray-700 dark:text-gray-300 peer-focus:text-violet-600 dark:peer-focus:text-violet-400">البريد الإلكتروني</label>
<input type="email" id="email" class="peer mt-1 block w-full border-gray-300 invalid:border-red-500 focus:border-violet-500 ..." required />
<p class="mt-2 invisible text-sm text-red-600 peer-invalid:visible">يرجى تقديم عنوان بريد إلكتروني صالح.</p>
</div>
تفصيل المعدِّل المكدس:
dark:peer-focus:text-violet-400
علىlabel
: عند تنشيط الوضع الداكن و التركيز على حقل الإدخال الشقيقpeer
، قم بتغيير لون التسمية إلى البنفسجي. يعمل هذا بالاقتران معpeer-focus:text-violet-600
القياسي للوضع الفاتح.peer-invalid:visible
على فقرة الخطأp
: عندما يكون لحقل الإدخال الشقيقpeer
حالةinvalid
(على سبيل المثال، حقل مطلوب فارغ)، قم بتغيير رؤيته منinvisible
إلىvisible
. هذا مثال رئيسي على تصميم التحقق من صحة النماذج بدون أي JavaScript.
الحد النهائي: التكديس مع المتغيرات الاعتباطية
في بعض الأحيان، تحتاج إلى تطبيق نمط بناءً على شرط لا يوفره Tailwind كمعدِّل جاهز. هنا يأتي دور المتغيرات الاعتباطية (arbitrary variants). تتيح لك كتابة محدد (selector) مخصص مباشرة في اسم الفئة الخاص بك، ونعم، هي قابلة للتكديس!
تستخدم الصيغة الأقواس المربعة: [&_selector]:utility
.
مثال 1: استهداف عناصر فرعية محددة عند التمرير
تخيل أن لديك حاوية، وتريد أن تتحول جميع علامات <strong>
بداخلها إلى اللون الأخضر عند التمرير فوق الحاوية، ولكن فقط على الشاشات الكبيرة.
<div class="p-4 border lg:hover:[&_strong]:text-green-500">
<p>هذه فقرة بها <strong>نص مهم</strong> سيتغير لونه.</p>
<p>هذه فقرة أخرى بها <strong>جزء آخر بخط عريض</strong>.</p>
</div>
التفصيل:
تجمع الفئة lg:hover:[&_strong]:text-green-500
بين معدِّل استجابة (lg:
)، ومعدِّل حالة (hover:
)، ومتغير اعتباطي ([&_strong]:
) لإنشاء قاعدة محددة للغاية: "على الشاشات الكبيرة وما فوق، عند التمرير فوق هذا الـ div، ابحث عن جميع عناصر <strong>
التابعة واجعل نصها أخضر."
مثال 2: التكديس مع محددات السمات (Attribute Selectors)
هذه التقنية مفيدة بشكل لا يصدق للتكامل مع أطر عمل JavaScript حيث قد تستخدم سمات data-*
لإدارة الحالة (على سبيل المثال، للأكورديون، علامات التبويب، أو القوائم المنسدلة).
دعنا نصمم منطقة محتوى عنصر أكورديون بحيث تكون مخفية بشكل افتراضي ولكنها مرئية عندما يكون لعنصرها الأب السمة data-state="open"
. نريد أيضًا لون خلفية مختلفًا عندما تكون مفتوحة في الوضع الداكن.
<div data-state="closed" class="border rounded">
<h3>... مشغل الأكورديون ...</h3>
<div class="overflow-hidden h-0 [data-state=open]:h-auto dark:[data-state=open]:bg-gray-800">
محتوى الأكورديون...
</div>
</div>
سيقوم كود JavaScript الخاص بك بتبديل السمة data-state
على العنصر الأب بين open
و closed
.
تفصيل المعدِّل المكدس:
تعتبر الفئة dark:[data-state=open]:bg-gray-800
الموجودة على div
المحتوى مثالًا مثاليًا. إنها تقول: "عندما يكون الوضع الداكن نشطًا و يحتوي العنصر على السمة data-state="open"
، قم بتطبيق خلفية رمادية داكنة". يتم تكديس هذا مع القاعدة الأساسية [data-state=open]:h-auto
التي تتحكم في رؤيته في جميع الأوضاع.
أفضل الممارسات واعتبارات الأداء
بينما يعد تكديس المعدِّلات قويًا، من الضروري استخدامه بحكمة للحفاظ على قاعدة كود نظيفة وقابلة للإدارة.
- الحفاظ على القروئية: يمكن أن تصبح السلاسل الطويلة من فئات الأدوات صعبة القراءة. يوصى بشدة باستخدام أداة فرز الفئات التلقائية مثل إضافة Prettier الرسمية لـ Tailwind CSS. فهي توحد ترتيب الفئات، مما يجعل التركيبات المعقدة أسهل بكثير في المسح الضوئي.
- تجريد المكونات: إذا وجدت نفسك تكرر نفس التكدس المعقد من المعدِّلات على العديد من العناصر، فهذه إشارة قوية لتجريد هذا النمط في مكون قابل لإعادة الاستخدام (على سبيل المثال، مكون React أو Vue، مكون Blade في Laravel، أو جزء بسيط).
- احتضان محرك JIT: في الماضي، كان تمكين العديد من المتغيرات يمكن أن يؤدي إلى أحجام ملفات CSS كبيرة. مع محرك Just-In-Time (JIT) من Tailwind، لم تعد هذه مشكلة. يقوم محرك JIT بمسح ملفاتك وإنشاء كود CSS الذي تحتاجه بالضبط فقط، بما في ذلك كل تركيبة معقدة من المعدِّلات المكدسة. التأثير على الأداء في البناء النهائي ضئيل، لذا يمكنك التكديس بثقة.
- فهم الخصوصية والترتيب: لا يؤثر ترتيب الفئات في HTML بشكل عام على الخصوصية بنفس طريقة CSS التقليدية. ومع ذلك، عندما تحاول أداتان في نفس نقطة التوقف والحالة التحكم في نفس الخاصية (على سبيل المثال،
md:text-left md:text-right
)، فإن الأداة التي تظهر أخيرًا في السلسلة هي التي تفوز. تتعامل إضافة Prettier مع هذا المنطق نيابة عنك.
الخلاصة: ابنِ أي شيء يمكنك تخيله
تكديس المعدِّلات في Tailwind CSS ليس مجرد ميزة؛ إنه الآلية الأساسية التي ترتقي بـ Tailwind من مكتبة أدوات بسيطة إلى إطار عمل شامل لتصميم واجهة المستخدم. من خلال إتقان فن دمج متغيرات الاستجابة، والحالة، والسمة، والمجموعة، والنظير، وحتى المتغيرات الاعتباطية، فإنك تتحرر من قيود المكونات المعدة مسبقًا وتكتسب القدرة على صياغة واجهات مخصصة وديناميكية ومتجاوبة حقًا.
الخلاصة الرئيسية هي أنك لم تعد مقيدًا بالأنماط أحادية الشرط. يمكنك الآن تحديد شكل وسلوك العنصر بشكل تعريفي تحت مجموعة دقيقة من الظروف. سواء كان زرًا بسيطًا يتكيف مع الوضع الداكن أو مكون نموذج معقد ومدرك للحالة، يوفر تكديس المعدِّلات الأدوات التي تحتاجها لبنائه بأناقة وكفاءة، كل ذلك دون مغادرة راحة لغة الترميز الخاصة بك.