جاري التحميل...
جاري التحميل...
تصميم صفحة هبوط احترافية
في هذا الدرس الأخير، سنبني معاً صفحة Landing Page احترافية تجمع كل ما تعلمناه في مرحلة CSS الحديثة. هذا المشروع ليس مجرد تمرين - بل هو تنفيذ حقيقي يمكنك استخدامه كأساس لأي مشروع مستقبلي.
سنستخدم جميع تقنيات CSS الحديثة: المتغيرات، تخطيطات الشبكة والمرونة، السمات الداكنة والفاتحة، الرسوم المتحركة، الخصائص المنطقية، الوحدات السائلة، والألوان المتقدمة.
لن نكتب HTML من الصفر - نركز على CSS فقط. لكننا سنبني الهيكل أولاً لفهم كيفية تنسيقه.
clamp() بدلاً من العديد من Media Queriesauto-fit و minmax للشبكات السائلةoklch() و color-mix()يتبع هيكل ملفات CSS نمط طبقات منظم:
نستخدم @layer لتنظيم الأولويات: كل طبقة محددة مسبقاً، والطبقة الأعلى في الترتيب تفوز عند التعارض.
project/
├── index.html
├── css/
│ ├── layers.css
│ ├── base.css
│ ├── variables.css
│ ├── components.css
│ ├── layout.css
│ ├── utilities.css
│ └── animations.css
└── js/
└── theme-toggle.jsنبدأ بإعداد المتغيرات وإعادة التعيين الأساسية. هذه أساس كل مشروع CSS حديث.
@layer base, components, layout, utilities, animations;@layer base {
:root {
color-scheme: light dark;
--color-primary: oklch(0.65 0.19 265);
--color-primary-hover: oklch(0.55 0.19 265);
--color-primary-light: oklch(0.92 0.05 265);
--color-secondary: oklch(0.65 0.19 145);
--color-accent: oklch(0.75 0.15 55);
--bg-page: light-dark(#f8fafc, #0f172a);
--bg-surface: light-dark(#ffffff, #1e293b);
--bg-surface-hover: light-dark(#f1f5f9, #334155);
--bg-muted: light-dark(#f1f5f9, #1e293b);
--text-primary: light-dark(#0f172a, #f1f5f9);
--text-secondary: light-dark(#475569, #94a3b8);
--text-muted: light-dark(#94a3b8, #64748b);
--border-default: light-dark(#e2e8f0, #334155);
--border-hover: light-dark(#cbd5e1, #475569);
--shadow-sm: 0 1px 2px oklch(0 0 0 / 0.05);
--shadow-md: 0 4px 6px -1px oklch(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px -3px oklch(0 0 0 / 0.1);
--shadow-glow: 0 0 20px color-mix(in oklch, var(--color-primary) 25%, transparent);
--font-family: 'Inter', system-ui, -apple-system, sans-serif;
--font-size-xs: clamp(0.75rem, 0.7rem + 0.15vw, 0.8rem);
--font-size-sm: clamp(0.8rem, 0.75rem + 0.2vw, 0.875rem);
--font-size-base: clamp(0.9rem, 0.85rem + 0.25vw, 1rem);
--font-size-lg: clamp(1rem, 0.9rem + 0.5vw, 1.25rem);
--font-size-xl: clamp(1.25rem, 1rem + 1vw, 1.75rem);
--font-size-2xl: clamp(1.5rem, 1.2rem + 1.5vw, 2.5rem);
--font-size-hero: clamp(2rem, 1.5rem + 2.5vw, 4rem);
--space-xs: 0.25rem;
--space-sm: 0.5rem;
--space-md: 1rem;
--space-lg: 1.5rem;
--space-xl: 2rem;
--space-2xl: 3rem;
--space-3xl: 4rem;
--radius-sm: 0.375rem;
--radius-md: 0.5rem;
--radius-lg: 0.75rem;
--radius-xl: 1rem;
--radius-full: 9999px;
--transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-base: 250ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-slow: 350ms cubic-bezier(0.4, 0, 0.2, 1);
--container-max: min(100% - 2rem, 72rem);
--nav-height: 4rem;
}
}@layer base {
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
scroll-behavior: smooth;
scroll-padding-top: var(--nav-height);
}
body {
font-family: var(--font-family);
font-size: var(--font-size-base);
line-height: 1.6;
color: var(--text-primary);
background-color: var(--bg-page);
min-height: 100dvh;
-webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a {
color: var(--color-primary);
text-decoration: none;
transition: color var(--transition-fast);
&:hover { color: var(--color-primary-hover); }
}
h1, h2, h3, h4, h5, h6 {
line-height: 1.2;
font-weight: 700;
color: var(--text-primary);
}
::selection {
background: color-mix(in oklch, var(--color-primary) 30%, transparent);
}
}الآن نبني التخطيط العام: شريط التنقل، قسم البطل، البطاقات، والتذييل.
/* components.css */
@layer components {
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
position: sticky;
top: 0;
z-index: 100;
height: var(--nav-height);
padding-inline: clamp(1rem, 3vw, 2rem);
background: color-mix(in oklch, var(--bg-surface) 85%, transparent);
backdrop-filter: blur(12px) saturate(1.5);
border-block-end: 1px solid var(--border-default);
}
.navbar__logo {
font-size: var(--font-size-xl);
font-weight: 800;
color: var(--color-primary);
}
.navbar__links {
display: flex;
align-items: center;
gap: var(--space-lg);
list-style: none;
}
.navbar__link {
color: var(--text-secondary);
font-size: var(--font-size-sm);
font-weight: 500;
padding: var(--space-xs) var(--space-sm);
border-radius: var(--radius-md);
transition: all var(--transition-fast);
&:hover, &.active {
color: var(--color-primary);
background: var(--color-primary-light);
}
}
.navbar__actions {
display: flex;
align-items: center;
gap: var(--space-md);
}
}@layer components {
.hero {
display: grid;
place-items: center;
min-height: min(70vh, 500px);
padding-block: var(--space-3xl);
padding-inline: var(--space-xl);
text-align: center;
position: relative;
overflow: hidden;
}
.hero__bg {
position: absolute;
inset: 0;
background:
radial-gradient(ellipse at 30% 20%, color-mix(in oklch, var(--color-primary) 15%, transparent), transparent 60%),
radial-gradient(ellipse at 70% 80%, color-mix(in oklch, var(--color-secondary) 10%, transparent), transparent 60%);
z-index: -1;
}
.hero__title {
font-size: var(--font-size-hero);
font-weight: 800;
line-height: 1.1;
letter-spacing: -0.02em;
max-width: 20ch;
background: linear-gradient(135deg, var(--text-primary) 0%, var(--color-primary) 100%);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
}
.hero__subtitle {
font-size: var(--font-size-xl);
color: var(--text-secondary);
max-width: 45ch;
margin-block-start: var(--space-lg);
}
.hero__actions {
display: flex;
flex-wrap: wrap;
gap: var(--space-md);
margin-block-start: var(--space-2xl);
justify-content: center;
}
}@layer layout {
.features {
padding-block: var(--space-3xl);
padding-inline: var(--space-xl);
}
.features__grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
gap: var(--space-xl);
max-width: var(--container-max);
margin-inline: auto;
}
}@layer components {
.feature-card {
container-type: inline-size;
container-name: feature-card;
background: var(--bg-surface);
border: 1px solid var(--border-default);
border-radius: var(--radius-xl);
padding: var(--space-xl);
transition: all var(--transition-base);
&:hover {
border-color: var(--border-hover);
box-shadow: var(--shadow-lg), var(--shadow-glow);
transform: translateY(-4px);
}
}
.feature-card__icon {
display: grid;
place-items: center;
width: 3rem;
height: 3rem;
border-radius: var(--radius-lg);
background: var(--color-primary-light);
color: var(--color-primary);
font-size: 1.5rem;
margin-block-end: var(--space-md);
}
.feature-card__title {
font-size: var(--font-size-lg);
font-weight: 700;
margin-block-end: var(--space-sm);
}
.feature-card__description {
font-size: var(--font-size-sm);
color: var(--text-secondary);
line-height: 1.7;
}
@container feature-card (min-width: 400px) {
.feature-card {
display: grid;
grid-template-columns: auto 1fr;
grid-template-rows: auto auto;
gap: var(--space-sm) var(--space-lg);
align-items: start;
}
.feature-card__icon {
grid-row: 1 / -1;
width: 4rem;
height: 4rem;
font-size: 2rem;
}
.feature-card__title { margin-block-end: 0; }
}
}@layer layout {
.footer {
display: grid;
place-items: center;
gap: var(--space-lg);
padding-block: var(--space-3xl) var(--space-xl);
padding-inline: var(--space-xl);
border-block-start: 1px solid var(--border-default);
background: var(--bg-muted);
text-align: center;
}
.footer__links {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: var(--space-md) var(--space-xl);
list-style: none;
}
.footer__copy {
font-size: var(--font-size-sm);
color: var(--text-muted);
}
}نستخدم CSS Variables مع light-dark() لإنشاء نظام سمات ذكي دون JavaScript معقد.
:root { color-scheme: light dark; }
.card {
background: light-dark(#ffffff, #1e293b);
color: light-dark(#0f172a, #f1f5f9);
}const STORAGE_KEY = "theme";
const html = document.documentElement;
function getPreferredTheme() {
const stored = localStorage.getItem(STORAGE_KEY);
if (stored) return stored;
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
}
function setTheme(theme) {
html.style.colorScheme = theme;
localStorage.setItem(STORAGE_KEY, theme);
}
setTheme(getPreferredTheme());[data-theme="ocean"] {
--color-primary: oklch(0.6 0.15 230);
--bg-page: light-dark(#f0f9ff, #0c1929);
}
[data-theme="forest"] {
--color-primary: oklch(0.6 0.18 155);
--bg-page: light-dark(#f0fdf4, #0a1f0a);
}تجلب الرسوم المتحركة الحياة للتصميم. نستخدم Transitions للتأثيرات البسيطة و Keyframes للرسوم المتحركة المعقدة.
@layer animations {
.btn {
position: relative;
display: inline-flex;
align-items: center;
gap: var(--space-sm);
padding: var(--space-sm) var(--space-xl);
font-size: var(--font-size-base);
font-weight: 600;
border: none;
border-radius: var(--radius-lg);
cursor: pointer;
overflow: hidden;
transition: all var(--transition-base);
}
.btn--primary {
background: var(--color-primary);
color: light-dark(#ffffff, #ffffff);
box-shadow: var(--shadow-md);
}
.btn--primary:hover {
background: var(--color-primary-hover);
box-shadow: var(--shadow-lg), var(--shadow-glow);
transform: translateY(-2px);
}
.btn--outline {
background: transparent;
color: var(--color-primary);
border: 2px solid var(--color-primary);
}
.btn--outline:hover {
background: var(--color-primary);
color: light-dark(#ffffff, #ffffff);
transform: translateY(-2px);
}
}@layer animations {
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
@keyframes pulse-glow {
0%, 100% { box-shadow: 0 0 0 0 color-mix(in oklch, var(--color-primary) 40%, transparent); }
50% { box-shadow: 0 0 20px 5px color-mix(in oklch, var(--color-primary) 20%, transparent); }
}
@keyframes fade-in-up {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.hero__title { animation: fade-in-up 0.8s ease-out both; }
.hero__subtitle { animation: fade-in-up 0.8s 0.2s ease-out both; }
.hero__actions { animation: fade-in-up 0.8s 0.4s ease-out both; }
.feature-card { animation: fade-in-up 0.6s ease-out both; }
.feature-card:nth-child(1) { animation-delay: 0.1s; }
.feature-card:nth-child(2) { animation-delay: 0.2s; }
.feature-card:nth-child(3) { animation-delay: 0.3s; }
.feature-card:hover .feature-card__icon {
animation: float 2s ease-in-out infinite;
}
}@layer animations {
@keyframes reveal {
from { opacity: 0; transform: translateY(40px) scale(0.96); }
to { opacity: 1; transform: translateY(0) scale(1); }
}
.feature-card {
animation: reveal linear both;
animation-timeline: view();
animation-range: entry 0% entry 100%;
}
}1. ابدأ دائماً بـ CSS Variables — هي أساس كل شيء
2. استخدم @layer لتنظيم الكود وتجنب مشاكل النوعية
3. clamp() يلغي الحاجة إلى العديد من Media Queries — استخدمه للخطوط والأحجام
4. light-dark() يجعل دعم السمات سهلاً للغاية
5. الخصائص المنطقية (inline/block) تجعل الموقع جاهزاً للعربية والإنجليزية
6. Container Queries تجعل المكونات مرنة حقاً بشكل مستقل عن الصفحة
7. CSS Nesting يجعل الكود أكثر طبيعية في القراءة وأسهل في الصيانة
ما الفرق بين CSS Grid و Flexbox في هذا المشروع؟
لماذا نستخدم oklch() بدلاً من hex أو rgb؟
ما فائدة @layer في هذا المشروع؟
أنشئ قسماً جديداً بعنوان 'ماذا يقول عملاؤنا' مع 3 بطاقات شهادات متحركة. يجب أن تتضمن كل بطاقة: صورة المستخدم (بديل)، الاسم، المنصب، والشهيدة. استخدم CSS Grid مع auto-fit/minmax، وأضف رسوم متحركة لكشف عند التمرير، واجعل البطاقات تتكيف مع Container Queries.
الحل:
/* Add your testimonials section CSS here */الدرس 1: أساسيات CSS
box-sizing: border-box — احسب الحشو + الحد داخل العرض
rem — نسبي للجذر، مثالي للخطوط
em — نسبي للأب، يتراكم في التداخل
clamp(min, preferred, max) — قيمة سائلة
oklch(L C H) — لون محسّن لإدراك humans البشري
color-mix(in oklch, c1, c2) — خلط لونين
light-dark(#fff, #111) — لون تلقائي حسب السمة
النوعية: element < class < id < inline < !importantالدرس 3: Flexbox
display: flex — تفعيل Flexbox
flex-direction: row / column — اتجاه المحور الرئيسي
justify-content: space-between / center — توزيع المحور الرئيسي
align-items: center / stretch — محاذاة المحور المتقاطع
gap: 1rem — مسافة بين العناصر
flex: 1 1 auto — اختصار grow/shrink/basisالدرس 4: CSS Grid
display: grid — تفعيل Grid
grid-template-columns: repeat(3, 1fr) — تعريف الأعمدة
auto-fit: repeat(auto-fit, minmax(250px, 1fr)) — أعمدة سائلة
place-items: center — توسيط أفقي + عمودي (سطر واحد)
grid-column: span 2 — امتداد عمودينالدرس 5: Media Queries والاستجابة
min-width: @media (width >= 768px) — شاشات كبيرة+
Container Queries: @container (min-width: 400px) — التكيف مع الحاوية
container-type: inline-size — تفعيل الاستعلام
clamp() — بديل عن Media Queries
الخصائص المنطقية: margin-inline / padding-block — دعم RTLالدرس 6: الألوان والسمات
CSS Variables: --name: value; — تعريف متغير
var(--name, fallback) — استخدام متغير
oklch(0.65 0.19 145) — لون حديث
color-mix(in oklch, blue 50%, red) — خلط
light-dark(#fff, #111) — ألوان السمة
color-scheme: light dark — تفعيل كلا الوضعين
@layer: @layer base, components; — تنظيم الأولوياتالدرس 7: الرسوم المتحركة والتأثيرات
transition: all 0.3s ease — انتقال سلس
cubic-bezier(0.4, 0, 0.2, 1) — منحنى حركة مخصص
@keyframes name { from {} to {} } — رسوم متحركة مخصصة
animation: fade-in 0.5s ease both — تطبيق رسوم متحركة
transform: translateY(-4px) / scale(1.05) — تحويل بصري
animation-timeline: view() — رسوم متحركة مدفوعة بالتمرير
will-change: transform — تلميح أداء الرسوم المتحركة
prefers-reduced-motion: reduce — احترام الحركة المخفضةالدرس 8: المشروع التطبيقي
CSS Nesting — تنظيم الكود الطبيع داخل القواعد
@layer — فصل base / components / layout / utilities
clamp() — طباعة وأحجام سائلة
CSS Grid + auto-fit/minmax — شبكة بطاقات متجاوبة
Flexbox — شريط التنقل وتوزيع العناصر
Container Queries — البطاقات تتكيف مع حاويتها
الخصائص المنطقية: margin-inline / padding-block لـ RTL
light-dark() + Variables — نظام سمات متكامل
oklch + color-mix — ألوان حديثة وتدرجات
Transitions + Keyframes — رسوم متحركة وتأثيرات سلسة
backdrop-filter — تأثير ضباب على شريط التنقل