CSS Grid: دليل شامل للتخطيط الشبكي المتقدم والتحكم ثنائي الأبعاد

CSS

CSS Grid: دليل شامل للتخطيط الشبكي المتقدم والتحكم ثنائي الأبعاد
إتقان CSS Grid - التخطيط الشبكي، المناطق، المحاذاة، والتحكم الدقيق في الصفوف والأعمدة. دليل عملي للتخطيطات المعقدة.
#CSS#Grid#Layout#Responsive#Advanced#Frontend#Web Design

CSS Grid: دليل شامل للتخطيط الشبكي المتقدم والتحكم ثنائي الأبعاد

دليل تخصصي من علاء عامر – مطور ومصمم مواقع وتطبيقات محترف

CSS Grid هو نظام التخطيط الأقوى للتحكم في الصفوف والأعمدة. تعلم إنشاء تخطيطات معقدة ومتجاوبة بدقة عالية.


1️⃣ مفاهيم Grid الأساسية

إنشاء Grid Container

.grid-container {
  display: grid; /* تحويل العنصر لـ grid container */

  /* أو للعناصر السطرية */
  display: inline-grid;
}

/* تعريف الشبكة الأساسية */
.basic-grid {
  display: grid;
  grid-template-columns: 200px 1fr 100px; /* 3 أعمدة */
  grid-template-rows: auto 1fr auto; /* 3 صفوف */
  gap: 20px;
  min-height: 100vh;
}

وحدات Grid الخاصة

.grid-units {
  display: grid;

  /* وحدة fr - الجزء المرن */
  grid-template-columns: 1fr 2fr 1fr; /* 1:2:1 */

  /* وحدة repeat */
  grid-template-columns: repeat(3, 1fr); /* 3 أعمدة متساوية */
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); /* متجاوب */

  /* وحدة minmax */
  grid-template-columns: minmax(200px, 1fr) 300px;

  /* وحدة auto */
  grid-template-columns: auto 1fr auto; /* حسب المحتوى */
}

2️⃣ تعريف الأعمدة والصفوف

.grid-definition {
  display: grid;

  /* تعريف الأعمدة */
  grid-template-columns:
    200px /* عمود ثابت */
    1fr /* عمود مرن */
    minmax(100px, 200px) /* عمود بحد أدنى وأقصى */
    auto; /* حسب المحتوى */

  /* تعريف الصفوف */
  grid-template-rows:
    60px /* رأس ثابت */
    1fr /* محتوى مرن */
    50px; /* ذيل ثابت */

  /* تعريف باستخدام أسماء الخطوط */
  grid-template-columns:
    [sidebar-start] 250px
    [sidebar-end main-start] 1fr
    [main-end aside-start] 200px
    [aside-end];
}

/* أمثلة متقدمة */
.responsive-columns {
  display: grid;

  /* شبكة متجاوبة */
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
  padding: 20px;
}

.magazine-layout {
  display: grid;
  grid-template-columns:
    1fr /* المحتوى الرئيسي */
    300px /* الشريط الجانبي */
    200px; /* الإعلانات */
  grid-template-rows:
    80px /* الرأس */
    1fr /* المحتوى */
    60px; /* الذيل */
  gap: 20px;
  min-height: 100vh;
}

3️⃣ وضع العناصر في الشبكة

/* وضع العناصر بالأرقام */
.grid-positioning {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(3, 100px);
  gap: 10px;
}

.item-1 {
  grid-column: 1 / 3; /* من العمود 1 إلى 3 */
  grid-row: 1 / 2; /* الصف الأول */
}

.item-2 {
  grid-column: 3 / 5; /* من العمود 3 إلى 5 */
  grid-row: 1 / 3; /* من الصف 1 إلى 3 */
}

/* استخدام span */
.item-3 {
  grid-column: span 2; /* يمتد عبر عمودين */
  grid-row: span 1; /* يمتد عبر صف واحد */
}

/* اختصار شامل */
.item-4 {
  grid-area: 2 / 1 / 4 / 3; /* row-start / col-start / row-end / col-end */
}

/* وضع باستخدام أسماء الخطوط */
.named-lines-grid {
  display: grid;
  grid-template-columns:
    [sidebar-start] 250px
    [sidebar-end content-start] 1fr
    [content-end];
  grid-template-rows:
    [header-start] 80px
    [header-end main-start] 1fr
    [main-end];
}

.sidebar-item {
  grid-column: sidebar-start / sidebar-end;
  grid-row: main-start / main-end;
}

4️⃣ Grid Areas - المناطق المحددة

.layout-areas {
  display: grid;
  grid-template-areas:
    "header header header"
    "sidebar main aside"
    "footer footer footer";
  grid-template-columns: 200px 1fr 150px;
  grid-template-rows: 80px 1fr 60px;
  gap: 20px;
  min-height: 100vh;
}

/* تعيين العناصر للمناطق */
.header {
  grid-area: header;
}
.sidebar {
  grid-area: sidebar;
}
.main {
  grid-area: main;
}
.aside {
  grid-area: aside;
}
.footer {
  grid-area: footer;
}

/* تخطيط متجاوب بتغيير المناطق */
@media (max-width: 768px) {
  .layout-areas {
    grid-template-areas:
      "header"
      "main"
      "sidebar"
      "aside"
      "footer";
    grid-template-columns: 1fr;
    grid-template-rows: auto auto auto auto auto;
  }
}

/* تخطيط مجلة معقد */
.magazine-areas {
  display: grid;
  grid-template-areas:
    "header header header header"
    "hero hero sidebar-1 sidebar-1"
    "article-1 article-2 sidebar-1 sidebar-1"
    "article-3 article-3 sidebar-2 ads"
    "footer footer footer footer";
  grid-template-columns: 1fr 1fr 200px 150px;
  gap: 20px;
}

5️⃣ المحاذاة في Grid

.grid-alignment {
  display: grid;
  grid-template-columns: repeat(3, 200px);
  grid-template-rows: repeat(3, 100px);
  gap: 10px;

  /* محاذاة الشبكة كاملة داخل الحاوي */
  justify-content: center; /* أفقي */
  align-content: center; /* عمودي */

  /* أو */
  place-content: center; /* اختصار للاثنين */

  /* توزيع المحتوى */
  justify-content: space-between;
  justify-content: space-around;
  justify-content: space-evenly;

  /* محاذاة العناصر داخل خلاياها */
  justify-items: center; /* أفقي */
  align-items: center; /* عمودي */
  place-items: center; /* اختصار للاثنين */
}

/* محاذاة عنصر واحد */
.special-grid-item {
  justify-self: end; /* أفقي */
  align-self: start; /* عمودي */
  place-self: center; /* اختصار للاثنين */
}

/* مثال عملي - بطاقات محاذاة */
.cards-grid-aligned {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
  align-items: start; /* جميع البطاقات من الأعلى */
}

.card-content-centered {
  display: grid;
  place-items: center; /* توسيط المحتوى */
  min-height: 200px;
  text-align: center;
}

6️⃣ Grid المتجاوب المتقدم

/* شبكة متجاوبة بالكامل */
.responsive-advanced-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
  padding: 20px;
}

/* تخطيطات مختلفة للشاشات */
.adaptive-layout {
  display: grid;
  gap: 20px;

  /* الشاشات الكبيرة */
  grid-template-columns: 250px 1fr 200px;
  grid-template-areas:
    "sidebar main aside"
    "sidebar main aside";
}

@media (max-width: 1024px) {
  .adaptive-layout {
    /* الشاشات المتوسطة */
    grid-template-columns: 200px 1fr;
    grid-template-areas:
      "sidebar main"
      "aside aside";
  }
}

@media (max-width: 768px) {
  .adaptive-layout {
    /* الشاشات الصغيرة */
    grid-template-columns: 1fr;
    grid-template-areas:
      "main"
      "sidebar"
      "aside";
  }
}

/* شبكة بكثافة مختلفة */
.density-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 15px;
}

.featured-item {
  grid-column: span 6; /* نصف العرض */
}

.regular-item {
  grid-column: span 4; /* ثلث العرض */
}

.small-item {
  grid-column: span 3; /* ربع العرض */
}

@media (max-width: 768px) {
  .featured-item,
  .regular-item,
  .small-item {
    grid-column: span 12; /* عرض كامل على الموبايل */
  }
}

7️⃣ مشروع عملي: لوحة تحكم متقدمة

<!DOCTYPE html>
<html lang="ar" dir="rtl">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>لوحة التحكم المتقدمة</title>
    <link rel="stylesheet" href="grid-dashboard.css" />
  </head>
  <body>
    <div class="dashboard">
      <!-- الرأس -->
      <header class="dashboard-header">
        <div class="logo">
          <h1>لوحة التحكم</h1>
        </div>
        <div class="header-controls">
          <input type="search" placeholder="بحث..." class="search-input" />
          <div class="user-profile">
            <span>أحمد محمد</span>
            <div class="avatar">أ</div>
          </div>
        </div>
      </header>

      <!-- الشريط الجانبي -->
      <nav class="sidebar">
        <div class="nav-section">
          <h3>الرئيسية</h3>
          <ul class="nav-menu">
            <li><a href="#" class="active">نظرة عامة</a></li>
            <li><a href="#">التحليلات</a></li>
            <li><a href="#">التقارير</a></li>
          </ul>
        </div>
        <div class="nav-section">
          <h3>البيانات</h3>
          <ul class="nav-menu">
            <li><a href="#">المستخدمون</a></li>
            <li><a href="#">المنتجات</a></li>
            <li><a href="#">الطلبات</a></li>
          </ul>
        </div>
      </nav>

      <!-- المحتوى الرئيسي -->
      <main class="main-content">
        <!-- بطاقات الإحصائيات -->
        <section class="stats-cards">
          <div class="stat-card primary">
            <div class="stat-icon">👥</div>
            <div class="stat-info">
              <h3>المستخدمون</h3>
              <p class="stat-number">12,456</p>
              <p class="stat-change positive">+12%</p>
            </div>
          </div>

          <div class="stat-card success">
            <div class="stat-icon">💰</div>
            <div class="stat-info">
              <h3>المبيعات</h3>
              <p class="stat-number">85,230</p>
              <p class="stat-change positive">+8%</p>
            </div>
          </div>

          <div class="stat-card warning">
            <div class="stat-icon">📦</div>
            <div class="stat-info">
              <h3>الطلبات</h3>
              <p class="stat-number">3,421</p>
              <p class="stat-change negative">-3%</p>
            </div>
          </div>

          <div class="stat-card info">
            <div class="stat-icon">📊</div>
            <div class="stat-info">
              <h3>التحليلات</h3>
              <p class="stat-number">98.5%</p>
              <p class="stat-change positive">+2%</p>
            </div>
          </div>
        </section>

        <!-- الرسوم البيانية -->
        <section class="charts-section">
          <div class="chart-card large">
            <div class="card-header">
              <h3>نظرة عامة على المبيعات</h3>
              <select class="time-filter">
                <option>آخر 7 أيام</option>
                <option>آخر 30 يوم</option>
                <option>آخر 3 أشهر</option>
              </select>
            </div>
            <div class="chart-placeholder">
              <p>رسم بياني للمبيعات</p>
            </div>
          </div>

          <div class="chart-card medium">
            <div class="card-header">
              <h3>توزيع المستخدمين</h3>
            </div>
            <div class="chart-placeholder">
              <p>رسم دائري</p>
            </div>
          </div>
        </section>

        <!-- جداول البيانات -->
        <section class="data-tables">
          <div class="table-card">
            <div class="card-header">
              <h3>أحدث الطلبات</h3>
              <button class="view-all-btn">عرض الكل</button>
            </div>
            <div class="table-container">
              <table class="data-table">
                <thead>
                  <tr>
                    <th>رقم الطلب</th>
                    <th>العميل</th>
                    <th>المبلغ</th>
                    <th>الحالة</th>
                  </tr>
                </thead>
                <tbody>
                  <tr>
                    <td>#12345</td>
                    <td>محمد أحمد</td>
                    <td>250 ريال</td>
                    <td><span class="status completed">مكتمل</span></td>
                  </tr>
                  <tr>
                    <td>#12346</td>
                    <td>فاطمة محمد</td>
                    <td>180 ريال</td>
                    <td><span class="status pending">قيد المعالجة</span></td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
        </section>
      </main>

      <!-- الشريط الجانبي الثانوي -->
      <aside class="secondary-sidebar">
        <div class="widget">
          <h4>الأنشطة الأخيرة</h4>
          <div class="activity-list">
            <div class="activity-item">
              <div class="activity-icon">✅</div>
              <div class="activity-text">
                <p>تم إكمال طلب جديد</p>
                <small>منذ 5 دقائق</small>
              </div>
            </div>
            <div class="activity-item">
              <div class="activity-icon">👤</div>
              <div class="activity-text">
                <p>مستخدم جديد سجل</p>
                <small>منذ 12 دقيقة</small>
              </div>
            </div>
          </div>
        </div>

        <div class="widget">
          <h4>الإشعارات</h4>
          <div class="notification-list">
            <div class="notification-item important">
              <p>تحديث النظام متاح</p>
              <button class="notification-action">تثبيت</button>
            </div>
          </div>
        </div>
      </aside>
    </div>
  </body>
</html>
/* grid-dashboard.css */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: "Cairo", Arial, sans-serif;
  background: #f5f7fa;
  color: #333;
}

/* تخطيط اللوحة الرئيسي */
.dashboard {
  display: grid;
  grid-template-areas:
    "header header header"
    "sidebar main aside"
    "sidebar main aside";
  grid-template-columns: 250px 1fr 280px;
  grid-template-rows: 70px 1fr;
  min-height: 100vh;
}

/* الرأس */
.dashboard-header {
  grid-area: header;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 30px;
  background: white;
  border-bottom: 1px solid #e0e6ed;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
}

.logo h1 {
  font-size: 1.4rem;
  color: #2d3748;
}

.header-controls {
  display: flex;
  align-items: center;
  gap: 20px;
}

.search-input {
  padding: 8px 15px;
  border: 1px solid #e0e6ed;
  border-radius: 8px;
  width: 250px;
  font-size: 14px;
}

.user-profile {
  display: flex;
  align-items: center;
  gap: 10px;
}

.avatar {
  width: 35px;
  height: 35px;
  background: #4299e1;
  color: white;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
}

/* الشريط الجانبي */
.sidebar {
  grid-area: sidebar;
  background: white;
  border-left: 1px solid #e0e6ed;
  padding: 30px 0;
  overflow-y: auto;
}

.nav-section {
  margin-bottom: 30px;
  padding: 0 25px;
}

.nav-section h3 {
  font-size: 12px;
  text-transform: uppercase;
  color: #a0aec0;
  margin-bottom: 15px;
  font-weight: 600;
}

.nav-menu {
  list-style: none;
}

.nav-menu li {
  margin-bottom: 5px;
}

.nav-menu a {
  display: block;
  padding: 12px 15px;
  color: #4a5568;
  text-decoration: none;
  border-radius: 8px;
  transition: all 0.2s ease;
  font-size: 14px;
}

.nav-menu a:hover,
.nav-menu a.active {
  background: #ebf8ff;
  color: #2b6cb0;
}

/* المحتوى الرئيسي */
.main-content {
  grid-area: main;
  padding: 30px;
  display: grid;
  grid-template-rows: auto auto 1fr;
  gap: 30px;
  overflow-y: auto;
}

/* بطاقات الإحصائيات */
.stats-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
}

.stat-card {
  background: white;
  padding: 25px;
  border-radius: 12px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  display: flex;
  align-items: center;
  gap: 15px;
  transition: transform 0.2s ease;
}

.stat-card:hover {
  transform: translateY(-2px);
}

.stat-icon {
  font-size: 2rem;
  width: 50px;
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
}

.stat-card.primary .stat-icon {
  background: #ebf8ff;
}
.stat-card.success .stat-icon {
  background: #f0fff4;
}
.stat-card.warning .stat-icon {
  background: #fffbeb;
}
.stat-card.info .stat-icon {
  background: #f0f4ff;
}

.stat-info h3 {
  font-size: 14px;
  color: #718096;
  margin-bottom: 5px;
}

.stat-number {
  font-size: 24px;
  font-weight: 700;
  color: #2d3748;
  margin-bottom: 3px;
}

.stat-change {
  font-size: 12px;
  font-weight: 600;
}

.stat-change.positive {
  color: #38a169;
}
.stat-change.negative {
  color: #e53e3e;
}

/* قسم الرسوم البيانية */
.charts-section {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 20px;
}

.chart-card {
  background: white;
  border-radius: 12px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 25px;
  border-bottom: 1px solid #e0e6ed;
}

.card-header h3 {
  font-size: 16px;
  font-weight: 600;
  color: #2d3748;
}

.time-filter {
  padding: 6px 12px;
  border: 1px solid #e0e6ed;
  border-radius: 6px;
  font-size: 13px;
  background: white;
}

.chart-placeholder {
  height: 300px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #a0aec0;
  background: #f7fafc;
}

/* جداول البيانات */
.data-tables {
  display: grid;
  gap: 20px;
}

.table-card {
  background: white;
  border-radius: 12px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}

.view-all-btn {
  padding: 6px 15px;
  background: #4299e1;
  color: white;
  border: none;
  border-radius: 6px;
  font-size: 13px;
  cursor: pointer;
  transition: background 0.2s ease;
}

.view-all-btn:hover {
  background: #3182ce;
}

.table-container {
  overflow-x: auto;
}

.data-table {
  width: 100%;
  border-collapse: collapse;
}

.data-table th,
.data-table td {
  padding: 15px 25px;
  text-align: right;
  border-bottom: 1px solid #e0e6ed;
}

.data-table th {
  background: #f7fafc;
  font-weight: 600;
  font-size: 13px;
  color: #4a5568;
}

.data-table td {
  font-size: 14px;
  color: #2d3748;
}

.status {
  padding: 4px 12px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 600;
}

.status.completed {
  background: #c6f6d5;
  color: #22543d;
}

.status.pending {
  background: #fbd38d;
  color: #744210;
}

/* الشريط الجانبي الثانوي */
.secondary-sidebar {
  grid-area: aside;
  padding: 30px 20px;
  background: #f7fafc;
  border-right: 1px solid #e0e6ed;
  overflow-y: auto;
}

.widget {
  background: white;
  border-radius: 12px;
  padding: 20px;
  margin-bottom: 20px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.widget h4 {
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 15px;
  color: #2d3748;
}

.activity-item,
.notification-item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid #e0e6ed;
}

.activity-item:last-child,
.notification-item:last-child {
  border-bottom: none;
}

.activity-icon {
  font-size: 16px;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f0f4ff;
  border-radius: 6px;
}

.activity-text p {
  font-size: 13px;
  margin-bottom: 3px;
  color: #2d3748;
}

.activity-text small {
  font-size: 11px;
  color: #a0aec0;
}

.notification-item.important {
  background: #fef5e7;
  padding: 15px;
  border-radius: 8px;
  border: none;
}

.notification-action {
  padding: 4px 12px;
  background: #ed8936;
  color: white;
  border: none;
  border-radius: 4px;
  font-size: 11px;
  cursor: pointer;
}

/* التصميم المتجاوب */
@media (max-width: 1024px) {
  .dashboard {
    grid-template-areas:
      "header header"
      "sidebar main"
      "sidebar main";
    grid-template-columns: 200px 1fr;
  }

  .secondary-sidebar {
    display: none;
  }

  .charts-section {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .dashboard {
    grid-template-areas:
      "header"
      "main"
      "main";
    grid-template-columns: 1fr;
  }

  .sidebar {
    display: none;
  }

  .main-content {
    padding: 20px;
  }

  .stats-cards {
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  }
}

الخلاصة

في هذا الدرس تعلمنا:

مفاهيم CSS Grid الأساسيةتعريف الأعمدة والصفوف المتقدموضع العناصر والمناطق المحددةالمحاذاة في Gridالتصميم المتجاوب مع Gridمشروع لوحة تحكم متقدمة

في الدرس القادم سندرس Position والموضع للتحكم الدقيق في موضع العناصر.

📩 تحتاج مساعدة في CSS Grid؟

aboutservicesprojectsBlogscontact