تخطَّ إلى المحتوى
NerdLevelTech
تطوير الواجهة الأمامية

مقدمة في عرض CSS التقديمي - الجزء الأول

CSS الحديث من الصفر (الجزء الأول): المحددات (selectors)، ونموذج الصندوق (the box model)، و Flexbox، و Grid، و Container Queries، و :has(). صمم أول صفحة حقيقية ليك بـ CSS بتاع النهاردة.

Nerd Level Techنُشر في تم التحديث ٨ دقائق للقراءةEnglish
صورة غلاف: مقدمة في عرض CSS التقديمي - الجزء الأول

ملخص

تتمحور لغة CSS الحديثة (٢٠٢٦) حول استعلامات الحاوية (Container Queries)، ومحدد :has()، وطبقات التتابع (Cascade Layers)، والتداخل الأصلي (native nesting). تظل Grid و Flexbox هي أسس التخطيط. تدير خصائص CSS المخصصة رموز التصميم. يضيف Tailwind CSS 4 التداخل الأصلي وتحسينات في الأداء، ولكن يمكن لـ CSS الخام الآن القيام بالكثير مما يفعله Tailwind.

إذا كان آخر تعمق لك في CSS قبل بضع سنوات، فاستعد للمفاجآت. لقد تطورت CSS بشكل كبير. اللغة التي كانت تبدو محدودة ذات يوم — "مجرد تنسيق" — تتعامل الآن مع تعقيد التخطيط، والمنطق (:has())، ورموز التصميم، والتكيف المتجاوب الذي كان يتطلب سابقًا JavaScript أو أدوات بناء.

يغطي هذا الدليل أساسيات CSS الحديثة لعام ٢٠٢٦: أدوات التخطيط الأساسية التي احتجتها دائمًا (Grid، Flexbox)، والميزات الثورية (استعلامات الحاوية)، وتحسينات الصيغة (التداخل الأصلي) التي تجعل كتابة CSS أكثر متعة. سواء كنت تبدأ من الصفر أو تحاول اللحاق بالركب، فإن فهم هذه الأساسيات يفتح لك الباب للبقية.

CSS Grid و Flexbox: أساس التخطيط

Grid و Flexbox ليسا ميزتين متقدمتين — بل هما أساسيتان. يستخدم كل تخطيط حديث أحدهما أو كليهما.

Flexbox: تخطيط أحادي الأبعاد

يقوم Flexbox بترتيب العناصر في اتجاه واحد (صف أو عمود).

css
/* Navigation bar: items in a row */
.nav {
  display: flex;
  gap: 1rem;
  justify-content: space-between; /* Space between nav items and logo */
  align-items: center; /* Vertically centered */
}

/* Form: items in a column */
.form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* Responsive: row on desktop, column on mobile */
@media (max-width: 768px) {
  .nav {
    flex-direction: column;
  }
}

الخصائص الرئيسية:

  • flex-direction: row | column
  • justify-content: يتحكم في التباعد على طول المحور الرئيسي (اتجاه الصف/العمود)
  • align-items: يتحكم في المحاذاة العمودية على المحور الرئيسي
  • flex-wrap: يلف العناصر إلى أسطر متعددة
  • gap: المسافة بين العناصر

CSS Grid: تخطيط ثنائي الأبعاد

يقوم Grid بترتيب العناصر في صفوف و أعمدة في وقت واحد.

css
/* Dashboard layout */
.dashboard {
  display: grid;
  grid-template-columns: 250px 1fr 300px; /* Sidebar, main, aside */
  grid-template-rows: auto 1fr auto; /* Header, content, footer */
  gap: 1rem;
  height: 100vh;
}

.header {
  grid-column: 1 / -1; /* Span all columns */
}

.sidebar {
  grid-column: 1;
  grid-row: 2;
}

.main {
  grid-column: 2;
  grid-row: 2;
}

.footer {
  grid-column: 1 / -1;
}

الفرق: متى تستخدم كل منهما

التخطيطFlexboxGrid
شريط التنقل (Navigation bar)✓
قائمة المنتجات (عمود واحد)✓
مدخلات النموذج (Form inputs)✓
لوحة التحكم (2D)✓
شبكة بطاقات مع subgrid✓
شريط جانبي + محتوى رئيسي✓

تستخدم معظم التخطيطات المعقدة كليهما:

css
.dashboard {
  display: grid;
  grid-template-columns: 250px 1fr;
}

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1rem;
}

.card {
  display: flex;
  flex-direction: column;
}

يتولى Grid هيكل الصفحة، بينما يتولى Flexbox تخطيطات المكونات الفردية.

خصائص CSS المخصصة (المتغيرات)

تخزن الخصائص المخصصة قيمًا قابلة لإعادة الاستخدام. إنها ديناميكية (يمكن أن تتغير في وقت التشغيل) على عكس متغيرات SASS/LESS.

الاستخدام الأساسي

css
:root {
  --color-primary: #0066ff;
  --color-text: #333;
  --spacing-base: 1rem;
  --radius: 0.5rem;
}

button {
  background: var(--color-primary);
  padding: var(--spacing-base);
  border-radius: var(--radius);
  color: white;
}

التنسيق الديناميكي (Theming)

css
/* Light theme (default) */
:root {
  --bg: #ffffff;
  --text: #000000;
}

/* Dark theme */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #1a1a1a;
    --text: #ffffff;
  }
}

/* User-selected dark mode */
body.dark-mode {
  --bg: #1a1a1a;
  --text: #ffffff;
}

body {
  background: var(--bg);
  color: var(--text);
}

المتغيرات محددة النطاق

css
.card {
  --card-bg: #f5f5f5;
  --card-padding: 1.5rem;
}

.card-header {
  background: var(--card-bg);
  padding: var(--card-padding);
}

/* Different card style */
.card.featured {
  --card-bg: #ffd700;
  --card-padding: 2rem;
  /* Header automatically uses new values */
}

استعلامات الحاوية: المكونات تتكيف مع السياق

سابقًا، كانت توجد استعلامات الوسائط (media queries) فقط — وهي تقيس نافذة العرض (viewport). أما استعلامات الحاوية (Container Queries) فتقيس حاوية المكون نفسه. وصلت استعلامات حجم الحاوية إلى حالة "Baseline Newly Available" في فبراير ٢٠٢٣ و "Baseline Widely Available" في أغسطس ٢٠٢٥، لذا فهي آمنة للاستخدام في الإنتاج اليوم.

css
/* Define a container context */
.card-container {
  container-type: inline-size;
}

/* Query the container's width */
@container (min-width: 400px) {
  .card-content {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
}

@container (max-width: 300px) {
  .card-content {
    display: block;
  }
}

المكون الموجود داخل شريط جانبي بعرض ٢٥٠ بكسل يظهر كعمود واحد. نفس المكون في منطقة رئيسية بعرض ٨٠٠ بكسل يظهر كعمودين. نفس الكود، سياقات مختلفة.

هذا أمر ثوري لأن المكونات أصبحت الآن قابلة لإعادة الاستخدام حقًا وواعية بالسياق.

محدد :has()

يختار :has() العناصر بناءً على أبنائها أو أشقائها. إنه "اختيار الأب" — وهو أمر لم يكن بإمكان CSS القيام به من قبل. وصل :has() إلى "Baseline Newly Available" في ديسمبر ٢٠٢٣ (كان Firefox 121 هو الأخير في دعمه) وهو متاح على نطاق واسع عبر المتصفحات الحديثة.

css
/* Select card if it contains an image */
.card:has(img) {
  display: grid;
  grid-template-columns: 200px 1fr;
}

/* Select form if it has an error */
.form:has(.error) {
  border: 2px solid red;
}

/* Select heading followed by text */
h2:has(+ p) {
  margin-bottom: 0.5rem;
}

/* Style based on input state */
form:has(input:invalid) {
  background: #ffe0e0;
}

/* Dark mode: if user prefers dark, select background */
@media (prefers-color-scheme: dark) {
  body:has(.dark-mode-toggle:checked) {
    --bg: #1a1a1a;
  }
}

يسمح :has() بسلوك متجاوب عبر CSS فقط دون الحاجة لاستعلامات الوسائط.

طبقات التتابع وتداخل CSS

طبقات التتابع (Cascade Layers)

تحكم في تعارضات الخصوصية (specificity) باستخدام الطبقات:

css
/* Define layer order */
@layer reset, base, theme, components, utilities;

@layer reset {
  * { margin: 0; padding: 0; }
}

@layer base {
  body { font-family: system-ui; }
}

@layer theme {
  :root {
    --color-primary: blue;
  }
}

@layer components {
  .button { background: var(--color-primary); }
}

@layer utilities {
  .text-center { text-align: center; }
}

/* Utilities override components override theme—determined by layer order */

تمنع الطبقات حروب الخصوصية. فالفئة المساعدة (utility class) في طبقة utilities ستتجاوز دائمًا المكون في طبقة components، بغض النظر عن مدى خصوصية المحدد.

تداخل CSS الأصلي

وصل التداخل الأصلي إلى "Baseline Newly Available" في أغسطس ٢٠٢٣ (Chrome 112، Safari 16.5، Firefox 117). لا مزيد من تكرار المحددات:

css
/* Before: repetition */
.card { border: 1px solid #ccc; }
.card-header { background: #f5f5f5; }
.card-body { padding: 1rem; }

/* After: native nesting */
.card {
  border: 1px solid #ccc;

  & .header {
    background: #f5f5f5;
  }

  & .body {
    padding: 1rem;
  }

  /* Hover state */
  &:hover {
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
  }

  /* Media query inside */
  @media (max-width: 600px) {
    flex-direction: column;
  }
}

يشير محدد & إلى العنصر الأب. هذه الصيغة أصبحت الآن CSS أصلي (لا حاجة لـ Sass).

انتقالات العرض (View Transitions) API

وصلت انتقالات العرض لنفس المستند إلى "Baseline Newly Available" في أكتوبر ٢٠٢٥ بمجرد أن قدم Firefox 133 الدعم لها، لتنضم إلى Chrome 111+ و Safari 18+. تعمل الانتقالات عبر المستندات (تطبيقات متعددة الصفحات) في Chrome 126+ و Safari 18.2+ ولكنها غير مدعومة بعد في Firefox اعتبارًا من مايو ٢٠٢٦ — استخدم التحسين التدريجي (progressive enhancement).

قم بعمل حركات (animation) بين حالات الصفحة:

css
.modal {
  view-transition-name: modal;
}

@supports (view-transition-name: modal) {
  ::view-transition-new(modal) {
    animation: slideUp 0.5s;
  }

  @keyframes slideUp {
    from {
      opacity: 0;
      transform: translateY(50px);
    }
  }
}

عند الانتقال إلى حالة نافذة منبثقة (modal) جديدة، يقوم المتصفح تلقائيًا بعمل حركة بين الحالتين القديمة والجديدة.

JavaScript
document.startViewTransition(() => {
  updateDOM(); // Change the DOM
  // Browser automatically animates the transition
});

يخلق هذا انتقالات سلسة دون الحاجة لمنطق حركات JavaScript يدوي.

Tailwind CSS 4 مقابل Vanilla CSS

تم إطلاق Tailwind CSS v4.0 في ٢٢ يناير ٢٠٢٥؛ ويستمر خط v4.x في التطور (أضاف v4.2 مكون إضافي لـ webpack وأدوات الخصائص المنطقية في فبراير ٢٠٢٦). تجلب بنية v4 ما يلي:

  • تداخل CSS الأصلي في ملفات المصدر
  • خصائص CSS المخصصة لتخصيص السمة (لا حاجة لتكوين JS)
  • محرك Oxide الجديد — بناء كامل أسرع حتى ٥ مرات، وبناء تدريجي في أجزاء من الثانية
  • إعداد من سطر واحد (@import "tailwindcss") مع اكتشاف تلقائي للقوالب

متى تستخدم Tailwind:

  • النماذج الأولية السريعة (أدوات متجاوبة جاهزة)
  • توحيد معايير الفريق (تباعد وألوان متسقة)
  • الاحتياجات المتجاوبة المعقدة (مع دعم استعلامات الحاوية)

متى يكون CSS الخام كافيًا:

  • المواقع البسيطة والثابتة
  • أنظمة التصميم التي نادرًا ما تتغير
  • عندما تبدو أدوات البناء مبالغًا فيها
  • الفرق التي تشعر بالراحة مع CSS

مثال: نفس المكون في Tailwind مقابل CSS الخام:

Tailwind:

jsx
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 p-4">
  <div className="border rounded-lg p-4 hover:shadow-lg">
    <h3 className="text-lg font-bold mb-2">Title</h3>
    <p>Content</p>
  </div>
</div>

CSS الخام مع الميزات الحديثة:

jsx
<div className="card-grid">
  <article className="card">
    <h3>Title</h3>
    <p>Content</p>
  </article>
</div>

<style>
  .card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 1rem;
    padding: 1rem;
  }

  .card {
    border: 1px solid #ccc;
    border-radius: 0.5rem;
    padding: 1rem;

    &:hover {
      box-shadow: 0 4px 8px rgba(0,0,0,0.1);
    }
  }
</style>

كلاهما صحيح. اختر بناءً على احتياجات المشروع، وليس بناءً على الضجة المثارة.

@starting-style للانتقالات

وصلت @starting-style إلى "Baseline Newly Available" في أغسطس ٢٠٢٤. وهي تحدد القيم التي ينتقل العنصر منها عند عرضه لأول مرة (أو عند عودته إلى DOM):

css
.toast {
  opacity: 1;
  transform: translateX(0);
  transition: opacity 0.3s, transform 0.3s;
}

/* The "from" state — applied only on first render */
@starting-style {
  .toast {
    opacity: 0;
    transform: translateX(-100%);
  }
}

عند إضافة .toast إلى DOM، يطبق المتصفح قيم @starting-style أولاً، ثم ينتقل إلى قيم .toast العادية. هذا يجعل من الممكن أخيرًا تحريك العناصر التي تظهر من display: none دون الحاجة لحيل JavaScript.

أهم النقاط المستفادة

تتعامل CSS الحديثة (٢٠٢٦) مع ما كان يتطلب سابقًا JavaScript أو أدوات بناء:

  1. Grid و Flexbox: أتقنهما لأي تخطيط.
  2. الخصائص المخصصة: رموز تصميم ديناميكية ومحددة النطاق.
  3. استعلامات الحاوية: أنماط مكونات واعية بالسياق.
  4. محدد :has(): منطق CSS فقط بناءً على العناصر التابعة.
  5. التداخل الأصلي: صيغة أنظف وأكثر اختصارًا (DRY).
  6. طبقات التتابع: إدارة الخصوصية (specificity).
  7. انتقالات العرض API: انتقالات سلسة بين الحالات.
  • @starting-style: حركات الدخول
  • CSS لم يعد مجرد تنسيق. إنها لغة قوية للتخطيط والمنطق والتفاعل. كلما تعلمت CSS الحديثة أكثر، قل احتياجك لـ JavaScript للعرض.

    ابقَ على مسار النيرد

    رسالتان كلّ أسبوع: شرح معمّق لموضوع واحد يوم الاثنين، وملخّص يوم الخميس للدورات والأدلّة والمقالات والبودكاست والوظائف.

    بدون إزعاج. إلغاء الاشتراك في أي وقت.