{ "$schema": "../../schemas/code-crispies-module-schema.json", "id": "css-basic-selectors", "title": "أساسيات CSS", "description": "تعلم اللبنات الأساسية لـ CSS: الخصائص والقيم والمحددات. يعلمك هذا الوحدة قواعد الصياغة التي يتبعها كل إعلان CSS.", "difficulty": "beginner", "lessons": [ { "id": "css-properties", "title": "خصائص CSS", "description": "تقوم CSS بتنسيق العناصر باستخدام الإعلانات - أزواج من الخصائص والقيم. كل إعلان يتبع نفس النمط:

property: value;

الخصاصية هي ما تريد تغييره (مثل color أو background). القيمة هي ما تضبطها عليه. النقطتان تفصلهما، والفاصلة المنقوطة تنهي السطر.

القيم تأتي بأنواع مختلفة:
كلمات مفتاحية: red، bold، center
أرقام بوحدات: 16px، 2rem، 100%
ألوان: steelblue، #ff0000", "task": "أكمل الإعلان بإضافة color: coral; لتغيير لون النص.", "previewHTML": "

This text should turn coral.

", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .text { font-size: 1.25rem; }", "sandboxCSS": "", "codePrefix": ".text {\n ", "initialCode": "", "codeSuffix": "\n}", "previewContainer": "preview-area", "solution": "color: coral;", "validations": [ { "type": "property_value", "value": { "property": "color", "expected": "coral" }, "message": "أضف color: coral;" } ] }, { "id": "multiple-properties", "title": "خصائص متعددة", "description": "يمكن أن تحتوي القاعدة على إعلانات متعددة. كل واحدة تذهب في سطرها الخاص، وكل واحدة تحتاج فاصلة منقوطة في النهاية:

.box {
background: gold;
color: navy;
padding: 1rem;
}

الترتيب عادةً لا يهم - CSS تطبقها جميعًا. عند التعارض، الأخيرة تفوز.", "task": "أضف إعلانين: background: lavender; و padding: 1rem;", "previewHTML": "
A styled card with background and padding.
", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .card { border-radius: 8px; }", "sandboxCSS": "", "codePrefix": ".card {\n ", "initialCode": "", "codeSuffix": "\n}", "previewContainer": "preview-area", "solution": "background: lavender;\n padding: 1rem;", "validations": [ { "type": "property_value", "value": { "property": "background", "expected": "lavender" }, "message": "أضف background: lavender;" }, { "type": "property_value", "value": { "property": "padding", "expected": "1rem" }, "message": "أضف padding: 1rem;" } ] }, { "id": "type-selectors", "title": "محددات النوع", "description": "المحدد يخبر المتصفح أي العناصر يجب تنسيقها. أبسط محدد هو محدد النوع — مجرد اسم وسم HTML.

p {
color: steelblue;
}

هذه القاعدة تستهدف كل عنصر <p> في الصفحة. محددات النوع رائعة لتعيين الأنماط الأساسية.", "task": "نسق جميع الفقرات. اكتب قاعدة مع p كمحدد واضبط color: steelblue.", "previewHTML": "
\n

Fresh Roasted Coffee

\n

Our beans are sourced from small farms in Colombia and Ethiopia.

\n

Each batch is roasted weekly to ensure peak freshness.

\n
", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } h2 { margin: 0 0 1rem; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "p {\n color: steelblue;\n}", "validations": [ { "type": "regex", "value": "p\\s*\\{", "message": "ابدأ بـ p { لاختيار الفقرات" }, { "type": "property_value", "value": { "property": "color", "expected": "steelblue" }, "message": "اضبط color: steelblue" } ] }, { "id": "styling-links", "title": "تنسيق الروابط", "description": "محددات النوع تعمل مع أي عنصر HTML. المحدد a يستهدف جميع الروابط في الصفحة.

الروابط لها لون أزرق وخط تحتها افتراضيًا. يمكنك تغيير كليهما مع CSS — استخدم color للنص و text-decoration: none لإزالة الخط.", "task": "نسق روابط التنقل. اكتب قاعدة مع a كمحدد واضبط color: coral.", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } nav { display: flex; gap: 1.5rem; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "a {\n color: coral;\n}", "validations": [ { "type": "regex", "value": "a\\s*\\{", "message": "ابدأ بـ a { لاختيار الروابط" }, { "type": "property_value", "value": { "property": "color", "expected": "coral" }, "message": "اضبط color: coral" } ] }, { "id": "class-selectors", "title": "محددات الفئة", "description": "محددات النوع تنسق جميع العناصر من ذلك النوع. لكن ماذا لو أردت تنسيق بعضها فقط؟

محددات الفئة تستهدف العناصر ذات سمة class محددة. تبدأ بنقطة:

.badge {
background: coral;
}

هذا ينسق فقط العناصر ذات class=\"badge\".", "task": "نسق شارة الإشعارات. اكتب قاعدة مع .badge كمحدد واضبط background: tomato.", "previewHTML": "
\n

Dashboard

\n 3\n
\n

You have new notifications waiting.

", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } header { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; } h1 { margin: 0; font-size: 1.5rem; } .badge { color: white; padding: 0.25rem 0.5rem; border-radius: 999px; font-size: 0.875rem; } p { color: #555; margin: 0; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": ".badge {\n background: tomato;\n}", "validations": [ { "type": "regex", "value": "\\.badge\\s*\\{", "message": "ابدأ بـ .badge { (لا تنسَ النقطة!)" }, { "type": "property_value", "value": { "property": "background", "expected": "tomato" }, "message": "اضبط background: tomato" } ] }, { "id": "button-variants", "title": "متغيرات الأزرار", "description": "يمكن أن تحتوي العناصر على فئات متعددة. عندما تسلسل محددات الفئة بدون مسافات، تستهدف العناصر التي لديها جميع تلك الفئات:

.btn.primary {
background: steelblue;
}

هذا يستهدف العناصر ذات class=\"btn primary\"، وليس فقط .btn أو فقط .primary.", "task": "نسق الزر الأساسي. اكتب قاعدة مع .btn.primary كمحدد واضبط background: steelblue.", "previewHTML": "
\n \n \n
", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } .actions { display: flex; gap: 0.75rem; } .btn { padding: 0.5rem 1rem; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; background: #e0e0e0; color: #333; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": ".btn.primary {\n background: steelblue;\n}", "validations": [ { "type": "regex", "value": "\\.btn\\.primary\\s*\\{", "message": "استخدم .btn.primary { (بدون مسافة بين الفئات)" }, { "type": "property_value", "value": { "property": "background", "expected": "steelblue" }, "message": "اضبط background: steelblue" } ] }, { "id": "specific-elements", "title": "استهداف عناصر محددة", "description": "أحيانًا تريد أن تبدو الفئة مختلفة على عناصر مختلفة. اجمع محدد النوع مع محدد الفئة (بدون مسافة) لتكون أكثر تحديدًا:

a.btn {
text-decoration: none;
}

هذا ينسق فقط عناصر <a> ذات الفئة btn، وليس عناصر <button> ذات تلك الفئة.", "task": "أزل الخط من أزرار الروابط. اكتب قاعدة مع a.btn كمحدد واضبط text-decoration: none.", "previewHTML": "
\n \n Link Button\n
", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } .actions { display: flex; gap: 0.75rem; align-items: center; } .btn { padding: 0.5rem 1rem; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; background: steelblue; color: white; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "a.btn {\n text-decoration: none;\n}", "validations": [ { "type": "regex", "value": "a\\.btn\\s*\\{", "message": "استخدم a.btn { (نوع + فئة، بدون مسافة)" }, { "type": "property_value", "value": { "property": "text-decoration", "expected": "none" }, "message": "اضبط text-decoration: none" } ] }, { "id": "grouping-selectors", "title": "تجميع المحددات", "description": "عندما تحتاج عناصر متعددة لنفس الأنماط، اذكرها مفصولة بفواصل. هذا يحافظ على CSS نظيفًا وقابلاً للصيانة.

h1, h2, h3 {
color: steelblue;
}

هذا يطبق نفس اللون على مستويات العناوين الثلاثة في قاعدة واحدة.", "task": "نسق جميع العناوين بشكل متسق. أضف color: steelblue إلى المحدد المجمع h1, h2, h3.", "previewHTML": "

Main Title

Introduction paragraph with some text.

Section Heading

More content here.

Subsection

Final paragraph.

", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } article { max-width: 500px; } p { color: #555; line-height: 1.6; }", "sandboxCSS": "", "codePrefix": "h1, h2, h3 {\n ", "initialCode": "", "codeSuffix": "\n}", "previewContainer": "preview-area", "solution": "color: steelblue;", "validations": [ { "type": "property_value", "value": { "property": "color", "expected": "steelblue" }, "message": "اضبط color: steelblue" } ] }, { "id": "descendant-selectors", "title": "محددات الأحفاد", "description": "استهدف العناصر داخل عناصر أخرى باستخدام مسافة بين المحددات. هذا أحد أكثر الأنماط فائدة في CSS.

.nav a {
color: white;
}

هذا ينسق فقط الروابط داخل .nav، تاركًا الروابط الأخرى دون تغيير.", "task": "نسق روابط التنقل بشكل مختلف. اكتب قاعدة مع .nav a كمحدد واضبط color: white.", "previewHTML": "

Read more in our documentation.

", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; margin: 0; } .nav { background: steelblue; padding: 1rem; display: flex; gap: 1rem; border-radius: 8px; margin-bottom: 1rem; } .nav a { text-decoration: none; } p a { color: steelblue; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": ".nav a {\n color: white;\n}", "validations": [ { "type": "regex", "value": "\\.nav\\s+a\\s*\\{", "message": "استخدم .nav a { (مسافة بين .nav و a)" }, { "type": "property_value", "value": { "property": "color", "expected": "white" }, "message": "اضبط color: white" } ] }, { "id": "nested-styling", "title": "الأنماط المتداخلة", "description": "محددات الأحفاد تتيح لك إنشاء أنماط سياقية. نفس العنصر يمكن أن يبدو مختلفًا حسب مكان ظهوره.

على سبيل المثال، الفقرات في .card قد تكون أصغر من الفقرات في article.", "task": "اجعل الفقرات داخل البطاقة أصغر. اكتب قاعدة مع .card p كمحدد واضبط font-size: 0.9rem.", "previewHTML": "

Article Title

This is a regular article paragraph with normal-sized text for comfortable reading.

Quick Tip

Card paragraphs should be slightly smaller to fit the compact design.

Back to regular article text here.

", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } article { max-width: 500px; } h2 { color: steelblue; margin-top: 0; } p { line-height: 1.6; color: #444; } .card { background: #f0f4f8; padding: 1rem; border-radius: 8px; border-left: 4px solid steelblue; } .card strong { color: steelblue; display: block; margin-bottom: 0.5rem; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": ".card p {\n font-size: 0.9rem;\n}", "validations": [ { "type": "regex", "value": "\\.card\\s+p\\s*\\{", "message": "استخدم .card p { (مسافة بين .card و p)" }, { "type": "property_value", "value": { "property": "font-size", "expected": "0.9rem" }, "message": "اضبط font-size: 0.9rem" } ] } ] }