مشروع CSS: صفحة هبوط متجاوبة خطوة بخطوة
وصلت إلى آخر درس في كورس CSS. حان وقت أن تجمع المحددات والألوان ونموذج الصندوق و Flexbox و Grid والمتغيرات والحركة في صفحة واحدة حقيقية: صفحة هبوط (Landing Page) لتطبيق اسمه «مذاكر». وهي الصفحة التي يصل إليها الزائر أولاً، وهدفها أن تقنعه بضغطة زر واحدة.
ماذا سنبني؟
Section titled “ماذا سنبني؟”| القسم | التقنية الأساسية |
|---|---|
| شريط علوي يلتصق عند التمرير | Flexbox و position: sticky |
| قسم رئيسي فيه عنوان وزر | clamp و text-align |
| ثلاث بطاقات مميزات | Grid متجاوب |
| تذييل | ألوان من المتغيرات |
وسنتبع طريقة «الموبايل أولاً»: نكتب التنسيق للشاشة الصغيرة، ونترك Grid يوزع البطاقات تلقائياً عندما تتسع الشاشة.
الخطوة 1: هيكل HTML
Section titled “الخطوة 1: هيكل HTML”<header class="navbar"> <a class="logo" href="#">مذاكر</a> <nav> <a href="#features">المميزات</a> <a href="#start">ابدأ</a> </nav></header>
<main> <section class="hero"> <h1>نظّم مذاكرتك في دقائق</h1> <p>جدول ذكي يوزّع موادك على أيام الأسبوع ويذكّرك بموعد كل درس.</p> <a class="btn" id="start" href="#">جرّبه مجاناً</a> </section>
<section class="features" id="features"> <article class="card"> <h2>جدول تلقائي</h2> <p>أدخل موادك وموعد الامتحان، واترك الباقي علينا.</p> </article> <article class="card"> <h2>تذكير يومي</h2> <p>إشعار خفيف قبل كل جلسة مذاكرة.</p> </article> <article class="card"> <h2>متابعة التقدم</h2> <p>اعرف كم أنجزت وكم بقي لك.</p> </article> </section></main>
<footer class="footer"> <p>© 2026 مذاكر</p></footer>الهيكل بوسوم دلالية، وكل ما يحتاج تنسيقاً له كلاس واضح الاسم.
الخطوة 2: المتغيرات والأساس
Section titled “الخطوة 2: المتغيرات والأساس”:root { --primary: #5b5bf0; --primary-dark: #4343c9; --text: #141826; --muted: #4b5568; --bg: #f7f8fc; --surface: #ffffff; --border: #e6e8f0; --radius: 14px;}
* { box-sizing: border-box;}
body { margin: 0; font-family: sans-serif; line-height: 1.8; color: var(--text); background: var(--bg);}كل ألوان الصفحة في مكان واحد. إذا أردت هوية مختلفة غيّرت --primary فقط.
الخطوة 3: الشريط العلوي
Section titled “الخطوة 3: الشريط العلوي”.navbar { position: sticky; top: 0; z-index: 10; display: flex; justify-content: space-between; align-items: center; padding: 12px 20px; background: var(--surface); border-bottom: 1px solid var(--border);}
.logo { font-size: 1.3rem; font-weight: bold; color: var(--primary); text-decoration: none;}
.navbar nav a { margin-inline-start: 16px; color: var(--text); text-decoration: none;}
.navbar nav a:hover { color: var(--primary);}display: flexمعspace-between: الشعار في طرف والروابط في الطرف الآخر.position: sticky: الشريط يبقى ظاهراً عند التمرير.margin-inline-start: هامش في بداية العنصر بحسب اتجاه اللغة. في الصفحة العربية هو الهامش الأيمن، وفي الإنجليزية الأيسر، فتعمل الصفحة في الاتجاهين.
الخطوة 4: القسم الرئيسي والزر
Section titled “الخطوة 4: القسم الرئيسي والزر”.hero { padding: 56px 20px; text-align: center;}
.hero h1 { margin: 0 0 12px; font-size: clamp(1.8rem, 6vw, 3rem); line-height: 1.4;}
.hero p { max-width: 45ch; margin: 0 auto 24px; color: var(--muted);}
.btn { display: inline-block; padding: 12px 28px; border-radius: 10px; background: var(--primary); color: white; font-weight: bold; text-decoration: none; transition: background 0.2s, transform 0.2s;}
.btn:hover { background: var(--primary-dark); transform: translateY(-2px);}
.btn:focus-visible { outline: 3px solid var(--text); outline-offset: 3px;}clampتجعل العنوان يكبر مع الشاشة داخل حدّين آمنين.max-width: 45chمعmargin: 0 autoتعطي فقرة قصيرة الأسطر في منتصف الصفحة.- الرابط صار زراً بـ
inline-blockوحشو وخلفية، وله حالة للفأرة وحالة للوحة المفاتيح.
الخطوة 5: البطاقات والتذييل
Section titled “الخطوة 5: البطاقات والتذييل”.features { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; max-width: 960px; margin: 0 auto; padding: 0 20px 56px;}
.card { padding: 20px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); transition: transform 0.2s, box-shadow 0.2s;}
.card:hover { transform: translateY(-4px); box-shadow: 0 10px 24px rgb(0 0 0 / 0.08);}
.card h2 { margin: 0 0 8px; font-size: 1.2rem; color: var(--primary);}
.card p { margin: 0; color: var(--muted);}
.footer { padding: 20px; text-align: center; color: var(--muted); border-top: 1px solid var(--border);}السطر repeat(auto-fit, minmax(220px, 1fr)) هو سر التجاوب هنا: كل بطاقة عرضها 220px على الأقل، والمتصفح يضع في الصف ما يسعه. على الموبايل عمود واحد، وعلى الشاشة العريضة ثلاثة أعمدة، بلا أي استعلام وسائط.
جرّب بنفسك
Section titled “جرّب بنفسك”هذه الصفحة كاملة. اسحب زاوية صندوق النتيجة لتغيّر عرضه وراقب البطاقات وهي تعيد ترتيب نفسها. ثم غيّر --primary إلى seagreen و --primary-dark إلى darkgreen:
الناتج
وبعد أن تبنيها على جهازك في ملفين، index.html و style.css، طوّرها:
- أضف وضعاً ليلياً بتبديل قيم المتغيرات داخل
prefers-color-scheme: dark. - أضف حركة
fade-inتُظهر القسم الرئيسي تدريجياً عند فتح الصفحة. - أضف قسماً رابعاً فيه نموذج اشتراك بالبريد، ونسّق حالة
:focusلحقله. - أضف شارة «جديد» في زاوية إحدى البطاقات بـ
position: absolute.
أخطاء شائعة
Section titled “أخطاء شائعة”- نسيان وسم viewport في HTML: الصفحة تظهر مصغّرة على الهاتف، ولا يعمل أي شيء من التجاوب.
- ألوان مكتوبة مباشرة بجانب المتغيرات: تغيّر الهوية ثم تجد زراً بقي باللون القديم. خذ كل لون من متغير.
- نص رمادي فاتح على خلفية بيضاء: يبدو أنيقاً ولا يُقرأ. تحقق من التباين، خصوصاً للنصوص الثانوية.
- حركات بلا حالة focus: الزر يتفاعل مع الفأرة فقط، ومستخدم لوحة المفاتيح لا يرى أين هو.
اختبر نفسك
Section titled “اختبر نفسك”سؤال
كيف تتحول البطاقات من ثلاثة أعمدة إلى عمود واحد على الموبايل في هذا المشروع؟
auto-fit مع minmax تجعل المتصفح يحسب عدد الأعمدة المناسب للعرض المتاح، فتتجاوب الشبكة وحدها.
سؤال
لماذا استخدمنا margin-inline-start بدلاً من margin-right لروابط الشريط؟
الخصائص المنطقية مثل margin-inline-start تشير إلى بداية السطر بحسب اتجاه الصفحة، لا إلى جهة ثابتة.
الخلاصة
Section titled “الخلاصة”- ابدأ بالمتغيرات: كل الألوان والزوايا في
:root. - Flexbox لصف واحد مثل الشريط العلوي، و Grid لشبكة البطاقات.
clampوauto-fitوminmaxتعطيك تجاوباً بلا استعلامات وسائط.transitionمعtransformتضيف حياة للصفحة، ومعها دائماً حالة:focus-visible.- الخصائص المنطقية تجعل صفحتك تعمل من اليمين لليسار ومن اليسار لليمين.
مبروك! ماذا بعد؟
Section titled “مبروك! ماذا بعد؟”أنهيت كورس CSS كاملاً، وتستطيع الآن أن تحوّل أي تصميم تراه إلى صفحة حقيقية. الخطوة التالية هي كورس JavaScript لتجعل صفحاتك تتفاعل مع الزائر: قوائم تفتح وتغلق، ونماذج تتحقق من البيانات، ومحتوى يتغير دون إعادة تحميل. وتعلّم أيضاً حفظ نسخ مشاريعك ومشاركتها من كورس Git.