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 والموضع للتحكم الدقيق في موضع العناصر.