{ "$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 التي تحوّل العنصر إلى حاوية صندوق مرن؟" } ] }, { "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": "ما الخاصية التي تُنشئ تباعداً بين عناصر flex بدون استخدام الهوامش؟" } ] }, { "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 التي تدفع العنصر الأول والأخير إلى الحواف المتقابلة؟" } ] }, { "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": "ما الخاصية التي تُحاذي عناصر flex على طول المحور المتقاطع؟" } ] }, { "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 بالتدفق إلى أسطر متعددة؟" } ] }, { "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 ينمو لملء المساحة المتبقية؟" } ] } ] }