تخطَّ إلى المحتوى

مشروع CSS: صفحة هبوط متجاوبة خطوة بخطوة

الدرس 19 من 19 · CSS

وصلت إلى آخر درس في كورس CSS. حان وقت أن تجمع المحددات والألوان ونموذج الصندوق و Flexbox و Grid والمتغيرات والحركة في صفحة واحدة حقيقية: صفحة هبوط (Landing Page) لتطبيق اسمه «مذاكر». وهي الصفحة التي يصل إليها الزائر أولاً، وهدفها أن تقنعه بضغطة زر واحدة.

القسم التقنية الأساسية
شريط علوي يلتصق عند التمرير Flexbox و position: sticky
قسم رئيسي فيه عنوان وزر clamp و text-align
ثلاث بطاقات مميزات Grid متجاوب
تذييل ألوان من المتغيرات

وسنتبع طريقة «الموبايل أولاً»: نكتب التنسيق للشاشة الصغيرة، ونترك Grid يوزع البطاقات تلقائياً عندما تتسع الشاشة.

index.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>&copy; 2026 مذاكر</p>
</footer>

الهيكل بوسوم دلالية، وكل ما يحتاج تنسيقاً له كلاس واضح الاسم.

الخطوة 2: المتغيرات والأساس

Section titled “الخطوة 2: المتغيرات والأساس”
style.css
: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 فقط.

style.css
.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: القسم الرئيسي والزر”
style.css
.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: البطاقات والتذييل”
style.css
.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 على الأقل، والمتصفح يضع في الصف ما يسعه. على الموبايل عمود واحد، وعلى الشاشة العريضة ثلاثة أعمدة، بلا أي استعلام وسائط.

هذه الصفحة كاملة. اسحب زاوية صندوق النتيجة لتغيّر عرضه وراقب البطاقات وهي تعيد ترتيب نفسها. ثم غيّر --primary إلى seagreen و --primary-dark إلى darkgreen:

جرّب بنفسكCSS
أو اضغط Ctrl + Enter

الناتج

وبعد أن تبنيها على جهازك في ملفين، index.html و style.css، طوّرها:

  1. أضف وضعاً ليلياً بتبديل قيم المتغيرات داخل prefers-color-scheme: dark.
  2. أضف حركة fade-in تُظهر القسم الرئيسي تدريجياً عند فتح الصفحة.
  3. أضف قسماً رابعاً فيه نموذج اشتراك بالبريد، ونسّق حالة :focus لحقله.
  4. أضف شارة «جديد» في زاوية إحدى البطاقات بـ position: absolute.
  • نسيان وسم viewport في HTML: الصفحة تظهر مصغّرة على الهاتف، ولا يعمل أي شيء من التجاوب.
  • ألوان مكتوبة مباشرة بجانب المتغيرات: تغيّر الهوية ثم تجد زراً بقي باللون القديم. خذ كل لون من متغير.
  • نص رمادي فاتح على خلفية بيضاء: يبدو أنيقاً ولا يُقرأ. تحقق من التباين، خصوصاً للنصوص الثانوية.
  • حركات بلا حالة focus: الزر يتفاعل مع الفأرة فقط، ومستخدم لوحة المفاتيح لا يرى أين هو.

سؤال

كيف تتحول البطاقات من ثلاثة أعمدة إلى عمود واحد على الموبايل في هذا المشروع؟

سؤال

لماذا استخدمنا margin-inline-start بدلاً من margin-right لروابط الشريط؟

  • ابدأ بالمتغيرات: كل الألوان والزوايا في :root.
  • Flexbox لصف واحد مثل الشريط العلوي، و Grid لشبكة البطاقات.
  • clamp و auto-fit و minmax تعطيك تجاوباً بلا استعلامات وسائط.
  • transition مع transform تضيف حياة للصفحة، ومعها دائماً حالة :focus-visible.
  • الخصائص المنطقية تجعل صفحتك تعمل من اليمين لليسار ومن اليسار لليمين.

أنهيت كورس CSS كاملاً، وتستطيع الآن أن تحوّل أي تصميم تراه إلى صفحة حقيقية. الخطوة التالية هي كورس JavaScript لتجعل صفحاتك تتفاعل مع الزائر: قوائم تفتح وتغلق، ونماذج تتحقق من البيانات، ومحتوى يتغير دون إعادة تحميل. وتعلّم أيضاً حفظ نسخ مشاريعك ومشاركتها من كورس Git.