{ "$schema": "../../schemas/code-crispies-module-schema.json", "id": "flexbox", "title": "CSS Flexbox", "description": "أتقن نموذج تخطيط الصندوق المرن للتصاميم المتجاوبة الحديثة", "difficulty": "intermediate", "lessons": [ { "id": "flexbox-1", "title": "Container", "description": "قبل flexbox، كانت حتى التخطيطات البسيطة تتطلب floats أو حيل التموضع أو تخطيطات الجداول. ثورة Flexbox (تخطيط الصندوق المرن) في CSS من خلال توفير نظام تخطيط أحادي البعد مصمم خصيصاً لتوزيع المساحة ومحاذاة المحتوى.

كيف يعمل: عندما تضبط display: flex على عنصر، يصبح حاوية flex. أبناؤه المباشرون يصبحون تلقائياً عناصر flex تتدفق على طول المحور الرئيسي (أفقياً بشكل افتراضي). هذه الخاصية الواحدة تحول العناصر الكتلية المتراصة إلى صف أفقي.

المحوران:
المحور الرئيسي – الاتجاه الأساسي لتدفق العناصر (row = يسار→يمين)
المحور المتقاطع – عمودي على الرئيسي (row = أعلى→أسفل)

.nav {\n  display: flex;\n}
", "task": "قائمة التنقل هذه تتراص عمودياً. أضف display: flex لترتيب الروابط أفقياً.", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui, sans-serif; margin: 0; } .nav { background: #1a1a2e; padding: 1rem; } .nav a { color: white; text-decoration: none; padding: 8px 1rem; border-radius: 4px; } .nav a:hover { background: rgba(255,255,255,0.1); }", "sandboxCSS": "", "codePrefix": ".nav {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "display: flex;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "display", "expected": "flex" }, "message": "اضبط display: flex" } ] }, { "id": "flexbox-2", "title": "Gap", "description": "خاصية gap تضيف تباعداً متسقاً بين عناصر flex بدون الحاجة إلى الهوامش. تُنشئ مساحة فقط بين العناصر، وليس على الحواف.", "task": "أضف gap: 1rem لتوزيع روابط التنقل بالتساوي.", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui, sans-serif; margin: 0; } .nav { background: #1a1a2e; padding: 1rem; display: flex; } .nav a { color: white; text-decoration: none; padding: 8px 1rem; border-radius: 4px; background: rgba(255,255,255,0.1); }", "sandboxCSS": "", "codePrefix": ".nav {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "gap: 1rem;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "gap", "expected": "1rem" }, "message": "اضبط gap: 1rem" } ] }, { "id": "flexbox-3", "title": "Justify Content", "description": "justify-content يوزع العناصر على طول المحور الرئيسي. القيم الشائعة:
flex-start – تجميع في البداية
flex-end – تجميع في النهاية
center – توسيط العناصر
space-between – مسافة متساوية بين العناصر
space-around – مسافة متساوية حول العناصر", "task": "ادفع زر \"Login\" إلى اليمين بضبط justify-content: space-between على التنقل.", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui, sans-serif; margin: 0; } .nav { background: #1a1a2e; padding: 1rem; display: flex; } .links { display: flex; gap: 8px; } .nav a { color: white; text-decoration: none; padding: 8px 1rem; border-radius: 4px; } .nav a:hover { background: rgba(255,255,255,0.1); } .login { background: steelblue; }", "sandboxCSS": "", "codePrefix": ".nav {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "justify-content: space-between;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "justify-content", "expected": "space-between" }, "message": "اضبط justify-content: space-between" } ] }, { "id": "flexbox-4", "title": "Align Items", "description": "align-items يتحكم في المحاذاة على المحور المتقاطع (عمودياً عندما يكون flex-direction هو row). القيم تشمل:
stretch – تمديد للملء (افتراضي)
flex-start – محاذاة للأعلى
flex-end – محاذاة للأسفل
center – توسيط عمودي", "task": "الشعار وروابط التنقل لها ارتفاعات مختلفة. وسّطها عمودياً باستخدام align-items: center.", "previewHTML": "
ACME
", "previewBaseCSS": "body { font-family: system-ui, sans-serif; margin: 0; } .header { background: white; padding: 1rem 2rem; display: flex; justify-content: space-between; border-bottom: 1px solid #eee; } .logo { font-size: 1.5rem; font-weight: bold; color: steelblue; } nav { display: flex; gap: 1rem; } nav a { color: #333; text-decoration: none; font-size: 0.9rem; }", "sandboxCSS": "", "codePrefix": ".header {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "align-items: center;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "align-items", "expected": "center" }, "message": "اضبط align-items: center" } ] }, { "id": "flexbox-5", "title": "Flex Wrap", "description": "بشكل افتراضي، تنضغط عناصر flex في سطر واحد. flex-wrap: wrap يسمح للعناصر بالتدفق إلى أسطر متعددة عندما تنفد المساحة.", "task": "هذه البطاقات تتجاوز الحاوية. أضف flex-wrap: wrap للسماح لها بالانتقال إلى صفوف جديدة.", "previewHTML": "
Card 1
Card 2
Card 3
Card 4
Card 5
Card 6
", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; background: #f5f5f5; } .cards { display: flex; gap: 1rem; } .card { background: white; padding: 2rem; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); min-width: 120px; text-align: center; }", "sandboxCSS": "", "codePrefix": ".cards {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "flex-wrap: wrap;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "flex-wrap", "expected": "wrap" }, "message": "اضبط flex-wrap: wrap" } ] }, { "id": "flexbox-6", "title": "Flex Grow", "description": "خاصية flex على العناصر تتحكم في كيفية نموها وانكماشها. flex: 1 يجعل العنصر ينمو لملء المساحة المتاحة. عناصر متعددة مع flex: 1 تتشارك المساحة بالتساوي.", "task": "اجعل حقل البحث يتوسع لملء المساحة المتاحة بضبط flex: 1 على .search.", "previewHTML": "
", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .toolbar { display: flex; gap: 8px; padding: 1rem; background: #f5f5f5; border-radius: 8px; } .search { padding: 8px 1rem; border: 1px solid #ddd; border-radius: 4px; font-size: 1rem; } .btn { padding: 8px 1rem; background: steelblue; color: white; border: none; border-radius: 4px; cursor: pointer; }", "sandboxCSS": "", "codePrefix": ".search {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "flex: 1;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "flex", "expected": "1" }, "message": "اضبط flex: 1" } ] } ] }