طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 242 · أطر الويب
الدرس 9 · الوحدة 3: تنفيذ التصميم المتجاوب

واجهات متجاوبة بـ Tailwind

صفحة واحدة تناسب الجوال والحاسب. ⏱ نحو 30 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تطبّق مبدأ الجوال أولًا ونقاط التوقف في Tailwind.
  • تبني شبكات وتخطيطات تتبدل مع الشاشة.
  • تبني قائمة تنقل متجاوبة بـ React و Tailwind.
  • تراعي الاتجاه العربي والوضع الداكن وقائمة فحص التجاوب.

١الجوال أولًا

أغلب زوار المواقع اليوم من الجوال. لذلك يتبع Tailwind قاعدة الجوال أولًا Mobile first: الصنف العادي للشاشات الصغيرة، ثم تضيف بادئة لتغيّره في الشاشات الأكبر:

البادئةيطبّق من عرضالجهاز تقريبًا
(بلا بادئة)0كل الأجهزة، والجوال أساسًا
sm:640pxجوال كبير بالعرض
md:768pxجهاز لوحي
lg:1024pxحاسب محمول
xl:1280pxشاشة كبيرة

جرّب أزرار العرض في شريط المعاينة (📱 و ▭ و 🖥) لترى البطاقات تتراتب:

const courses = ['أطر الويب', 'أمن الويب', 'علم البيانات', 'ضمان الجودة', 'الأجهزة الذكية', 'تحليل البرمجيات']; export default function App() {  return (    <div className="p-3 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">      {courses.map(c => (        <div key={c} className="p-4 rounded-xl bg-sky-50 border border-sky-200 font-semibold text-sky-900">{c}</div>      ))}    </div>  );}

grid-cols-1 عمود واحد للجوال، و sm:grid-cols-2 عمودان من 640 بكسل، و lg:grid-cols-3 ثلاثة من 1024 بكسل.

٢إخفاء وإظهار وتبديل الاتجاه

export default function App() {  return (    <div className="p-3 space-y-3">      <div className="flex flex-col md:flex-row gap-3">        <aside className="md:w-48 p-3 rounded-lg bg-slate-100">القائمة الجانبية</aside>        <main className="flex-1 p-3 rounded-lg bg-white border">المحتوى الرئيسي</main>      </div>      <p className="block md:hidden text-rose-700">📱 أنت على شاشة صغيرة</p>      <p className="hidden md:block text-emerald-700">🖥 أنت على شاشة كبيرة</p>      <h1 className="text-xl md:text-3xl font-bold">عنوان يكبر مع الشاشة</h1>    </div>  );}
الحاجةالأصناف
عمودي في الجوال، أفقي في الكبيرflex flex-col md:flex-row
يظهر في الجوال فقطblock md:hidden
يظهر في الكبير فقطhidden md:block
حجم خط متدرجtext-xl md:text-3xl
عرض محدود في المنتصفmax-w-5xl mx-auto

٣قائمة تنقل متجاوبة بـ React

نمط ستراه في كل موقع: في الشاشة الكبيرة روابط ظاهرة، وفي الجوال زر «☰» يفتح القائمة. Tailwind للشكل، و useState للفتح والإغلاق:

import { useState } from 'react'; const links = ['الرئيسية', 'الدورات', 'الجدول', 'تواصل']; export default function App() {  const [open, setOpen] = useState(false);  return (    <nav className="bg-sky-700 text-white rounded-xl p-3">      <div className="flex items-center justify-between">        <b>🎓 الكلية التقنية</b>        <button className="md:hidden text-2xl" onClick={() => setOpen(!open)} aria-label="القائمة">          {open ? '✕' : '☰'}        </button>        <ul className="hidden md:flex gap-4">          {links.map(l => <li key={l}><a href="#" className="hover:underline">{l}</a></li>)}        </ul>      </div>      {open && (        <ul className="md:hidden mt-3 space-y-2">          {links.map(l => <li key={l}><a href="#" className="block p-2 rounded bg-sky-800">{l}</a></li>)}        </ul>      )}    </nav>  );}

اضغط 📱 في شريط المعاينة ثم «☰».

٤الوضع الداكن والاتجاه

البادئة dark: تطبّق الصنف حين يكون الجهاز على الوضع الداكن. والبادئتان rtl: و ltr: للحالات النادرة التي تختلف حسب الاتجاه (مثل سهم يشير للأمام):

<div className="bg-white text-slate-900 dark:bg-slate-900 dark:text-slate-100">  <p>يتبع وضع الجهاز تلقائيًّا</p>  <span className="inline-block rtl:rotate-180">➜</span></div>

توقّع وتحقّق

الصنف md:grid-cols-3 يطبّق:

Mobile first.

عنصر يظهر في الجوال فقط:

يظهر ثم يختفي من md.

flex flex-col md:flex-row تعني:

تبديل الاتجاه.

البادئة التي تتبع وضع الجهاز الداكن:

dark:

الخلاصة

تحدٍّ برمجي: معرض منتجات متجاوب

متوسط

اعرض المنتجات في شبكة تتكيف مع الشاشة.

المطلوب:
  • حاوية الشبكة <div id="grid">: عمود واحد في الجوال، وعمودان من sm، وأربعة من lg، بفجوة gap-4.
  • كل منتج بطاقة <div className="… item"> بحشو p-4 وزوايا rounded-lg.
  • عنوان <h1> بحجم text-xl في الجوال و text-3xl من md.
👀 اعرض الناتج المطلوب (وجرّبه)
✓ التحقق الآلي من حلّك:
  • الكود يعمل بلا أخطاء في Console
  • الشبكة grid بفجوة 16px
  • عمود واحد ثم sm:2 ثم lg:4
  • البطاقات بحشو 16px وزوايا
  • العنوان text-xl ثم md:text-3xl

💡 تلميح 1
grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4
💡 تلميح 2
أضف الصنف item مع بقية أصناف البطاقة.

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

const items = ['قهوة', 'تمر', 'عسل', 'شاي', 'هيل', 'زعفران', 'بخور', 'دلة']; export default function App() {  return (    <div className="p-3">      <h1 className="text-xl md:text-3xl font-bold mb-3">منتجاتنا</h1>      <div id="grid" className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">        {items.map(i => <div key={i} className="item p-4 rounded-lg bg-amber-50 border">{i}</div>)}      </div>    </div>  );}
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

📝 معلم؟ أرسل ملاحظة للمؤلف عن هذا الدرس