feat: sync all language files to match English CSS Basics lessons

- Updated de, pl, es, ar, uk translations to have identical structure
- All 10 lessons now match English: code, solutions, validations
- Only title, description, task, and message fields are translated
- Removed obsolete lessons not present in English version

🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
2026-01-14 11:55:30 +01:00
parent 79e07cdd47
commit 857e110905
5 changed files with 895 additions and 2350 deletions

View File

@@ -1,548 +1,257 @@
{ {
"$schema": "../../schemas/code-crispies-module-schema.json", "$schema": "../../schemas/code-crispies-module-schema.json",
"id": "css-basic-selectors", "id": "css-basic-selectors",
"title": "CSS Selectors", "title": "أساسيات CSS",
"description": "CSS selectors are the foundation of styling web pages, allowing you to target specific HTML elements for styling. This module introduces fundamental selector types including element type selectors, class selectors, ID selectors, and the universal selector.", "description": "تعلم اللبنات الأساسية لـ CSS: الخصائص والقيم والمحددات. يعلمك هذا الوحدة قواعد الصياغة التي يتبعها كل إعلان CSS.",
"difficulty": "beginner", "difficulty": "beginner",
"lessons": [ "lessons": [
{ {
"id": "introduction-to-selectors", "id": "css-properties",
"title": "What's a Selector?", "title": "خصائص CSS",
"description": "A CSS selector is the first part of a CSS rule that tells the browser which HTML elements should receive the styles defined in the declaration block. Selectors are essentially patterns that match against elements in your HTML document. Understanding selectors is fundamental because they determine which elements your CSS rules will affect. The element or elements targeted by a selector are referred to as the 'subject of the selector.' When writing a CSS rule, you first specify the selector, followed by curly braces that contain the style declarations.<br/>For example, to change the text color of elements, you can use the <kbd>color</kbd> property within your declaration block.<br><br><pre>/* Element selector */\np {\n color: orangered;\n /* │ └─── Indicates the value of the expression\n │ \n └─────────── Indicates the property of the expression */\n}</pre>", "description": "تقوم CSS بتنسيق العناصر باستخدام <strong>الإعلانات</strong> - أزواج من الخصائص والقيم. كل إعلان يتبع نفس النمط:<br><br><pre>property: value;</pre><br><strong>الخصاصية</strong> هي ما تريد تغييره (مثل <kbd>color</kbd> أو <kbd>background</kbd>). <strong>القيمة</strong> هي ما تضبطها عليه. النقطتان تفصلهما، والفاصلة المنقوطة تنهي السطر.<br><br>القيم تأتي بأنواع مختلفة:<br>• <strong>كلمات مفتاحية:</strong> <kbd>red</kbd>، <kbd>bold</kbd>، <kbd>center</kbd><br>• <strong>أرقام بوحدات:</strong> <kbd>16px</kbd>، <kbd>2rem</kbd>، <kbd>100%</kbd><br>• <strong>ألوان:</strong> <kbd>steelblue</kbd>، <kbd>#ff0000</kbd>",
"task": "Write a CSS rule using a type selector that targets all paragraph elements <kbd>p</kbd> in the document. Make the text blue by setting the <kbd>color</kbd> property to <kbd>blue</kbd>.", "task": "أكمل الإعلان بإضافة <kbd>color: coral;</kbd> لتغيير لون النص.",
"previewHTML": "<h1>Introduction to CSS Selectors</h1>\n<p>This paragraph should turn blue.</p>\n<div>This div element should remain unchanged.</div>\n<p>This second paragraph should also turn blue.</p>", "previewHTML": "<p class=\"text\">This text should turn coral.</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .text { font-size: 1.25rem; }",
"sandboxCSS": "h1, p, div { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }", "sandboxCSS": "",
"codePrefix": "/* Write a type selector to target all paragraph elements */\n", "codePrefix": ".text {\n ",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "\n}",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": "p { color: blue }", "solution": "color: coral;",
"validations": [ "validations": [
{ {
"type": "regex", "type": "property_value",
"value": "^p\\s*{", "value": { "property": "color", "expected": "coral" },
"message": "Start your rule with <kbd>p { … }</kbd> to select all paragraph elements", "message": "أضف <kbd>color: coral;</kbd>"
"options": { }
"caseSensitive": false ]
} },
}, {
"id": "multiple-properties",
"title": "خصائص متعددة",
"description": "يمكن أن تحتوي القاعدة على إعلانات متعددة. كل واحدة تذهب في سطرها الخاص، وكل واحدة تحتاج فاصلة منقوطة في النهاية:<br><br><pre>.box {<br> background: gold;<br> color: navy;<br> padding: 1rem;<br>}</pre><br>الترتيب عادةً لا يهم - CSS تطبقها جميعًا. عند التعارض، الأخيرة تفوز.",
"task": "أضف إعلانين: <kbd>background: lavender;</kbd> و <kbd>padding: 1rem;</kbd>",
"previewHTML": "<div class=\"card\">A styled card with background and padding.</div>",
"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": "contains", "type": "property_value",
"value": "color:", "value": { "property": "background", "expected": "lavender" },
"message": "Include the <kbd>color:</kbd> property in your CSS rule" "message": "أضف <kbd>background: lavender;</kbd>"
},
{
"type": "contains",
"value": "blue",
"message": "Set the color value to <kbd>blue</kbd>"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "padding", "expected": "1rem" },
"property": "color", "message": "أضف <kbd>padding: 1rem;</kbd>"
"expected": "blue"
},
"message": "Use <kbd>color: blue</kbd> to set the text color"
},
{
"type": "regex",
"value": "p\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": false
}
} }
] ]
}, },
{ {
"id": "type-selectors", "id": "type-selectors",
"title": "Type Selectors", "title": "محددات النوع",
"description": "Type selectors (also called tag name selectors or element selectors) target HTML elements based on their tag name. For example, <kbd>p</kbd> selects all paragraph elements, <kbd>h1</kbd> selects all level-one headings, and <kbd>div</kbd> selects all division elements. Type selectors are the most fundamental way to select elements, applying styles consistently to all instances of a particular HTML element throughout your document. You can define a variety of CSS properties with type selectors, such as <kbd>color</kbd> for text color, <kbd>background-color</kbd> for the background, and <kbd>font-weight</kbd> for text emphasis. They provide a broad approach for styling your page and are often the starting point for more specific styling using other selector types.", "description": "<strong>المحدد</strong> يخبر المتصفح أي العناصر يجب تنسيقها. أبسط محدد هو <strong>محدد النوع</strong> — مجرد اسم وسم HTML.<br><br><pre>p {<br> color: steelblue;<br>}</pre><br>هذه القاعدة تستهدف كل عنصر <kbd>&lt;p&gt;</kbd> في الصفحة. محددات النوع رائعة لتعيين الأنماط الأساسية.",
"task": "Write three separate CSS rules using type selectors to target specific HTML elements: make <kbd>h2</kbd> headings <kbd>purple</kbd>, give <kbd>span</kbd> elements a <kbd>yellow</kbd> background, and make <kbd>strong</kbd> elements <kbd>red</kbd>.", "task": "نسق جميع الفقرات. اكتب قاعدة مع <kbd>p</kbd> كمحدد واضبط <kbd>color: steelblue</kbd>.",
"previewHTML": "<h2>Type Selectors Example</h2>\n<p>Regular paragraph text <span>with a highlighted span</span> that should have a yellow background.</p>\n<p>Another paragraph with <strong>strong important text</strong> that should be red.</p>\n<h2>Another Heading</h2>", "previewHTML": "<article>\n <h2>Fresh Roasted Coffee</h2>\n <p>Our beans are sourced from small farms in Colombia and Ethiopia.</p>\n <p>Each batch is roasted weekly to ensure peak freshness.</p>\n</article>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } h2 { margin: 0 0 1rem; }",
"sandboxCSS": "h2, p, span, strong { padding: 3px; }", "sandboxCSS": "",
"codePrefix": "/* Write three separate type selectors below */\n\n", "codePrefix": "",
"initialCode": "/* 1. Make h2 headings purple */\n\n\n/* 2. Give span elements a yellow background */\n\n\n/* 3. Make strong elements red */\n", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": "/* 1. Make h2 headings purple */\nh2 {\n color: purple;\n}\n\n/* 2. Give span elements a yellow background */\nspan {\n background-color: yellow;\n}\n\n/* 3. Make strong elements red */\nstrong {\n color: red;\n}", "solution": "p {\n color: steelblue;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^h2\\s*{", "value": "p\\s*\\{",
"message": "Include an <kbd>h2 { … }</kbd> selector" "message": "ابدأ بـ <kbd>p {</kbd> لاختيار الفقرات"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "color", "expected": "steelblue" },
"property": "color", "message": "اضبط <kbd>color: steelblue</kbd>"
"expected": "purple" }
}, ]
"message": "Set the <kbd>color</kbd> property to <kbd>purple</kbd> for h2 elements" },
}, {
"id": "styling-links",
"title": "تنسيق الروابط",
"description": "محددات النوع تعمل مع أي عنصر HTML. المحدد <kbd>a</kbd> يستهدف جميع الروابط في الصفحة.<br><br>الروابط لها لون أزرق وخط تحتها افتراضيًا. يمكنك تغيير كليهما مع CSS — استخدم <kbd>color</kbd> للنص و <kbd>text-decoration: none</kbd> لإزالة الخط.",
"task": "نسق روابط التنقل. اكتب قاعدة مع <kbd>a</kbd> كمحدد واضبط <kbd>color: coral</kbd>.",
"previewHTML": "<nav>\n <a href=\"#\">Home</a>\n <a href=\"#\">Menu</a>\n <a href=\"#\">About</a>\n <a href=\"#\">Contact</a>\n</nav>",
"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", "type": "regex",
"value": "h2\\s*{[^}]*}", "value": "a\\s*\\{",
"message": "Make sure to close your h2 rule with a closing brace <kbd>}</kbd>" "message": "ابدأ بـ <kbd>a {</kbd> لاختيار الروابط"
},
{
"type": "regex",
"value": "^span\\s*{",
"message": "Include a <kbd>span { … }</kbd> selector"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "color", "expected": "coral" },
"property": "background-color", "message": "اضبط <kbd>color: coral</kbd>"
"expected": "yellow"
},
"message": "Set a <kbd>background-color: yellow</kbd> for span elements"
},
{
"type": "regex",
"value": "span\\s*{[^}]*}",
"message": "Make sure to close your span rule with a closing brace <kbd>}</kbd>"
},
{
"type": "regex",
"value": "^strong\\s*{",
"message": "Include a <kbd>strong { … }</kbd> selector"
},
{
"type": "regex",
"value": "strong\\s*{\\s*color:\\s*red;[^}]*}",
"message": "Set the <kbd>color: red</kbd> for strong elements"
} }
] ]
}, },
{ {
"id": "class-selectors", "id": "class-selectors",
"title": "Class Selectors", "title": "محددات الفئة",
"description": "Class selectors target elements with a specific class attribute value. They begin with a dot (.) followed by the class name. Classes are powerful because they allow you to apply the same styles to multiple elements regardless of their type. An HTML element can have multiple classes (separated by spaces in the class attribute), and a class can be applied to any number of elements. When using class selectors, you can apply properties like <kbd>background-color</kbd> to set the background color of elements, and <kbd>font-weight</kbd> to control text thickness, making text bold or normal. This flexibility makes class selectors one of the most commonly used methods for applying styles in CSS, allowing for modular and reusable styling across your website.", "description": "محددات النوع تنسق <em>جميع</em> العناصر من ذلك النوع. لكن ماذا لو أردت تنسيق بعضها فقط؟<br><br><strong>محددات الفئة</strong> تستهدف العناصر ذات سمة <kbd>class</kbd> محددة. تبدأ بنقطة:<br><br><pre>.badge {<br> background: coral;<br>}</pre><br>هذا ينسق فقط العناصر ذات <kbd>class=\"badge\"</kbd>.",
"task": "Create a CSS rule using a class selector that targets elements with the class <kbd>highlight</kbd>. Give these elements a <kbd>yellow</kbd> background and <kbd>bold</kbd> text.", "task": "نسق شارة الإشعارات. اكتب قاعدة مع <kbd>.badge</kbd> كمحدد واضبط <kbd>background: tomato</kbd>.",
"previewHTML": "<h2>Using Class Selectors</h2>\n<p>This is a regular paragraph, but <span class=\"highlight\">this span has the highlight class</span> applied to it.</p>\n<p class=\"highlight\">This entire paragraph has the highlight class.</p>\n<ul>\n <li>Regular list item</li>\n <li class=\"highlight\">This list item is highlighted</li>\n</ul>", "previewHTML": "<header>\n <h1>Dashboard</h1>\n <span class=\"badge\">3</span>\n</header>\n<p>You have new notifications waiting.</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "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": "h2, p, li { padding: 5px; margin-bottom: 10px; }",
"codePrefix": "/* Create a class selector for elements with the 'highlight' class */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^\\.highlight\\s*{",
"message": "Start your rule with <kbd>.highlight { … }</kbd> to create a class selector",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "background-color:",
"message": "Include the <kbd>background-color:</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "yellow"
},
"message": "Set the background color to <kbd>yellow</kbd>"
},
{
"type": "contains",
"value": "font-weight:",
"message": "Include the <kbd>font-weight:</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "font-weight",
"expected": "bold"
},
"message": "Set the font-weight to <kbd>bold</kbd>"
},
{
"type": "regex",
"value": "\\.highlight\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "multiple-classes",
"title": "Multiple Classes",
"description": "HTML elements can have multiple classes applied simultaneously, allowing for composable and modular CSS designs. When an element has multiple classes, it will receive styles from all matching class selectors. This approach enables you to build a library of reusable CSS classes that can be combined in different ways. You can also target elements that have a specific combination of classes by chaining class selectors together without spaces (e.g., <kbd>.class1.class2</kbd>). When styling these elements, you might use properties like <kbd>border-color</kbd> to change the color of element borders, and <kbd>background-color</kbd> to set the background color of elements. This technique lets you create conditional styles that only apply when certain classes appear together.",
"task": "Complete the CSS rule that targets elements with both <kbd>card</kbd> and <kbd>featured</kbd> classes by chaining the selectors. Set the border-color to gold and the background-color to lemonchiffon to make featured cards stand out.",
"previewHTML": "<h2>Multiple Class Combinations</h2>\n<div class=\"card\">Regular Card</div>\n<div class=\"card featured\">Featured Card</div>\n<div class=\"featured\">Just Featured (not a card)</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } .card { border: 2px solid gray; padding: 15px; margin-bottom: 10px; border-radius: 5px; }",
"sandboxCSS": "", "sandboxCSS": "",
"codePrefix": "/* The .card class already has basic styling */\n/* Now target elements with BOTH classes: 'card' AND 'featured' */\n", "codePrefix": "",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": ".card.featured { border-color: gold; background-color: lemonchiffon }", "solution": ".badge {\n background: tomato;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^\\.card\\.featured\\s*{", "value": "\\.badge\\s*\\{",
"message": "Chain the selectors as <kbd>.card.featured</kbd> (no space between them)", "message": "ابدأ بـ <kbd>.badge {</kbd> (لا تنسَ النقطة!)"
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "border-color:",
"message": "Include the <kbd>border-color</kbd> property"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "background", "expected": "tomato" },
"property": "border-color", "message": "اضبط <kbd>background: tomato</kbd>"
"expected": "gold"
},
"message": "Set the border color to <kbd>gold</kbd>"
},
{
"type": "regex",
"value": "\\.card\\.featured\\s*{[^}]*;",
"message": "Make sure to end your CSS rule with a semicolon <kbd>;</kbd>"
},
{
"type": "contains",
"value": "background-color:",
"message": "Include the <kbd>background-color</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "lemonchiffon"
},
"message": "Set the background color to <kbd>lemonchiffon</kbd>"
},
{
"type": "regex",
"value": "\\.card\\.featured\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
} }
] ]
}, },
{ {
"id": "class-with-type", "id": "button-variants",
"title": "Combining Types", "title": "متغيرات الأزرار",
"description": "You can combine type selectors with class selectors to target specific HTML elements that have a certain class. This creates a more specific selector that only matches when both conditions are true: the element is of the specified type AND it has the specified class. For example, <kbd>p.note</kbd> would select paragraph elements with the class <kbd>note</kbd>, but would not select divs or spans with that same class. You can style these combined selections using properties like <kbd>background-color</kbd> to set a colored background for your elements. This approach allows you to apply different styles to the same class when it appears on different element types.", "description": "يمكن أن تحتوي العناصر على فئات متعددة. عندما تسلسل محددات الفئة بدون مسافات، تستهدف العناصر التي لديها <em>جميع</em> تلك الفئات:<br><br><pre>.btn.primary {<br> background: steelblue;<br>}</pre><br>هذا يستهدف العناصر ذات <kbd>class=\"btn primary\"</kbd>، وليس فقط <kbd>.btn</kbd> أو فقط <kbd>.primary</kbd>.",
"task": "Create a CSS rule that specifically targets <kbd>&lt;span&gt;</kbd> elements with the class <kbd>highlight</kbd>. Make those elements have an orange background, while other elements with the highlight class remain untouched.", "task": "نسق الزر الأساسي. اكتب قاعدة مع <kbd>.btn.primary</kbd> كمحدد واضبط <kbd>background: steelblue</kbd>.",
"previewHTML": "<h2>Type and Class Combinations</h2>\n<p>This paragraph has a <span class=\"highlight\">highlighted span</span> that should have an orange background.</p>\n<p class=\"highlight\">This paragraph has the highlight class but should NOT have an orange background.</p>", "previewHTML": "<div class=\"actions\">\n <button class=\"btn\">Cancel</button>\n <button class=\"btn primary\">Save Changes</button>\n</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } .highlight { font-weight: bold; }", "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": "h2, p, span { padding: 5px; }",
"codePrefix": "/* The .highlight class already sets font-weight to bold */\n/* Now target ONLY span elements with the highlight class */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^span\\.highlight\\s*{",
"message": "Use <kbd>span.highlight</kbd> selector (no space between element and class)",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "background-color:",
"message": "Include the <kbd>background-color</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "orange"
},
"message": "Set the background color to <kbd>orange</kbd>"
},
{
"type": "regex",
"value": "span\\.highlight\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "id-selectors",
"title": "ID Selectors",
"description": "ID selectors target elements with a specific id attribute. They begin with a hash/pound sign (#) followed by the ID name. Unlike classes, IDs must be unique within a document—each ID value should be used only once per page. ID selectors have higher specificity than class or element selectors, meaning they override those selectors when conflicts arise. When styling with ID selectors, you can use properties like <kbd>color</kbd> to define text color, and <kbd>text-decoration</kbd> to control the appearance of text, such as adding underlines to elements. Because of their uniqueness requirement, IDs are best used for one-of-a-kind elements like page headers, main navigation, or specific unique components that appear only once on a page.",
"task": "Create a CSS rule with an ID selector that targets the element with the ID <kbd>main-title</kbd>. Set its color to purple and add an underline with <kbd>text-decoration: underline</kbd>.",
"previewHTML": "<h1 id=\"main-title\">Main Page Title</h1>\n<p>Regular paragraph content.</p>\n<h2>Secondary Heading</h2>\n<p id=\"intro\">Introduction paragraph (different ID).</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }",
"sandboxCSS": "h1, h2, p { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }",
"codePrefix": "/* Create an ID selector to target the element with id=\"main-title\" */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^#main-title\\s*{",
"message": "Start your rule with <kbd>#main-title</kbd> to create an ID selector",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "color:",
"message": "Include the <kbd>color</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "color",
"expected": "purple"
},
"message": "Set the color to <kbd>purple</kbd>"
},
{
"type": "contains",
"value": "text-decoration:",
"message": "Include the <kbd>text-decoration</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "text-decoration",
"expected": "underline"
},
"message": "Set the text-decoration to <kbd>underline</kbd>"
},
{
"type": "regex",
"value": "#main-title\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "id-with-type",
"title": "Type + ID",
"description": "Similar to how you can combine type and class selectors, you can also combine type selectors with ID selectors. For example, <kbd>h1#title</kbd> targets an h1 element with the ID 'title'. When using this combined approach, you can apply CSS properties like <kbd>font-style</kbd> to control the slant of the text, making it italic or normal. While this selector combination is more specific than using just the ID selector, it's often unnecessary since IDs should already be unique in a document. However, this technique can be useful for improving code readability or when you want to emphasize that a particular ID should only appear on a specific element type.",
"task": "Create a CSS rule that combines a type selector with an ID selector to target specifically a paragraph element with the ID <kbd>special</kbd>. Set its font style to italic.",
"previewHTML": "<h2 id=\"special\">Heading with ID \"special\" (should NOT be affected)</h2>\n<p id=\"special\">Paragraph with ID \"special\" (should become italic)</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }",
"sandboxCSS": "h2, p { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }",
"codePrefix": "/* Create a combined type+ID selector for a paragraph with id=\"special\" */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^p#special\\s*{",
"message": "Use <kbd>p#special</kbd> to target paragraphs with ID <kbd>special</kbd>",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "font-style:",
"message": "Include the <kbd>font-style</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "font-style",
"expected": "italic"
},
"message": "Set the font-style to <kbd>italic</kbd>"
},
{
"type": "regex",
"value": "p#special\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "selector-lists",
"title": "Selector Lists",
"description": "When multiple elements need the same styling, you can group them together using a selector list (also known as grouping selectors). Selector lists are created by separating individual selectors with commas. This approach reduces repetition in your CSS, making it more maintainable and efficient. For example, <kbd>h1, h2, h3 { color: blue; }</kbd> applies the same blue color to all three heading levels. When styling multiple selectors at once, you can apply properties like <kbd>background-color</kbd> to set the background, <kbd>border-left</kbd> to create a left border with a specific thickness, style, and color, and <kbd>padding-left</kbd> to create space between the content and the left border. Whitespace around commas is optional, and each selector in the list can be any valid selector type-elements, classes, IDs, or even more complex selectors.",
"task": "Create a selector list that applies the same styles to three different elements: paragraphs with class <kbd>note</kbd>, list items with class <kbd>important</kbd>, and the element with ID <kbd>summary</kbd>. Give them a <kbd>lightyellow</kbd> background, a <kbd>gold</kbd> left border, and some left <kbd>padding</kbd>.",
"previewHTML": "<p class=\"note\">This is a note paragraph.</p>\n<ul>\n <li>Regular list item</li>\n <li class=\"important\">Important list item</li>\n</ul>\n<div id=\"summary\">Summary section</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }",
"sandboxCSS": "p, li, div { padding: 8px; margin-bottom: 8px; border: 1px dashed gray; }",
"codePrefix": "/* Create a selector list to apply the same styles to multiple different elements */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"solution": "p.note,\nli.important,\n#summary {\n background-color: lightyellow;\n border-left: 3px solid gold;\n padding-left: 10px\n}",
"validations": [
{
"type": "contains",
"value": "p.note",
"message": "Include <kbd>p.note</kbd> in your selector list",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "li.important",
"message": "Include <kbd>li.important</kbd> in your selector list",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "#summary",
"message": "Include <kbd>#summary</kbd> in your selector list",
"options": {
"caseSensitive": true
}
},
{
"type": "regex",
"value": "(p\\.note|li\\.important|#summary)\\s*,\\s*(p\\.note|li\\.important|#summary)\\s*,\\s*(p\\.note|li\\.important|#summary)",
"message": "Create a comma-separated list with all three selectors",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "background-color:",
"message": "Include the <kbd>background-color</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "lightyellow"
},
"message": "Set the background color to <kbd>lightyellow</kbd>"
},
{
"type": "contains",
"value": "border-left:",
"message": "Include the <kbd>border-left</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "border-left",
"expected": "3px solid gold"
},
"message": "Use <kbd>border-left: 3px solid gold</kbd> to create a left border"
},
{
"type": "contains",
"value": "padding-left:",
"message": "Include the <kbd>padding-left</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "padding-left",
"expected": "10px"
},
"message": "Use <kbd>padding-left: 10px</kbd> to add left padding"
}
]
},
{
"id": "universal-selector",
"title": "Universal (*)",
"description": "The universal selector is denoted by an asterisk (*) and matches any element of any type. It selects everything in the document or, when combined with other selectors, everything within a specific context. For example, <kbd>* { margin: 0; }</kbd> removes margins from all elements, while <kbd>article *</kbd> selects all elements inside article elements. When using the universal selector in combination with other selectors, you can apply properties like <kbd>margin</kbd> to control the spacing around elements. The universal selector is powerful but should be used carefully due to its broad impact. It's commonly used in CSS resets, to override default browser styling, or to target all children of a particular element.",
"task": "Use the universal selector to remove margins from all elements inside the container div. Create a rule using <kbd>div.container *</kbd> as the selector and set <kbd>margin: 0</kbd>.",
"previewHTML": "<div class=\"container\">\n <h2>Inside Container</h2>\n <p>This paragraph is inside the container.</p>\n <ul>\n <li>List item inside container</li>\n </ul>\n</div>\n<p>This paragraph is outside the container and should not be affected.</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } div.container { border: 2px solid navy; padding: 15px; background-color: lavender; } h2, p, ul, li { margin: 15px 0; }",
"sandboxCSS": "", "sandboxCSS": "",
"codePrefix": "/* Use the universal selector to target all elements inside the container */\n", "codePrefix": "",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": ".btn.primary {\n background: steelblue;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^div\\.container\\s+\\*\\s*{", "value": "\\.btn\\.primary\\s*\\{",
"message": "Use <kbd>div.container *</kbd> selector (with a space between container and *)", "message": "استخدم <kbd>.btn.primary {</kbd> (بدون مسافة بين الفئات)"
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "margin:",
"message": "Include the <kbd>margin</kbd> property"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "background", "expected": "steelblue" },
"property": "margin", "message": "اضبط <kbd>background: steelblue</kbd>"
"expected": "0"
},
"message": "Set margin to <kbd>0</kbd>"
},
{
"type": "regex",
"value": "div\\.container\\s+\\*\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
} }
] ]
}, },
{ {
"id": "specificity-basics", "id": "specific-elements",
"title": "Specificity", "title": "استهداف عناصر محددة",
"description": "CSS specificity determines which styles take precedence when multiple conflicting rules target the same element. Specificity follows a hierarchical system: inline styles have the highest specificity, followed by ID selectors, then class/attribute/pseudo-class selectors, and finally element/pseudo-element selectors. This can be conceptualized as a four-part score (inline, ID, class, element). When creating multiple rules that may target the same elements, you can use the <kbd>color</kbd> property to set text colors, and specificity will determine which color is actually applied. Understanding specificity is crucial for predictable styling and debugging CSS conflicts. When two selectors have equal specificity, the one that comes last in the stylesheet wins.", "description": "أحيانًا تريد أن تبدو الفئة مختلفة على عناصر مختلفة. اجمع محدد النوع مع محدد الفئة (بدون مسافة) لتكون أكثر تحديدًا:<br><br><pre>a.btn {<br> text-decoration: none;<br>}</pre><br>هذا ينسق فقط عناصر <kbd>&lt;a&gt;</kbd> ذات الفئة <kbd>btn</kbd>، وليس عناصر <kbd>&lt;button&gt;</kbd> ذات تلك الفئة.",
"task": "Examine the existing CSS rules and add a new rule with higher specificity to override the text color of the paragraph. Create a rule using '.content p' as the selector and set color: green.", "task": "أزل الخط من أزرار الروابط. اكتب قاعدة مع <kbd>a.btn</kbd> كمحدد واضبط <kbd>text-decoration: none</kbd>.",
"previewHTML": "<div class=\"content\">\n <p>What color will this paragraph be? Look at the CSS rules and their specificity.</p>\n</div>", "previewHTML": "<div class=\"actions\">\n <button class=\"btn\">Regular Button</button>\n <a href=\"#\" class=\"btn\">Link Button</a>\n</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "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": "p { border: 1px dashed gray; padding: 10px; }", "sandboxCSS": "",
"codePrefix": "/* These CSS rules target the same paragraph but have different specificity */\n\n/* Rule 1: Element selector (lowest specificity) */\np {\n color: red;\n}\n\n/* Rule 2: Descendant selector (higher specificity than just 'p') */\n", "codePrefix": "",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": "a.btn {\n text-decoration: none;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^\\.content\\s+p\\s*{", "value": "a\\.btn\\s*\\{",
"message": "Use <kbd>.content p</kbd> as your selector (note the space between)", "message": "استخدم <kbd>a.btn {</kbd> (نوع + فئة، بدون مسافة)"
"options": {
"caseSensitive": true
}
}, },
{ {
"type": "contains", "type": "property_value",
"value": "color:", "value": { "property": "text-decoration", "expected": "none" },
"message": "Include the <kbd>color</kbd> property" "message": "اضبط <kbd>text-decoration: none</kbd>"
}
]
},
{
"id": "grouping-selectors",
"title": "تجميع المحددات",
"description": "عندما تحتاج عناصر متعددة لنفس الأنماط، اذكرها مفصولة بفواصل. هذا يحافظ على CSS نظيفًا وقابلاً للصيانة.<br><br><pre>h1, h2, h3 {<br> color: steelblue;<br>}</pre><br>هذا يطبق نفس اللون على مستويات العناوين الثلاثة في قاعدة واحدة.",
"task": "نسق جميع العناوين بشكل متسق. أضف <kbd>color: steelblue</kbd> إلى المحدد المجمع <kbd>h1, h2, h3</kbd>.",
"previewHTML": "<article><h1>Main Title</h1><p>Introduction paragraph with some text.</p><h2>Section Heading</h2><p>More content here.</p><h3>Subsection</h3><p>Final paragraph.</p></article>",
"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": "اضبط <kbd>color: steelblue</kbd>"
}
]
},
{
"id": "descendant-selectors",
"title": "محددات الأحفاد",
"description": "استهدف العناصر داخل عناصر أخرى باستخدام مسافة بين المحددات. هذا أحد أكثر الأنماط فائدة في CSS.<br><br><pre>.nav a {<br> color: white;<br>}</pre><br>هذا ينسق فقط الروابط داخل <kbd>.nav</kbd>، تاركًا الروابط الأخرى دون تغيير.",
"task": "نسق روابط التنقل بشكل مختلف. اكتب قاعدة مع <kbd>.nav a</kbd> كمحدد واضبط <kbd>color: white</kbd>.",
"previewHTML": "<nav class=\"nav\"><a href=\"#\">Home</a><a href=\"#\">About</a><a href=\"#\">Contact</a></nav><p>Read more in our <a href=\"#\">documentation</a>.</p>",
"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": "استخدم <kbd>.nav a {</kbd> (مسافة بين .nav و a)"
}, },
{ {
"type": "contains", "type": "property_value",
"value": "green", "value": { "property": "color", "expected": "white" },
"message": "" "message": "اضبط <kbd>color: white</kbd>"
}
]
},
{
"id": "nested-styling",
"title": "الأنماط المتداخلة",
"description": "محددات الأحفاد تتيح لك إنشاء أنماط سياقية. نفس العنصر يمكن أن يبدو مختلفًا حسب مكان ظهوره.<br><br>على سبيل المثال، الفقرات في <kbd>.card</kbd> قد تكون أصغر من الفقرات في <kbd>article</kbd>.",
"task": "اجعل الفقرات داخل البطاقة أصغر. اكتب قاعدة مع <kbd>.card p</kbd> كمحدد واضبط <kbd>font-size: 0.9rem</kbd>.",
"previewHTML": "<article><h2>Article Title</h2><p>This is a regular article paragraph with normal-sized text for comfortable reading.</p><div class=\"card\"><strong>Quick Tip</strong><p>Card paragraphs should be slightly smaller to fit the compact design.</p></div><p>Back to regular article text here.</p></article>",
"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": "استخدم <kbd>.card p {</kbd> (مسافة بين .card و p)"
},
{
"type": "property_value",
"value": { "property": "font-size", "expected": "0.9rem" },
"message": "اضبط <kbd>font-size: 0.9rem</kbd>"
} }
] ]
} }

View File

@@ -1,548 +1,257 @@
{ {
"$schema": "../../schemas/code-crispies-module-schema.json", "$schema": "../../schemas/code-crispies-module-schema.json",
"id": "css-basic-selectors", "id": "css-basic-selectors",
"title": "CSS Selektoren", "title": "CSS Grundlagen",
"description": "CSS-Selektoren sind die Grundlage für das Stylen von Webseiten und ermöglichen es dir, bestimmte HTML-Elemente für die Gestaltung auszuwählen. Dieses Modul stellt grundlegende Selektortypen vor, einschließlich Element-Typ-Selektoren, Klassen-Selektoren, ID-Selektoren und des universellen Selektors.", "description": "Lerne die grundlegenden Bausteine von CSS: Eigenschaften, Werte und Selektoren. Dieses Modul vermittelt dir die Syntaxregeln, denen jede CSS-Deklaration folgt.",
"difficulty": "beginner", "difficulty": "beginner",
"lessons": [ "lessons": [
{ {
"id": "introduction-to-selectors", "id": "css-properties",
"title": "Was ist ein CSS-Selektor?", "title": "CSS-Eigenschaften",
"description": "Ein CSS-Selektor ist der erste Teil einer CSS-Regel, der dem Browser mitteilt, welche HTML-Elemente die im Deklarationsblock definierten Stile erhalten sollen. Selektoren sind im Wesentlichen Muster, die mit Elementen in deinem HTML-Dokument übereinstimmen. Das Verstehen von Selektoren ist grundlegend, da sie bestimmen, welche Elemente von deinen CSS-Regeln betroffen sind. Das Element oder die Elemente, die von einem Selektor anvisiert werden, werden als 'Subjekt des Selektors' bezeichnet. Beim Schreiben einer CSS-Regel gibst du zuerst den Selektor an, gefolgt von geschweiften Klammern, die die Stil-Deklarationen enthalten.<br/>Um beispielsweise die Textfarbe von Elementen zu ändern, kannst du die <kbd>color</kbd>-Eigenschaft in deinem Deklarationsblock verwenden.<br><br><pre>/* Element-Selektor */\np {\n color: orangered;\n /* │ └─── Gibt den Wert des Ausdrucks an\n │ \n └─────────── Gibt die Eigenschaft des Ausdrucks an */\n}</pre>", "description": "CSS gestaltet Elemente mit <strong>Deklarationen</strong> - Paaren aus Eigenschaften und Werten. Jede Deklaration folgt dem gleichen Muster:<br><br><pre>property: value;</pre><br>Die <strong>Eigenschaft</strong> ist das, was du ändern möchtest (wie <kbd>color</kbd> oder <kbd>background</kbd>). Der <strong>Wert</strong> ist das, worauf du es setzt. Ein Doppelpunkt trennt sie, und ein Semikolon beendet die Zeile.<br><br>Werte gibt es in verschiedenen Typen:<br>• <strong>Schlüsselwörter:</strong> <kbd>red</kbd>, <kbd>bold</kbd>, <kbd>center</kbd><br>• <strong>Zahlen mit Einheiten:</strong> <kbd>16px</kbd>, <kbd>2rem</kbd>, <kbd>100%</kbd><br>• <strong>Farben:</strong> <kbd>steelblue</kbd>, <kbd>#ff0000</kbd>",
"task": "Schreibe eine CSS-Regel mit einem Typ-Selektor, die alle Absatz-Elemente <kbd>p</kbd> im Dokument anvisiert. Mache den Text blau, indem du die <kbd>color</kbd>-Eigenschaft auf <kbd>blue</kbd> setzt.", "task": "Vervollständige die Deklaration, indem du <kbd>color: coral;</kbd> hinzufügst, um die Textfarbe zu ändern.",
"previewHTML": "<h1>Einführung in CSS-Selektoren</h1>\n<p>Dieser Absatz sollte blau werden.</p>\n<div>Dieses div-Element sollte unverändert bleiben.</div>\n<p>Dieser zweite Absatz sollte ebenfalls blau werden.</p>", "previewHTML": "<p class=\"text\">This text should turn coral.</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .text { font-size: 1.25rem; }",
"sandboxCSS": "h1, p, div { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }", "sandboxCSS": "",
"codePrefix": "/* Schreibe einen Typ-Selektor, um alle Absatz-Elemente anzuvisieren */\n", "codePrefix": ".text {\n ",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "\n}",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": "p { color: blue }", "solution": "color: coral;",
"validations": [ "validations": [
{ {
"type": "regex", "type": "property_value",
"value": "^p\\s*{", "value": { "property": "color", "expected": "coral" },
"message": "Beginne deine Regel mit <kbd>p { … }</kbd>, um alle Absatz-Elemente auszuwählen", "message": "Füge <kbd>color: coral;</kbd> hinzu"
"options": { }
"caseSensitive": false ]
} },
}, {
"id": "multiple-properties",
"title": "Mehrere Eigenschaften",
"description": "Eine Regel kann mehrere Deklarationen enthalten. Jede steht in einer eigenen Zeile und jede benötigt ein Semikolon am Ende:<br><br><pre>.box {<br> background: gold;<br> color: navy;<br> padding: 1rem;<br>}</pre><br>Die Reihenfolge spielt normalerweise keine Rolle - CSS wendet alle an. Bei Konflikten gewinnt die letzte.",
"task": "Füge zwei Deklarationen hinzu: <kbd>background: lavender;</kbd> und <kbd>padding: 1rem;</kbd>",
"previewHTML": "<div class=\"card\">A styled card with background and padding.</div>",
"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": "contains", "type": "property_value",
"value": "color:", "value": { "property": "background", "expected": "lavender" },
"message": "Füge die <kbd>color:</kbd>-Eigenschaft in deine CSS-Regel ein" "message": "Füge <kbd>background: lavender;</kbd> hinzu"
},
{
"type": "contains",
"value": "blue",
"message": "Setze den Farbwert auf <kbd>blue</kbd>"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "padding", "expected": "1rem" },
"property": "color", "message": "Füge <kbd>padding: 1rem;</kbd> hinzu"
"expected": "blue"
},
"message": "Verwende <kbd>color: blue</kbd>, um die Textfarbe zu setzen"
},
{
"type": "regex",
"value": "p\\s*{[^}]*}",
"message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer <kbd>}</kbd> zu beenden",
"options": {
"caseSensitive": false
}
} }
] ]
}, },
{ {
"id": "type-selectors", "id": "type-selectors",
"title": "Typ-Selektoren: HTML-Elemente anvisieren", "title": "Typ-Selektoren",
"description": "Typ-Selektoren (auch Tag-Name-Selektoren oder Element-Selektoren genannt) visieren HTML-Elemente basierend auf ihrem Tag-Namen an. Zum Beispiel wählt <kbd>p</kbd> alle Absatz-Elemente, <kbd>h1</kbd> alle Überschriften der ersten Ebene und <kbd>div</kbd> alle Division-Elemente aus. Typ-Selektoren sind die grundlegendste Art, Elemente auszuwählen, und wenden Stile einheitlich auf alle Instanzen eines bestimmten HTML-Elements in deinem Dokument an. Du kannst verschiedene CSS-Eigenschaften mit Typ-Selektoren definieren, wie <kbd>color</kbd> für Textfarbe, <kbd>background-color</kbd> für den Hintergrund und <kbd>font-weight</kbd> für Textbetonung. Sie bieten einen breiten Ansatz für das Styling deiner Seite und sind oft der Ausgangspunkt für spezifischeres Styling mit anderen Selektortypen.", "description": "Ein <strong>Selektor</strong> sagt dem Browser, welche Elemente gestylt werden sollen. Der einfachste Selektor ist ein <strong>Typ-Selektor</strong> — einfach der HTML-Tag-Name.<br><br><pre>p {<br> color: steelblue;<br>}</pre><br>Diese Regel zielt auf jedes <kbd>&lt;p&gt;</kbd>-Element auf der Seite. Typ-Selektoren eignen sich hervorragend für Basis-Styles.",
"task": "Schreibe drei separate CSS-Regeln mit Typ-Selektoren, um bestimmte HTML-Elemente anzuvisieren: mache <kbd>h2</kbd>-Überschriften <kbd>purple</kbd>, gib <kbd>span</kbd>-Elementen einen <kbd>yellow</kbd>-Hintergrund und mache <kbd>strong</kbd>-Elemente <kbd>red</kbd>.", "task": "Style alle Absätze. Schreibe eine Regel mit <kbd>p</kbd> als Selektor und setze <kbd>color: steelblue</kbd>.",
"previewHTML": "<h2>Typ-Selektoren Beispiel</h2>\n<p>Normaler Absatztext <span>mit einem hervorgehobenen Span</span>, der einen gelben Hintergrund haben sollte.</p>\n<p>Ein weiterer Absatz mit <strong>wichtigem, fetten Text</strong>, der rot sein sollte.</p>\n<h2>Eine weitere Überschrift</h2>", "previewHTML": "<article>\n <h2>Fresh Roasted Coffee</h2>\n <p>Our beans are sourced from small farms in Colombia and Ethiopia.</p>\n <p>Each batch is roasted weekly to ensure peak freshness.</p>\n</article>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } h2 { margin: 0 0 1rem; }",
"sandboxCSS": "h2, p, span, strong { padding: 3px; }", "sandboxCSS": "",
"codePrefix": "/* Schreibe drei separate Typ-Selektoren unten */\n\n", "codePrefix": "",
"initialCode": "/* 1. Mache h2-Überschriften lila */\n\n\n/* 2. Gib span-Elementen einen gelben Hintergrund */\n\n\n/* 3. Mache strong-Elemente rot */\n", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": "/* 1. Mache h2-Überschriften lila */\nh2 {\n color: purple;\n}\n\n/* 2. Gib span-Elementen einen gelben Hintergrund */\nspan {\n background-color: yellow;\n}\n\n/* 3. Mache strong-Elemente rot */\nstrong {\n color: red;\n}", "solution": "p {\n color: steelblue;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^h2\\s*{", "value": "p\\s*\\{",
"message": "Füge einen <kbd>h2 { … }</kbd>-Selektor hinzu" "message": "Beginne mit <kbd>p {</kbd>, um Absätze auszuwählen"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "color", "expected": "steelblue" },
"property": "color", "message": "Setze <kbd>color: steelblue</kbd>"
"expected": "purple" }
}, ]
"message": "Setze die <kbd>color</kbd>-Eigenschaft auf <kbd>purple</kbd> für h2-Elemente" },
}, {
"id": "styling-links",
"title": "Links stylen",
"description": "Typ-Selektoren funktionieren für jedes HTML-Element. Der <kbd>a</kbd>-Selektor zielt auf alle Links einer Seite.<br><br>Links haben standardmäßig eine blaue Farbe und Unterstreichung. Du kannst beides mit CSS ändern — verwende <kbd>color</kbd> für den Text und <kbd>text-decoration: none</kbd>, um die Unterstreichung zu entfernen.",
"task": "Style die Navigationslinks. Schreibe eine Regel mit <kbd>a</kbd> als Selektor und setze <kbd>color: coral</kbd>.",
"previewHTML": "<nav>\n <a href=\"#\">Home</a>\n <a href=\"#\">Menu</a>\n <a href=\"#\">About</a>\n <a href=\"#\">Contact</a>\n</nav>",
"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", "type": "regex",
"value": "h2\\s*{[^}]*}", "value": "a\\s*\\{",
"message": "Vergiss nicht, deine h2-Regel mit einer schließenden Klammer <kbd>}</kbd> zu beenden" "message": "Beginne mit <kbd>a {</kbd>, um Links auszuwählen"
},
{
"type": "regex",
"value": "^span\\s*{",
"message": "Füge einen <kbd>span { … }</kbd>-Selektor hinzu"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "color", "expected": "coral" },
"property": "background-color", "message": "Setze <kbd>color: coral</kbd>"
"expected": "yellow"
},
"message": "Setze <kbd>background-color: yellow</kbd> für span-Elemente"
},
{
"type": "regex",
"value": "span\\s*{[^}]*}",
"message": "Vergiss nicht, deine span-Regel mit einer schließenden Klammer <kbd>}</kbd> zu beenden"
},
{
"type": "regex",
"value": "^strong\\s*{",
"message": "Füge einen <kbd>strong { … }</kbd>-Selektor hinzu"
},
{
"type": "regex",
"value": "strong\\s*{\\s*color:\\s*red;[^}]*}",
"message": "Setze <kbd>color: red</kbd> für strong-Elemente"
} }
] ]
}, },
{ {
"id": "class-selectors", "id": "class-selectors",
"title": "Klassen-Selektoren: Elementgruppen stylen", "title": "Klassen-Selektoren",
"description": "Klassen-Selektoren visieren Elemente mit einem bestimmten Klassen-Attributwert an. Sie beginnen mit einem Punkt (.) gefolgt vom Klassennamen. Klassen sind mächtig, weil sie es ermöglichen, die gleichen Stile auf mehrere Elemente anzuwenden, unabhängig von ihrem Typ. Ein HTML-Element kann mehrere Klassen haben (durch Leerzeichen im class-Attribut getrennt), und eine Klasse kann auf beliebig viele Elemente angewendet werden. Bei der Verwendung von Klassen-Selektoren kannst du Eigenschaften wie <kbd>background-color</kbd> zum Setzen der Hintergrundfarbe und <kbd>font-weight</kbd> zur Kontrolle der Textdicke anwenden. Diese Flexibilität macht Klassen-Selektoren zu einer der am häufigsten verwendeten Methoden zur Anwendung von Stilen in CSS und ermöglicht modulares und wiederverwendbares Styling auf deiner gesamten Website.", "description": "Typ-Selektoren stylen <em>alle</em> Elemente dieses Typs. Aber was, wenn du nur einige davon stylen möchtest?<br><br><strong>Klassen-Selektoren</strong> zielen auf Elemente mit einem bestimmten <kbd>class</kbd>-Attribut. Sie beginnen mit einem Punkt:<br><br><pre>.badge {<br> background: coral;<br>}</pre><br>Das stylt nur Elemente mit <kbd>class=\"badge\"</kbd>.",
"task": "Erstelle eine CSS-Regel mit einem Klassen-Selektor, die Elemente mit der Klasse <kbd>highlight</kbd> anvisiert. Gib diesen Elementen einen <kbd>yellow</kbd>-Hintergrund und <kbd>bold</kbd>-Text.", "task": "Style das Benachrichtigungs-Badge. Schreibe eine Regel mit <kbd>.badge</kbd> als Selektor und setze <kbd>background: tomato</kbd>.",
"previewHTML": "<h2>Verwendung von Klassen-Selektoren</h2>\n<p>Dies ist ein normaler Absatz, aber <span class=\"highlight\">dieser Span hat die highlight-Klasse</span> angewendet.</p>\n<p class=\"highlight\">Dieser gesamte Absatz hat die highlight-Klasse.</p>\n<ul>\n <li>Normales Listenelement</li>\n <li class=\"highlight\">Dieses Listenelement ist hervorgehoben</li>\n</ul>", "previewHTML": "<header>\n <h1>Dashboard</h1>\n <span class=\"badge\">3</span>\n</header>\n<p>You have new notifications waiting.</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "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": "h2, p, li { padding: 5px; margin-bottom: 10px; }",
"codePrefix": "/* Erstelle einen Klassen-Selektor für Elemente mit der 'highlight'-Klasse */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^\\.highlight\\s*{",
"message": "Beginne deine Regel mit <kbd>.highlight { … }</kbd>, um einen Klassen-Selektor zu erstellen",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "background-color:",
"message": "Füge die <kbd>background-color:</kbd>-Eigenschaft hinzu"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "yellow"
},
"message": "Setze die Hintergrundfarbe auf <kbd>yellow</kbd>"
},
{
"type": "contains",
"value": "font-weight:",
"message": "Füge die <kbd>font-weight:</kbd>-Eigenschaft hinzu"
},
{
"type": "property_value",
"value": {
"property": "font-weight",
"expected": "bold"
},
"message": "Setze font-weight auf <kbd>bold</kbd>"
},
{
"type": "regex",
"value": "\\.highlight\\s*{[^}]*}",
"message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer <kbd>}</kbd> zu beenden",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "multiple-classes",
"title": "Mit mehreren Klassen arbeiten",
"description": "HTML-Elemente können mehrere Klassen gleichzeitig haben, was komponierbare und modulare CSS-Designs ermöglicht. Wenn ein Element mehrere Klassen hat, erhält es Stile von allen passenden Klassen-Selektoren. Dieser Ansatz ermöglicht es dir, eine Bibliothek wiederverwendbarer CSS-Klassen aufzubauen, die auf verschiedene Arten kombiniert werden können. Du kannst auch Elemente anvisieren, die eine bestimmte Kombination von Klassen haben, indem du Klassen-Selektoren ohne Leerzeichen verkettst (z.B. <kbd>.class1.class2</kbd>). Beim Stylen dieser Elemente könntest du Eigenschaften wie <kbd>border-color</kbd> verwenden, um die Farbe von Element-Rahmen zu ändern, und <kbd>background-color</kbd>, um die Hintergrundfarbe von Elementen zu setzen. Diese Technik ermöglicht bedingte Stile, die nur gelten, wenn bestimmte Klassen zusammen erscheinen.",
"task": "Vervollständige die CSS-Regel, die Elemente mit sowohl <kbd>card</kbd> als auch <kbd>featured</kbd>-Klassen anvisiert, indem du die Selektoren verkettest. Setze border-color auf gold und background-color auf lemonchiffon, um hervorgehobene Karten hervorzuheben.",
"previewHTML": "<h2>Mehrfach-Klassen-Kombinationen</h2>\n<div class=\"card\">Normale Karte</div>\n<div class=\"card featured\">Hervorgehobene Karte</div>\n<div class=\"featured\">Nur hervorgehoben (keine Karte)</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } .card { border: 2px solid gray; padding: 15px; margin-bottom: 10px; border-radius: 5px; }",
"sandboxCSS": "", "sandboxCSS": "",
"codePrefix": "/* Die .card-Klasse hat bereits grundlegendes Styling */\n/* Visiere jetzt Elemente mit BEIDEN Klassen an: 'card' UND 'featured' */\n", "codePrefix": "",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": ".card.featured { border-color: gold; background-color: lemonchiffon }", "solution": ".badge {\n background: tomato;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^\\.card\\.featured\\s*{", "value": "\\.badge\\s*\\{",
"message": "Verkette die Selektoren als <kbd>.card.featured</kbd> (kein Leerzeichen dazwischen)", "message": "Beginne mit <kbd>.badge {</kbd> (vergiss den Punkt nicht!)"
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "border-color:",
"message": "Füge die <kbd>border-color</kbd>-Eigenschaft hinzu"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "background", "expected": "tomato" },
"property": "border-color", "message": "Setze <kbd>background: tomato</kbd>"
"expected": "gold"
},
"message": "Setze die Rahmenfarbe auf <kbd>gold</kbd>"
},
{
"type": "regex",
"value": "\\.card\\.featured\\s*{[^}]*;",
"message": "Vergiss nicht, deine CSS-Regel mit einem Semikolon <kbd>;</kbd> zu beenden"
},
{
"type": "contains",
"value": "background-color:",
"message": "Füge die <kbd>background-color</kbd>-Eigenschaft hinzu"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "lemonchiffon"
},
"message": "Setze die Hintergrundfarbe auf <kbd>lemonchiffon</kbd>"
},
{
"type": "regex",
"value": "\\.card\\.featured\\s*{[^}]*}",
"message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer <kbd>}</kbd> zu beenden",
"options": {
"caseSensitive": true
}
} }
] ]
}, },
{ {
"id": "class-with-type", "id": "button-variants",
"title": "Typ- und Klassen-Selektoren kombinieren", "title": "Button-Varianten",
"description": "Du kannst Typ-Selektoren mit Klassen-Selektoren kombinieren, um bestimmte HTML-Elemente anzuvisieren, die eine bestimmte Klasse haben. Dies erstellt einen spezifischeren Selektor, der nur passt, wenn beide Bedingungen wahr sind: das Element ist vom angegebenen Typ UND es hat die angegebene Klasse. Zum Beispiel würde <kbd>p.note</kbd> Absatz-Elemente mit der Klasse <kbd>note</kbd> auswählen, aber keine divs oder spans mit derselben Klasse. Du kannst diese kombinierten Selektionen mit Eigenschaften wie <kbd>background-color</kbd> stylen, um einen farbigen Hintergrund für deine Elemente zu setzen. Dieser Ansatz ermöglicht es dir, verschiedene Stile auf dieselbe Klasse anzuwenden, wenn sie auf verschiedenen Elementtypen erscheint.", "description": "Elemente können mehrere Klassen haben. Wenn du Klassen-Selektoren ohne Leerzeichen verkettst, zielst du auf Elemente, die <em>alle</em> diese Klassen haben:<br><br><pre>.btn.primary {<br> background: steelblue;<br>}</pre><br>Das zielt auf Elemente mit <kbd>class=\"btn primary\"</kbd>, nicht nur auf <kbd>.btn</kbd> oder nur <kbd>.primary</kbd>.",
"task": "Erstelle eine CSS-Regel, die speziell <kbd>&lt;span&gt;</kbd>-Elemente mit der Klasse <kbd>highlight</kbd> anvisiert. Gib diesen Elementen einen orangen Hintergrund, während andere Elemente mit der highlight-Klasse unverändert bleiben.", "task": "Style den primären Button. Schreibe eine Regel mit <kbd>.btn.primary</kbd> als Selektor und setze <kbd>background: steelblue</kbd>.",
"previewHTML": "<h2>Typ- und Klassen-Kombinationen</h2>\n<p>Dieser Absatz hat einen <span class=\"highlight\">hervorgehobenen Span</span>, der einen orangen Hintergrund haben sollte.</p>\n<p class=\"highlight\">Dieser Absatz hat die highlight-Klasse, sollte aber KEINEN orangen Hintergrund haben.</p>", "previewHTML": "<div class=\"actions\">\n <button class=\"btn\">Cancel</button>\n <button class=\"btn primary\">Save Changes</button>\n</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } .highlight { font-weight: bold; }", "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": "h2, p, span { padding: 5px; }",
"codePrefix": "/* Die .highlight-Klasse setzt bereits font-weight auf bold */\n/* Visiere jetzt NUR span-Elemente mit der highlight-Klasse an */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^span\\.highlight\\s*{",
"message": "Verwende den <kbd>span.highlight</kbd>-Selektor (kein Leerzeichen zwischen Element und Klasse)",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "background-color:",
"message": "Füge die <kbd>background-color</kbd>-Eigenschaft hinzu"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "orange"
},
"message": "Setze die Hintergrundfarbe auf <kbd>orange</kbd>"
},
{
"type": "regex",
"value": "span\\.highlight\\s*{[^}]*}",
"message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer <kbd>}</kbd> zu beenden",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "id-selectors",
"title": "ID-Selektoren: Einzigartige Elemente anvisieren",
"description": "ID-Selektoren visieren Elemente mit einem bestimmten id-Attribut an. Sie beginnen mit einem Raute-/Hash-Zeichen (#) gefolgt vom ID-Namen. Im Gegensatz zu Klassen müssen IDs innerhalb eines Dokuments einzigartig sein jeder ID-Wert sollte nur einmal pro Seite verwendet werden. ID-Selektoren haben eine höhere Spezifität als Klassen- oder Element-Selektoren, was bedeutet, dass sie diese Selektoren bei Konflikten überschreiben. Beim Stylen mit ID-Selektoren kannst du Eigenschaften wie <kbd>color</kbd> verwenden, um die Textfarbe zu definieren, und <kbd>text-decoration</kbd>, um das Erscheinungsbild von Text zu kontrollieren, wie das Hinzufügen von Unterstreichungen zu Elementen. Wegen ihrer Einzigartigkeitsanforderung werden IDs am besten für einmalige Elemente wie Seitenköpfe, Hauptnavigation oder spezifische einzigartige Komponenten verwendet, die nur einmal auf einer Seite erscheinen.",
"task": "Erstelle eine CSS-Regel mit einem ID-Selektor, die das Element mit der ID <kbd>main-title</kbd> anvisiert. Setze seine Farbe auf purple und füge eine Unterstreichung mit <kbd>text-decoration: underline</kbd> hinzu.",
"previewHTML": "<h1 id=\"main-title\">Haupt-Seitentitel</h1>\n<p>Normaler Absatzinhalt.</p>\n<h2>Sekundäre Überschrift</h2>\n<p id=\"intro\">Einführungsabsatz (andere ID).</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }",
"sandboxCSS": "h1, h2, p { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }",
"codePrefix": "/* Erstelle einen ID-Selektor für das Element mit id=\"main-title\" */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^#main-title\\s*{",
"message": "Beginne deine Regel mit <kbd>#main-title</kbd>, um einen ID-Selektor zu erstellen",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "color:",
"message": "Füge die <kbd>color</kbd>-Eigenschaft hinzu"
},
{
"type": "property_value",
"value": {
"property": "color",
"expected": "purple"
},
"message": "Setze die Farbe auf <kbd>purple</kbd>"
},
{
"type": "contains",
"value": "text-decoration:",
"message": "Füge die <kbd>text-decoration</kbd>-Eigenschaft hinzu"
},
{
"type": "property_value",
"value": {
"property": "text-decoration",
"expected": "underline"
},
"message": "Setze text-decoration auf <kbd>underline</kbd>"
},
{
"type": "regex",
"value": "#main-title\\s*{[^}]*}",
"message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer <kbd>}</kbd> zu beenden",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "id-with-type",
"title": "Typ- und ID-Selektoren kombinieren",
"description": "Ähnlich wie du Typ- und Klassen-Selektoren kombinieren kannst, kannst du auch Typ-Selektoren mit ID-Selektoren kombinieren. Zum Beispiel visiert <kbd>h1#title</kbd> ein h1-Element mit der ID 'title' an. Bei diesem kombinierten Ansatz kannst du CSS-Eigenschaften wie <kbd>font-style</kbd> anwenden, um die Neigung des Textes zu kontrollieren und ihn kursiv oder normal zu machen. Obwohl diese Selektor-Kombination spezifischer ist als die Verwendung nur des ID-Selektors, ist sie oft unnötig, da IDs bereits einzigartig im Dokument sein sollten. Diese Technik kann jedoch nützlich sein, um die Lesbarkeit des Codes zu verbessern oder wenn du betonen möchtest, dass eine bestimmte ID nur auf einem bestimmten Elementtyp erscheinen sollte.",
"task": "Erstelle eine CSS-Regel, die einen Typ-Selektor mit einem ID-Selektor kombiniert, um speziell ein Absatz-Element mit der ID <kbd>special</kbd> anzuvisieren. Setze seinen Schriftstil auf kursiv.",
"previewHTML": "<h2 id=\"special\">Überschrift mit ID \"special\" (sollte NICHT betroffen sein)</h2>\n<p id=\"special\">Absatz mit ID \"special\" (sollte kursiv werden)</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }",
"sandboxCSS": "h2, p { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }",
"codePrefix": "/* Erstelle einen kombinierten Typ+ID-Selektor für einen Absatz mit id=\"special\" */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^p#special\\s*{",
"message": "Verwende <kbd>p#special</kbd>, um Absätze mit ID <kbd>special</kbd> anzuvisieren",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "font-style:",
"message": "Füge die <kbd>font-style</kbd>-Eigenschaft hinzu"
},
{
"type": "property_value",
"value": {
"property": "font-style",
"expected": "italic"
},
"message": "Setze font-style auf <kbd>italic</kbd>"
},
{
"type": "regex",
"value": "p#special\\s*{[^}]*}",
"message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer <kbd>}</kbd> zu beenden",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "selector-lists",
"title": "Selektor-Listen: Gleiche Regeln auf mehrere Selektoren anwenden",
"description": "Wenn mehrere Elemente das gleiche Styling benötigen, kannst du sie mit einer Selektor-Liste (auch Gruppierungs-Selektoren genannt) zusammenfassen. Selektor-Listen werden erstellt, indem einzelne Selektoren durch Kommas getrennt werden. Dieser Ansatz reduziert Wiederholungen in deinem CSS und macht es wartbarer und effizienter. Zum Beispiel wendet <kbd>h1, h2, h3 { color: blue; }</kbd> die gleiche blaue Farbe auf alle drei Überschriftenebenen an. Beim Stylen mehrerer Selektoren gleichzeitig kannst du Eigenschaften wie <kbd>background-color</kbd> für den Hintergrund, <kbd>border-left</kbd> für einen linken Rahmen mit bestimmter Dicke, Stil und Farbe, und <kbd>padding-left</kbd> anwenden, um Abstand zwischen dem Inhalt und dem linken Rahmen zu schaffen. Leerzeichen um Kommas sind optional, und jeder Selektor in der Liste kann ein beliebiger gültiger Selektortyp sein Elemente, Klassen, IDs oder sogar komplexere Selektoren.",
"task": "Erstelle eine Selektor-Liste, die die gleichen Stile auf drei verschiedene Elemente anwendet: Absätze mit der Klasse <kbd>note</kbd>, Listenelemente mit der Klasse <kbd>important</kbd> und das Element mit der ID <kbd>summary</kbd>. Gib ihnen einen <kbd>lightyellow</kbd>-Hintergrund, einen <kbd>gold</kbd>-linken Rahmen und etwas linkes <kbd>padding</kbd>.",
"previewHTML": "<p class=\"note\">Dies ist ein Notiz-Absatz.</p>\n<ul>\n <li>Normales Listenelement</li>\n <li class=\"important\">Wichtiges Listenelement</li>\n</ul>\n<div id=\"summary\">Zusammenfassungs-Abschnitt</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }",
"sandboxCSS": "p, li, div { padding: 8px; margin-bottom: 8px; border: 1px dashed gray; }",
"codePrefix": "/* Erstelle eine Selektor-Liste, um die gleichen Stile auf mehrere verschiedene Elemente anzuwenden */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"solution": "p.note,\nli.important,\n#summary {\n background-color: lightyellow;\n border-left: 3px solid gold;\n padding-left: 10px\n}",
"validations": [
{
"type": "contains",
"value": "p.note",
"message": "Füge <kbd>p.note</kbd> in deine Selektor-Liste ein",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "li.important",
"message": "Füge <kbd>li.important</kbd> in deine Selektor-Liste ein",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "#summary",
"message": "Füge <kbd>#summary</kbd> in deine Selektor-Liste ein",
"options": {
"caseSensitive": true
}
},
{
"type": "regex",
"value": "(p\\.note|li\\.important|#summary)\\s*,\\s*(p\\.note|li\\.important|#summary)\\s*,\\s*(p\\.note|li\\.important|#summary)",
"message": "Erstelle eine kommagetrennte Liste mit allen drei Selektoren",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "background-color:",
"message": "Füge die <kbd>background-color</kbd>-Eigenschaft hinzu"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "lightyellow"
},
"message": "Setze die Hintergrundfarbe auf <kbd>lightyellow</kbd>"
},
{
"type": "contains",
"value": "border-left:",
"message": "Füge die <kbd>border-left</kbd>-Eigenschaft hinzu"
},
{
"type": "property_value",
"value": {
"property": "border-left",
"expected": "3px solid gold"
},
"message": "Verwende <kbd>border-left: 3px solid gold</kbd>, um einen linken Rahmen zu erstellen"
},
{
"type": "contains",
"value": "padding-left:",
"message": "Füge die <kbd>padding-left</kbd>-Eigenschaft hinzu"
},
{
"type": "property_value",
"value": {
"property": "padding-left",
"expected": "10px"
},
"message": "Verwende <kbd>padding-left: 10px</kbd>, um linkes Padding hinzuzufügen"
}
]
},
{
"id": "universal-selector",
"title": "Der universelle Selektor: Alles anvisieren",
"description": "Der universelle Selektor wird durch ein Sternchen (*) gekennzeichnet und passt auf jedes Element jedes Typs. Er wählt alles im Dokument aus oder, wenn er mit anderen Selektoren kombiniert wird, alles innerhalb eines bestimmten Kontexts. Zum Beispiel entfernt <kbd>* { margin: 0; }</kbd> Ränder von allen Elementen, während <kbd>article *</kbd> alle Elemente innerhalb von article-Elementen auswählt. Bei der Verwendung des universellen Selektors in Kombination mit anderen Selektoren kannst du Eigenschaften wie <kbd>margin</kbd> anwenden, um die Abstände um Elemente zu kontrollieren. Der universelle Selektor ist mächtig, sollte aber wegen seiner breiten Auswirkung vorsichtig verwendet werden. Er wird häufig in CSS-Resets verwendet, um Standard-Browser-Styling zu überschreiben, oder um alle Kinder eines bestimmten Elements anzuvisieren.",
"task": "Verwende den universellen Selektor, um Ränder von allen Elementen innerhalb des Container-divs zu entfernen. Erstelle eine Regel mit <kbd>div.container *</kbd> als Selektor und setze <kbd>margin: 0</kbd>.",
"previewHTML": "<div class=\"container\">\n <h2>Innerhalb des Containers</h2>\n <p>Dieser Absatz ist innerhalb des Containers.</p>\n <ul>\n <li>Listenelement innerhalb des Containers</li>\n </ul>\n</div>\n<p>Dieser Absatz ist außerhalb des Containers und sollte nicht betroffen sein.</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } div.container { border: 2px solid navy; padding: 15px; background-color: lavender; } h2, p, ul, li { margin: 15px 0; }",
"sandboxCSS": "", "sandboxCSS": "",
"codePrefix": "/* Verwende den universellen Selektor, um alle Elemente innerhalb des Containers anzuvisieren */\n", "codePrefix": "",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": ".btn.primary {\n background: steelblue;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^div\\.container\\s+\\*\\s*{", "value": "\\.btn\\.primary\\s*\\{",
"message": "Verwende <kbd>div.container *</kbd>-Selektor (mit einem Leerzeichen zwischen container und *)", "message": "Verwende <kbd>.btn.primary {</kbd> (kein Leerzeichen zwischen den Klassen)"
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "margin:",
"message": "Füge die <kbd>margin</kbd>-Eigenschaft hinzu"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "background", "expected": "steelblue" },
"property": "margin", "message": "Setze <kbd>background: steelblue</kbd>"
"expected": "0"
},
"message": "Setze margin auf <kbd>0</kbd>"
},
{
"type": "regex",
"value": "div\\.container\\s+\\*\\s*{[^}]*}",
"message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer <kbd>}</kbd> zu beenden",
"options": {
"caseSensitive": true
}
} }
] ]
}, },
{ {
"id": "specificity-basics", "id": "specific-elements",
"title": "Selektor-Spezifität verstehen", "title": "Spezifische Elemente ansprechen",
"description": "CSS-Spezifität bestimmt, welche Stile Vorrang haben, wenn mehrere widersprüchliche Regeln auf dasselbe Element abzielen. Spezifität folgt einem hierarchischen System: Inline-Stile haben die höchste Spezifität, gefolgt von ID-Selektoren, dann Klassen-/Attribut-/Pseudo-Klassen-Selektoren und schließlich Element-/Pseudo-Element-Selektoren. Dies kann als vierteilige Punktzahl (inline, ID, Klasse, Element) konzeptualisiert werden. Beim Erstellen mehrerer Regeln, die auf dieselben Elemente abzielen könnten, kannst du die <kbd>color</kbd>-Eigenschaft verwenden, um Textfarben zu setzen, und die Spezifität bestimmt, welche Farbe tatsächlich angewendet wird. Das Verstehen von Spezifität ist entscheidend für vorhersagbares Styling und das Debuggen von CSS-Konflikten. Wenn zwei Selektoren gleiche Spezifität haben, gewinnt derjenige, der zuletzt im Stylesheet kommt.", "description": "Manchmal soll eine Klasse auf verschiedenen Elementen unterschiedlich aussehen. Kombiniere einen Typ-Selektor mit einem Klassen-Selektor (ohne Leerzeichen), um spezifischer zu sein:<br><br><pre>a.btn {<br> text-decoration: none;<br>}</pre><br>Das stylt nur <kbd>&lt;a&gt;</kbd>-Elemente mit der <kbd>btn</kbd>-Klasse, nicht <kbd>&lt;button&gt;</kbd>-Elemente mit dieser Klasse.",
"task": "Untersuche die vorhandenen CSS-Regeln und füge eine neue Regel mit höherer Spezifität hinzu, um die Textfarbe des Absatzes zu überschreiben. Erstelle eine Regel mit '.content p' als Selektor und setze color: green.", "task": "Entferne die Unterstreichung von Link-Buttons. Schreibe eine Regel mit <kbd>a.btn</kbd> als Selektor und setze <kbd>text-decoration: none</kbd>.",
"previewHTML": "<div class=\"content\">\n <p>Welche Farbe wird dieser Absatz haben? Schau dir die CSS-Regeln und ihre Spezifität an.</p>\n</div>", "previewHTML": "<div class=\"actions\">\n <button class=\"btn\">Regular Button</button>\n <a href=\"#\" class=\"btn\">Link Button</a>\n</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "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": "p { border: 1px dashed gray; padding: 10px; }", "sandboxCSS": "",
"codePrefix": "/* Diese CSS-Regeln visieren denselben Absatz an, haben aber unterschiedliche Spezifität */\n\n/* Regel 1: Element-Selektor (niedrigste Spezifität) */\np {\n color: red;\n}\n\n/* Regel 2: Nachfahren-Selektor (höhere Spezifität als nur 'p') */\n", "codePrefix": "",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": "a.btn {\n text-decoration: none;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^\\.content\\s+p\\s*{", "value": "a\\.btn\\s*\\{",
"message": "Verwende <kbd>.content p</kbd> als deinen Selektor (beachte das Leerzeichen dazwischen)", "message": "Verwende <kbd>a.btn {</kbd> (Typ + Klasse, kein Leerzeichen)"
"options": {
"caseSensitive": true
}
}, },
{ {
"type": "contains", "type": "property_value",
"value": "color:", "value": { "property": "text-decoration", "expected": "none" },
"message": "Füge die <kbd>color</kbd>-Eigenschaft hinzu" "message": "Setze <kbd>text-decoration: none</kbd>"
}
]
},
{
"id": "grouping-selectors",
"title": "Selektoren gruppieren",
"description": "Wenn mehrere Elemente die gleichen Styles brauchen, liste sie durch Kommas getrennt auf. Das hält dein CSS sauber und wartbar.<br><br><pre>h1, h2, h3 {<br> color: steelblue;<br>}</pre><br>Das wendet die gleiche Farbe auf alle drei Überschriftenebenen in einer Regel an.",
"task": "Style alle Überschriften einheitlich. Füge <kbd>color: steelblue</kbd> zum gruppierten <kbd>h1, h2, h3</kbd>-Selektor hinzu.",
"previewHTML": "<article><h1>Main Title</h1><p>Introduction paragraph with some text.</p><h2>Section Heading</h2><p>More content here.</p><h3>Subsection</h3><p>Final paragraph.</p></article>",
"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": "Setze <kbd>color: steelblue</kbd>"
}
]
},
{
"id": "descendant-selectors",
"title": "Nachfahren-Selektoren",
"description": "Ziele auf Elemente innerhalb anderer Elemente mit einem Leerzeichen zwischen den Selektoren. Das ist eines der nützlichsten Muster in CSS.<br><br><pre>.nav a {<br> color: white;<br>}</pre><br>Das stylt nur Links innerhalb von <kbd>.nav</kbd> und lässt andere Links unverändert.",
"task": "Style Navigationslinks anders. Schreibe eine Regel mit <kbd>.nav a</kbd> als Selektor und setze <kbd>color: white</kbd>.",
"previewHTML": "<nav class=\"nav\"><a href=\"#\">Home</a><a href=\"#\">About</a><a href=\"#\">Contact</a></nav><p>Read more in our <a href=\"#\">documentation</a>.</p>",
"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": "Verwende <kbd>.nav a {</kbd> (Leerzeichen zwischen .nav und a)"
}, },
{ {
"type": "contains", "type": "property_value",
"value": "green", "value": { "property": "color", "expected": "white" },
"message": "" "message": "Setze <kbd>color: white</kbd>"
}
]
},
{
"id": "nested-styling",
"title": "Verschachtelte Styles",
"description": "Nachfahren-Selektoren ermöglichen kontextabhängige Styles. Das gleiche Element kann je nach Position unterschiedlich aussehen.<br><br>Zum Beispiel könnten Absätze in einer <kbd>.card</kbd> kleiner sein als Absätze in einem <kbd>article</kbd>.",
"task": "Mache Absätze innerhalb der Karte kleiner. Schreibe eine Regel mit <kbd>.card p</kbd> als Selektor und setze <kbd>font-size: 0.9rem</kbd>.",
"previewHTML": "<article><h2>Article Title</h2><p>This is a regular article paragraph with normal-sized text for comfortable reading.</p><div class=\"card\"><strong>Quick Tip</strong><p>Card paragraphs should be slightly smaller to fit the compact design.</p></div><p>Back to regular article text here.</p></article>",
"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": "Verwende <kbd>.card p {</kbd> (Leerzeichen zwischen .card und p)"
},
{
"type": "property_value",
"value": { "property": "font-size", "expected": "0.9rem" },
"message": "Setze <kbd>font-size: 0.9rem</kbd>"
} }
] ]
} }

View File

@@ -1,548 +1,257 @@
{ {
"$schema": "../../schemas/code-crispies-module-schema.json", "$schema": "../../schemas/code-crispies-module-schema.json",
"id": "css-basic-selectors", "id": "css-basic-selectors",
"title": "CSS Selectors", "title": "Fundamentos de CSS",
"description": "CSS selectors are the foundation of styling web pages, allowing you to target specific HTML elements for styling. This module introduces fundamental selector types including element type selectors, class selectors, ID selectors, and the universal selector.", "description": "Aprende los bloques fundamentales de CSS: propiedades, valores y selectores. Este módulo te enseña las reglas de sintaxis que sigue cada declaración CSS.",
"difficulty": "beginner", "difficulty": "beginner",
"lessons": [ "lessons": [
{ {
"id": "introduction-to-selectors", "id": "css-properties",
"title": "What's a Selector?", "title": "Propiedades CSS",
"description": "A CSS selector is the first part of a CSS rule that tells the browser which HTML elements should receive the styles defined in the declaration block. Selectors are essentially patterns that match against elements in your HTML document. Understanding selectors is fundamental because they determine which elements your CSS rules will affect. The element or elements targeted by a selector are referred to as the 'subject of the selector.' When writing a CSS rule, you first specify the selector, followed by curly braces that contain the style declarations.<br/>For example, to change the text color of elements, you can use the <kbd>color</kbd> property within your declaration block.<br><br><pre>/* Element selector */\np {\n color: orangered;\n /* │ └─── Indicates the value of the expression\n │ \n └─────────── Indicates the property of the expression */\n}</pre>", "description": "CSS estiliza elementos usando <strong>declaraciones</strong> - pares de propiedades y valores. Cada declaración sigue el mismo patrón:<br><br><pre>property: value;</pre><br>La <strong>propiedad</strong> es lo que quieres cambiar (como <kbd>color</kbd> o <kbd>background</kbd>). El <strong>valor</strong> es a lo que lo estableces. Dos puntos los separan, y un punto y coma termina la línea.<br><br>Los valores vienen en diferentes tipos:<br>• <strong>Palabras clave:</strong> <kbd>red</kbd>, <kbd>bold</kbd>, <kbd>center</kbd><br>• <strong>Números con unidades:</strong> <kbd>16px</kbd>, <kbd>2rem</kbd>, <kbd>100%</kbd><br>• <strong>Colores:</strong> <kbd>steelblue</kbd>, <kbd>#ff0000</kbd>",
"task": "Write a CSS rule using a type selector that targets all paragraph elements <kbd>p</kbd> in the document. Make the text blue by setting the <kbd>color</kbd> property to <kbd>blue</kbd>.", "task": "Completa la declaración añadiendo <kbd>color: coral;</kbd> para cambiar el color del texto.",
"previewHTML": "<h1>Introduction to CSS Selectors</h1>\n<p>This paragraph should turn blue.</p>\n<div>This div element should remain unchanged.</div>\n<p>This second paragraph should also turn blue.</p>", "previewHTML": "<p class=\"text\">This text should turn coral.</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .text { font-size: 1.25rem; }",
"sandboxCSS": "h1, p, div { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }", "sandboxCSS": "",
"codePrefix": "/* Write a type selector to target all paragraph elements */\n", "codePrefix": ".text {\n ",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "\n}",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": "p { color: blue }", "solution": "color: coral;",
"validations": [ "validations": [
{ {
"type": "regex", "type": "property_value",
"value": "^p\\s*{", "value": { "property": "color", "expected": "coral" },
"message": "Start your rule with <kbd>p { … }</kbd> to select all paragraph elements", "message": "Añade <kbd>color: coral;</kbd>"
"options": { }
"caseSensitive": false ]
} },
}, {
"id": "multiple-properties",
"title": "Múltiples propiedades",
"description": "Una regla puede tener múltiples declaraciones. Cada una va en su propia línea, y cada una necesita un punto y coma al final:<br><br><pre>.box {<br> background: gold;<br> color: navy;<br> padding: 1rem;<br>}</pre><br>El orden normalmente no importa - CSS las aplica todas. Cuando hay conflictos, la última gana.",
"task": "Añade dos declaraciones: <kbd>background: lavender;</kbd> y <kbd>padding: 1rem;</kbd>",
"previewHTML": "<div class=\"card\">A styled card with background and padding.</div>",
"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": "contains", "type": "property_value",
"value": "color:", "value": { "property": "background", "expected": "lavender" },
"message": "Include the <kbd>color:</kbd> property in your CSS rule" "message": "Añade <kbd>background: lavender;</kbd>"
},
{
"type": "contains",
"value": "blue",
"message": "Set the color value to <kbd>blue</kbd>"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "padding", "expected": "1rem" },
"property": "color", "message": "Añade <kbd>padding: 1rem;</kbd>"
"expected": "blue"
},
"message": "Use <kbd>color: blue</kbd> to set the text color"
},
{
"type": "regex",
"value": "p\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": false
}
} }
] ]
}, },
{ {
"id": "type-selectors", "id": "type-selectors",
"title": "Type Selectors", "title": "Selectores de tipo",
"description": "Type selectors (also called tag name selectors or element selectors) target HTML elements based on their tag name. For example, <kbd>p</kbd> selects all paragraph elements, <kbd>h1</kbd> selects all level-one headings, and <kbd>div</kbd> selects all division elements. Type selectors are the most fundamental way to select elements, applying styles consistently to all instances of a particular HTML element throughout your document. You can define a variety of CSS properties with type selectors, such as <kbd>color</kbd> for text color, <kbd>background-color</kbd> for the background, and <kbd>font-weight</kbd> for text emphasis. They provide a broad approach for styling your page and are often the starting point for more specific styling using other selector types.", "description": "Un <strong>selector</strong> le dice al navegador qué elementos estilizar. El selector más simple es un <strong>selector de tipo</strong> — simplemente el nombre de la etiqueta HTML.<br><br><pre>p {<br> color: steelblue;<br>}</pre><br>Esta regla apunta a cada elemento <kbd>&lt;p&gt;</kbd> en la página. Los selectores de tipo son geniales para establecer estilos base.",
"task": "Write three separate CSS rules using type selectors to target specific HTML elements: make <kbd>h2</kbd> headings <kbd>purple</kbd>, give <kbd>span</kbd> elements a <kbd>yellow</kbd> background, and make <kbd>strong</kbd> elements <kbd>red</kbd>.", "task": "Estiliza todos los párrafos. Escribe una regla con <kbd>p</kbd> como selector y establece <kbd>color: steelblue</kbd>.",
"previewHTML": "<h2>Type Selectors Example</h2>\n<p>Regular paragraph text <span>with a highlighted span</span> that should have a yellow background.</p>\n<p>Another paragraph with <strong>strong important text</strong> that should be red.</p>\n<h2>Another Heading</h2>", "previewHTML": "<article>\n <h2>Fresh Roasted Coffee</h2>\n <p>Our beans are sourced from small farms in Colombia and Ethiopia.</p>\n <p>Each batch is roasted weekly to ensure peak freshness.</p>\n</article>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } h2 { margin: 0 0 1rem; }",
"sandboxCSS": "h2, p, span, strong { padding: 3px; }", "sandboxCSS": "",
"codePrefix": "/* Write three separate type selectors below */\n\n", "codePrefix": "",
"initialCode": "/* 1. Make h2 headings purple */\n\n\n/* 2. Give span elements a yellow background */\n\n\n/* 3. Make strong elements red */\n", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": "/* 1. Make h2 headings purple */\nh2 {\n color: purple;\n}\n\n/* 2. Give span elements a yellow background */\nspan {\n background-color: yellow;\n}\n\n/* 3. Make strong elements red */\nstrong {\n color: red;\n}", "solution": "p {\n color: steelblue;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^h2\\s*{", "value": "p\\s*\\{",
"message": "Include an <kbd>h2 { … }</kbd> selector" "message": "Empieza con <kbd>p {</kbd> para seleccionar párrafos"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "color", "expected": "steelblue" },
"property": "color", "message": "Establece <kbd>color: steelblue</kbd>"
"expected": "purple" }
}, ]
"message": "Set the <kbd>color</kbd> property to <kbd>purple</kbd> for h2 elements" },
}, {
"id": "styling-links",
"title": "Estilizando enlaces",
"description": "Los selectores de tipo funcionan para cualquier elemento HTML. El selector <kbd>a</kbd> apunta a todos los enlaces de una página.<br><br>Los enlaces tienen un color azul y subrayado por defecto. Puedes cambiar ambos con CSS — usa <kbd>color</kbd> para el texto y <kbd>text-decoration: none</kbd> para quitar el subrayado.",
"task": "Estiliza los enlaces de navegación. Escribe una regla con <kbd>a</kbd> como selector y establece <kbd>color: coral</kbd>.",
"previewHTML": "<nav>\n <a href=\"#\">Home</a>\n <a href=\"#\">Menu</a>\n <a href=\"#\">About</a>\n <a href=\"#\">Contact</a>\n</nav>",
"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", "type": "regex",
"value": "h2\\s*{[^}]*}", "value": "a\\s*\\{",
"message": "Make sure to close your h2 rule with a closing brace <kbd>}</kbd>" "message": "Empieza con <kbd>a {</kbd> para seleccionar enlaces"
},
{
"type": "regex",
"value": "^span\\s*{",
"message": "Include a <kbd>span { … }</kbd> selector"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "color", "expected": "coral" },
"property": "background-color", "message": "Establece <kbd>color: coral</kbd>"
"expected": "yellow"
},
"message": "Set a <kbd>background-color: yellow</kbd> for span elements"
},
{
"type": "regex",
"value": "span\\s*{[^}]*}",
"message": "Make sure to close your span rule with a closing brace <kbd>}</kbd>"
},
{
"type": "regex",
"value": "^strong\\s*{",
"message": "Include a <kbd>strong { … }</kbd> selector"
},
{
"type": "regex",
"value": "strong\\s*{\\s*color:\\s*red;[^}]*}",
"message": "Set the <kbd>color: red</kbd> for strong elements"
} }
] ]
}, },
{ {
"id": "class-selectors", "id": "class-selectors",
"title": "Class Selectors", "title": "Selectores de clase",
"description": "Class selectors target elements with a specific class attribute value. They begin with a dot (.) followed by the class name. Classes are powerful because they allow you to apply the same styles to multiple elements regardless of their type. An HTML element can have multiple classes (separated by spaces in the class attribute), and a class can be applied to any number of elements. When using class selectors, you can apply properties like <kbd>background-color</kbd> to set the background color of elements, and <kbd>font-weight</kbd> to control text thickness, making text bold or normal. This flexibility makes class selectors one of the most commonly used methods for applying styles in CSS, allowing for modular and reusable styling across your website.", "description": "Los selectores de tipo estilizan <em>todos</em> los elementos de ese tipo. ¿Pero qué si quieres estilizar solo algunos de ellos?<br><br>Los <strong>selectores de clase</strong> apuntan a elementos con un atributo <kbd>class</kbd> específico. Empiezan con un punto:<br><br><pre>.badge {<br> background: coral;<br>}</pre><br>Esto estiliza solo elementos con <kbd>class=\"badge\"</kbd>.",
"task": "Create a CSS rule using a class selector that targets elements with the class <kbd>highlight</kbd>. Give these elements a <kbd>yellow</kbd> background and <kbd>bold</kbd> text.", "task": "Estiliza el badge de notificación. Escribe una regla con <kbd>.badge</kbd> como selector y establece <kbd>background: tomato</kbd>.",
"previewHTML": "<h2>Using Class Selectors</h2>\n<p>This is a regular paragraph, but <span class=\"highlight\">this span has the highlight class</span> applied to it.</p>\n<p class=\"highlight\">This entire paragraph has the highlight class.</p>\n<ul>\n <li>Regular list item</li>\n <li class=\"highlight\">This list item is highlighted</li>\n</ul>", "previewHTML": "<header>\n <h1>Dashboard</h1>\n <span class=\"badge\">3</span>\n</header>\n<p>You have new notifications waiting.</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "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": "h2, p, li { padding: 5px; margin-bottom: 10px; }",
"codePrefix": "/* Create a class selector for elements with the 'highlight' class */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^\\.highlight\\s*{",
"message": "Start your rule with <kbd>.highlight { … }</kbd> to create a class selector",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "background-color:",
"message": "Include the <kbd>background-color:</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "yellow"
},
"message": "Set the background color to <kbd>yellow</kbd>"
},
{
"type": "contains",
"value": "font-weight:",
"message": "Include the <kbd>font-weight:</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "font-weight",
"expected": "bold"
},
"message": "Set the font-weight to <kbd>bold</kbd>"
},
{
"type": "regex",
"value": "\\.highlight\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "multiple-classes",
"title": "Multiple Classes",
"description": "HTML elements can have multiple classes applied simultaneously, allowing for composable and modular CSS designs. When an element has multiple classes, it will receive styles from all matching class selectors. This approach enables you to build a library of reusable CSS classes that can be combined in different ways. You can also target elements that have a specific combination of classes by chaining class selectors together without spaces (e.g., <kbd>.class1.class2</kbd>). When styling these elements, you might use properties like <kbd>border-color</kbd> to change the color of element borders, and <kbd>background-color</kbd> to set the background color of elements. This technique lets you create conditional styles that only apply when certain classes appear together.",
"task": "Complete the CSS rule that targets elements with both <kbd>card</kbd> and <kbd>featured</kbd> classes by chaining the selectors. Set the border-color to gold and the background-color to lemonchiffon to make featured cards stand out.",
"previewHTML": "<h2>Multiple Class Combinations</h2>\n<div class=\"card\">Regular Card</div>\n<div class=\"card featured\">Featured Card</div>\n<div class=\"featured\">Just Featured (not a card)</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } .card { border: 2px solid gray; padding: 15px; margin-bottom: 10px; border-radius: 5px; }",
"sandboxCSS": "", "sandboxCSS": "",
"codePrefix": "/* The .card class already has basic styling */\n/* Now target elements with BOTH classes: 'card' AND 'featured' */\n", "codePrefix": "",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": ".card.featured { border-color: gold; background-color: lemonchiffon }", "solution": ".badge {\n background: tomato;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^\\.card\\.featured\\s*{", "value": "\\.badge\\s*\\{",
"message": "Chain the selectors as <kbd>.card.featured</kbd> (no space between them)", "message": "Empieza con <kbd>.badge {</kbd> (¡no olvides el punto!)"
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "border-color:",
"message": "Include the <kbd>border-color</kbd> property"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "background", "expected": "tomato" },
"property": "border-color", "message": "Establece <kbd>background: tomato</kbd>"
"expected": "gold"
},
"message": "Set the border color to <kbd>gold</kbd>"
},
{
"type": "regex",
"value": "\\.card\\.featured\\s*{[^}]*;",
"message": "Make sure to end your CSS rule with a semicolon <kbd>;</kbd>"
},
{
"type": "contains",
"value": "background-color:",
"message": "Include the <kbd>background-color</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "lemonchiffon"
},
"message": "Set the background color to <kbd>lemonchiffon</kbd>"
},
{
"type": "regex",
"value": "\\.card\\.featured\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
} }
] ]
}, },
{ {
"id": "class-with-type", "id": "button-variants",
"title": "Combining Types", "title": "Variantes de botón",
"description": "You can combine type selectors with class selectors to target specific HTML elements that have a certain class. This creates a more specific selector that only matches when both conditions are true: the element is of the specified type AND it has the specified class. For example, <kbd>p.note</kbd> would select paragraph elements with the class <kbd>note</kbd>, but would not select divs or spans with that same class. You can style these combined selections using properties like <kbd>background-color</kbd> to set a colored background for your elements. This approach allows you to apply different styles to the same class when it appears on different element types.", "description": "Los elementos pueden tener múltiples clases. Cuando encadenas selectores de clase sin espacios, apuntas a elementos que tienen <em>todas</em> esas clases:<br><br><pre>.btn.primary {<br> background: steelblue;<br>}</pre><br>Esto apunta a elementos con <kbd>class=\"btn primary\"</kbd>, no solo <kbd>.btn</kbd> o solo <kbd>.primary</kbd>.",
"task": "Create a CSS rule that specifically targets <kbd>&lt;span&gt;</kbd> elements with the class <kbd>highlight</kbd>. Make those elements have an orange background, while other elements with the highlight class remain untouched.", "task": "Estiliza el botón primario. Escribe una regla con <kbd>.btn.primary</kbd> como selector y establece <kbd>background: steelblue</kbd>.",
"previewHTML": "<h2>Type and Class Combinations</h2>\n<p>This paragraph has a <span class=\"highlight\">highlighted span</span> that should have an orange background.</p>\n<p class=\"highlight\">This paragraph has the highlight class but should NOT have an orange background.</p>", "previewHTML": "<div class=\"actions\">\n <button class=\"btn\">Cancel</button>\n <button class=\"btn primary\">Save Changes</button>\n</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } .highlight { font-weight: bold; }", "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": "h2, p, span { padding: 5px; }",
"codePrefix": "/* The .highlight class already sets font-weight to bold */\n/* Now target ONLY span elements with the highlight class */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^span\\.highlight\\s*{",
"message": "Use <kbd>span.highlight</kbd> selector (no space between element and class)",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "background-color:",
"message": "Include the <kbd>background-color</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "orange"
},
"message": "Set the background color to <kbd>orange</kbd>"
},
{
"type": "regex",
"value": "span\\.highlight\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "id-selectors",
"title": "ID Selectors",
"description": "ID selectors target elements with a specific id attribute. They begin with a hash/pound sign (#) followed by the ID name. Unlike classes, IDs must be unique within a document—each ID value should be used only once per page. ID selectors have higher specificity than class or element selectors, meaning they override those selectors when conflicts arise. When styling with ID selectors, you can use properties like <kbd>color</kbd> to define text color, and <kbd>text-decoration</kbd> to control the appearance of text, such as adding underlines to elements. Because of their uniqueness requirement, IDs are best used for one-of-a-kind elements like page headers, main navigation, or specific unique components that appear only once on a page.",
"task": "Create a CSS rule with an ID selector that targets the element with the ID <kbd>main-title</kbd>. Set its color to purple and add an underline with <kbd>text-decoration: underline</kbd>.",
"previewHTML": "<h1 id=\"main-title\">Main Page Title</h1>\n<p>Regular paragraph content.</p>\n<h2>Secondary Heading</h2>\n<p id=\"intro\">Introduction paragraph (different ID).</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }",
"sandboxCSS": "h1, h2, p { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }",
"codePrefix": "/* Create an ID selector to target the element with id=\"main-title\" */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^#main-title\\s*{",
"message": "Start your rule with <kbd>#main-title</kbd> to create an ID selector",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "color:",
"message": "Include the <kbd>color</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "color",
"expected": "purple"
},
"message": "Set the color to <kbd>purple</kbd>"
},
{
"type": "contains",
"value": "text-decoration:",
"message": "Include the <kbd>text-decoration</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "text-decoration",
"expected": "underline"
},
"message": "Set the text-decoration to <kbd>underline</kbd>"
},
{
"type": "regex",
"value": "#main-title\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "id-with-type",
"title": "Type + ID",
"description": "Similar to how you can combine type and class selectors, you can also combine type selectors with ID selectors. For example, <kbd>h1#title</kbd> targets an h1 element with the ID 'title'. When using this combined approach, you can apply CSS properties like <kbd>font-style</kbd> to control the slant of the text, making it italic or normal. While this selector combination is more specific than using just the ID selector, it's often unnecessary since IDs should already be unique in a document. However, this technique can be useful for improving code readability or when you want to emphasize that a particular ID should only appear on a specific element type.",
"task": "Create a CSS rule that combines a type selector with an ID selector to target specifically a paragraph element with the ID <kbd>special</kbd>. Set its font style to italic.",
"previewHTML": "<h2 id=\"special\">Heading with ID \"special\" (should NOT be affected)</h2>\n<p id=\"special\">Paragraph with ID \"special\" (should become italic)</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }",
"sandboxCSS": "h2, p { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }",
"codePrefix": "/* Create a combined type+ID selector for a paragraph with id=\"special\" */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^p#special\\s*{",
"message": "Use <kbd>p#special</kbd> to target paragraphs with ID <kbd>special</kbd>",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "font-style:",
"message": "Include the <kbd>font-style</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "font-style",
"expected": "italic"
},
"message": "Set the font-style to <kbd>italic</kbd>"
},
{
"type": "regex",
"value": "p#special\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "selector-lists",
"title": "Selector Lists",
"description": "When multiple elements need the same styling, you can group them together using a selector list (also known as grouping selectors). Selector lists are created by separating individual selectors with commas. This approach reduces repetition in your CSS, making it more maintainable and efficient. For example, <kbd>h1, h2, h3 { color: blue; }</kbd> applies the same blue color to all three heading levels. When styling multiple selectors at once, you can apply properties like <kbd>background-color</kbd> to set the background, <kbd>border-left</kbd> to create a left border with a specific thickness, style, and color, and <kbd>padding-left</kbd> to create space between the content and the left border. Whitespace around commas is optional, and each selector in the list can be any valid selector type-elements, classes, IDs, or even more complex selectors.",
"task": "Create a selector list that applies the same styles to three different elements: paragraphs with class <kbd>note</kbd>, list items with class <kbd>important</kbd>, and the element with ID <kbd>summary</kbd>. Give them a <kbd>lightyellow</kbd> background, a <kbd>gold</kbd> left border, and some left <kbd>padding</kbd>.",
"previewHTML": "<p class=\"note\">This is a note paragraph.</p>\n<ul>\n <li>Regular list item</li>\n <li class=\"important\">Important list item</li>\n</ul>\n<div id=\"summary\">Summary section</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }",
"sandboxCSS": "p, li, div { padding: 8px; margin-bottom: 8px; border: 1px dashed gray; }",
"codePrefix": "/* Create a selector list to apply the same styles to multiple different elements */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"solution": "p.note,\nli.important,\n#summary {\n background-color: lightyellow;\n border-left: 3px solid gold;\n padding-left: 10px\n}",
"validations": [
{
"type": "contains",
"value": "p.note",
"message": "Include <kbd>p.note</kbd> in your selector list",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "li.important",
"message": "Include <kbd>li.important</kbd> in your selector list",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "#summary",
"message": "Include <kbd>#summary</kbd> in your selector list",
"options": {
"caseSensitive": true
}
},
{
"type": "regex",
"value": "(p\\.note|li\\.important|#summary)\\s*,\\s*(p\\.note|li\\.important|#summary)\\s*,\\s*(p\\.note|li\\.important|#summary)",
"message": "Create a comma-separated list with all three selectors",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "background-color:",
"message": "Include the <kbd>background-color</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "lightyellow"
},
"message": "Set the background color to <kbd>lightyellow</kbd>"
},
{
"type": "contains",
"value": "border-left:",
"message": "Include the <kbd>border-left</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "border-left",
"expected": "3px solid gold"
},
"message": "Use <kbd>border-left: 3px solid gold</kbd> to create a left border"
},
{
"type": "contains",
"value": "padding-left:",
"message": "Include the <kbd>padding-left</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "padding-left",
"expected": "10px"
},
"message": "Use <kbd>padding-left: 10px</kbd> to add left padding"
}
]
},
{
"id": "universal-selector",
"title": "Universal (*)",
"description": "The universal selector is denoted by an asterisk (*) and matches any element of any type. It selects everything in the document or, when combined with other selectors, everything within a specific context. For example, <kbd>* { margin: 0; }</kbd> removes margins from all elements, while <kbd>article *</kbd> selects all elements inside article elements. When using the universal selector in combination with other selectors, you can apply properties like <kbd>margin</kbd> to control the spacing around elements. The universal selector is powerful but should be used carefully due to its broad impact. It's commonly used in CSS resets, to override default browser styling, or to target all children of a particular element.",
"task": "Use the universal selector to remove margins from all elements inside the container div. Create a rule using <kbd>div.container *</kbd> as the selector and set <kbd>margin: 0</kbd>.",
"previewHTML": "<div class=\"container\">\n <h2>Inside Container</h2>\n <p>This paragraph is inside the container.</p>\n <ul>\n <li>List item inside container</li>\n </ul>\n</div>\n<p>This paragraph is outside the container and should not be affected.</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } div.container { border: 2px solid navy; padding: 15px; background-color: lavender; } h2, p, ul, li { margin: 15px 0; }",
"sandboxCSS": "", "sandboxCSS": "",
"codePrefix": "/* Use the universal selector to target all elements inside the container */\n", "codePrefix": "",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": ".btn.primary {\n background: steelblue;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^div\\.container\\s+\\*\\s*{", "value": "\\.btn\\.primary\\s*\\{",
"message": "Use <kbd>div.container *</kbd> selector (with a space between container and *)", "message": "Usa <kbd>.btn.primary {</kbd> (sin espacio entre clases)"
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "margin:",
"message": "Include the <kbd>margin</kbd> property"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "background", "expected": "steelblue" },
"property": "margin", "message": "Establece <kbd>background: steelblue</kbd>"
"expected": "0"
},
"message": "Set margin to <kbd>0</kbd>"
},
{
"type": "regex",
"value": "div\\.container\\s+\\*\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
} }
] ]
}, },
{ {
"id": "specificity-basics", "id": "specific-elements",
"title": "Specificity", "title": "Apuntando a elementos específicos",
"description": "CSS specificity determines which styles take precedence when multiple conflicting rules target the same element. Specificity follows a hierarchical system: inline styles have the highest specificity, followed by ID selectors, then class/attribute/pseudo-class selectors, and finally element/pseudo-element selectors. This can be conceptualized as a four-part score (inline, ID, class, element). When creating multiple rules that may target the same elements, you can use the <kbd>color</kbd> property to set text colors, and specificity will determine which color is actually applied. Understanding specificity is crucial for predictable styling and debugging CSS conflicts. When two selectors have equal specificity, the one that comes last in the stylesheet wins.", "description": "A veces quieres que una clase se vea diferente en diferentes elementos. Combina un selector de tipo con un selector de clase (sin espacio) para ser más específico:<br><br><pre>a.btn {<br> text-decoration: none;<br>}</pre><br>Esto estiliza solo elementos <kbd>&lt;a&gt;</kbd> con la clase <kbd>btn</kbd>, no elementos <kbd>&lt;button&gt;</kbd> con esa clase.",
"task": "Examine the existing CSS rules and add a new rule with higher specificity to override the text color of the paragraph. Create a rule using '.content p' as the selector and set color: green.", "task": "Quita el subrayado de los botones-enlace. Escribe una regla con <kbd>a.btn</kbd> como selector y establece <kbd>text-decoration: none</kbd>.",
"previewHTML": "<div class=\"content\">\n <p>What color will this paragraph be? Look at the CSS rules and their specificity.</p>\n</div>", "previewHTML": "<div class=\"actions\">\n <button class=\"btn\">Regular Button</button>\n <a href=\"#\" class=\"btn\">Link Button</a>\n</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "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": "p { border: 1px dashed gray; padding: 10px; }", "sandboxCSS": "",
"codePrefix": "/* These CSS rules target the same paragraph but have different specificity */\n\n/* Rule 1: Element selector (lowest specificity) */\np {\n color: red;\n}\n\n/* Rule 2: Descendant selector (higher specificity than just 'p') */\n", "codePrefix": "",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": "a.btn {\n text-decoration: none;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^\\.content\\s+p\\s*{", "value": "a\\.btn\\s*\\{",
"message": "Use <kbd>.content p</kbd> as your selector (note the space between)", "message": "Usa <kbd>a.btn {</kbd> (tipo + clase, sin espacio)"
"options": {
"caseSensitive": true
}
}, },
{ {
"type": "contains", "type": "property_value",
"value": "color:", "value": { "property": "text-decoration", "expected": "none" },
"message": "Include the <kbd>color</kbd> property" "message": "Establece <kbd>text-decoration: none</kbd>"
}
]
},
{
"id": "grouping-selectors",
"title": "Agrupando selectores",
"description": "Cuando múltiples elementos necesitan los mismos estilos, lístalos separados por comas. Esto mantiene tu CSS limpio y mantenible.<br><br><pre>h1, h2, h3 {<br> color: steelblue;<br>}</pre><br>Esto aplica el mismo color a los tres niveles de encabezado en una regla.",
"task": "Estiliza todos los encabezados consistentemente. Añade <kbd>color: steelblue</kbd> al selector agrupado <kbd>h1, h2, h3</kbd>.",
"previewHTML": "<article><h1>Main Title</h1><p>Introduction paragraph with some text.</p><h2>Section Heading</h2><p>More content here.</p><h3>Subsection</h3><p>Final paragraph.</p></article>",
"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": "Establece <kbd>color: steelblue</kbd>"
}
]
},
{
"id": "descendant-selectors",
"title": "Selectores descendientes",
"description": "Apunta a elementos dentro de otros elementos usando un espacio entre selectores. Este es uno de los patrones más útiles en CSS.<br><br><pre>.nav a {<br> color: white;<br>}</pre><br>Esto estiliza solo enlaces dentro de <kbd>.nav</kbd>, dejando otros enlaces sin cambios.",
"task": "Estiliza los enlaces de navegación diferente. Escribe una regla con <kbd>.nav a</kbd> como selector y establece <kbd>color: white</kbd>.",
"previewHTML": "<nav class=\"nav\"><a href=\"#\">Home</a><a href=\"#\">About</a><a href=\"#\">Contact</a></nav><p>Read more in our <a href=\"#\">documentation</a>.</p>",
"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": "Usa <kbd>.nav a {</kbd> (espacio entre .nav y a)"
}, },
{ {
"type": "contains", "type": "property_value",
"value": "green", "value": { "property": "color", "expected": "white" },
"message": "" "message": "Establece <kbd>color: white</kbd>"
}
]
},
{
"id": "nested-styling",
"title": "Estilos anidados",
"description": "Los selectores descendientes te permiten crear estilos contextuales. El mismo elemento puede verse diferente dependiendo de dónde aparezca.<br><br>Por ejemplo, los párrafos en una <kbd>.card</kbd> podrían ser más pequeños que los párrafos en un <kbd>article</kbd>.",
"task": "Haz los párrafos dentro de la tarjeta más pequeños. Escribe una regla con <kbd>.card p</kbd> como selector y establece <kbd>font-size: 0.9rem</kbd>.",
"previewHTML": "<article><h2>Article Title</h2><p>This is a regular article paragraph with normal-sized text for comfortable reading.</p><div class=\"card\"><strong>Quick Tip</strong><p>Card paragraphs should be slightly smaller to fit the compact design.</p></div><p>Back to regular article text here.</p></article>",
"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": "Usa <kbd>.card p {</kbd> (espacio entre .card y p)"
},
{
"type": "property_value",
"value": { "property": "font-size", "expected": "0.9rem" },
"message": "Establece <kbd>font-size: 0.9rem</kbd>"
} }
] ]
} }

View File

@@ -1,548 +1,257 @@
{ {
"$schema": "../../schemas/code-crispies-module-schema.json", "$schema": "../../schemas/code-crispies-module-schema.json",
"id": "css-basic-selectors", "id": "css-basic-selectors",
"title": "CSS Selectors", "title": "Podstawy CSS",
"description": "CSS selectors are the foundation of styling web pages, allowing you to target specific HTML elements for styling. This module introduces fundamental selector types including element type selectors, class selectors, ID selectors, and the universal selector.", "description": "Poznaj podstawowe elementy CSS: właściwości, wartości i selektory. Ten moduł uczy zasad składni, których przestrzega każda deklaracja CSS.",
"difficulty": "beginner", "difficulty": "beginner",
"lessons": [ "lessons": [
{ {
"id": "introduction-to-selectors", "id": "css-properties",
"title": "What's a Selector?", "title": "Właściwości CSS",
"description": "A CSS selector is the first part of a CSS rule that tells the browser which HTML elements should receive the styles defined in the declaration block. Selectors are essentially patterns that match against elements in your HTML document. Understanding selectors is fundamental because they determine which elements your CSS rules will affect. The element or elements targeted by a selector are referred to as the 'subject of the selector.' When writing a CSS rule, you first specify the selector, followed by curly braces that contain the style declarations.<br/>For example, to change the text color of elements, you can use the <kbd>color</kbd> property within your declaration block.<br><br><pre>/* Element selector */\np {\n color: orangered;\n /* │ └─── Indicates the value of the expression\n │ \n └─────────── Indicates the property of the expression */\n}</pre>", "description": "CSS stylizuje elementy za pomocą <strong>deklaracji</strong> - par właściwości i wartości. Każda deklaracja ma ten sam wzorzec:<br><br><pre>property: value;</pre><br><strong>Właściwość</strong> to co chcesz zmienić (jak <kbd>color</kbd> lub <kbd>background</kbd>). <strong>Wartość</strong> to na co to ustawiasz. Dwukropek je rozdziela, a średnik kończy linię.<br><br>Wartości występują w różnych typach:<br>• <strong>Słowa kluczowe:</strong> <kbd>red</kbd>, <kbd>bold</kbd>, <kbd>center</kbd><br>• <strong>Liczby z jednostkami:</strong> <kbd>16px</kbd>, <kbd>2rem</kbd>, <kbd>100%</kbd><br>• <strong>Kolory:</strong> <kbd>steelblue</kbd>, <kbd>#ff0000</kbd>",
"task": "Write a CSS rule using a type selector that targets all paragraph elements <kbd>p</kbd> in the document. Make the text blue by setting the <kbd>color</kbd> property to <kbd>blue</kbd>.", "task": "Uzupełnij deklarację dodając <kbd>color: coral;</kbd> aby zmienić kolor tekstu.",
"previewHTML": "<h1>Introduction to CSS Selectors</h1>\n<p>This paragraph should turn blue.</p>\n<div>This div element should remain unchanged.</div>\n<p>This second paragraph should also turn blue.</p>", "previewHTML": "<p class=\"text\">This text should turn coral.</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .text { font-size: 1.25rem; }",
"sandboxCSS": "h1, p, div { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }", "sandboxCSS": "",
"codePrefix": "/* Write a type selector to target all paragraph elements */\n", "codePrefix": ".text {\n ",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "\n}",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": "p { color: blue }", "solution": "color: coral;",
"validations": [ "validations": [
{ {
"type": "regex", "type": "property_value",
"value": "^p\\s*{", "value": { "property": "color", "expected": "coral" },
"message": "Start your rule with <kbd>p { … }</kbd> to select all paragraph elements", "message": "Dodaj <kbd>color: coral;</kbd>"
"options": { }
"caseSensitive": false ]
} },
}, {
"id": "multiple-properties",
"title": "Wiele właściwości",
"description": "Reguła może mieć wiele deklaracji. Każda idzie w osobnej linii i każda potrzebuje średnika na końcu:<br><br><pre>.box {<br> background: gold;<br> color: navy;<br> padding: 1rem;<br>}</pre><br>Kolejność zwykle nie ma znaczenia - CSS stosuje wszystkie. Przy konfliktach wygrywa ostatnia.",
"task": "Dodaj dwie deklaracje: <kbd>background: lavender;</kbd> i <kbd>padding: 1rem;</kbd>",
"previewHTML": "<div class=\"card\">A styled card with background and padding.</div>",
"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": "contains", "type": "property_value",
"value": "color:", "value": { "property": "background", "expected": "lavender" },
"message": "Include the <kbd>color:</kbd> property in your CSS rule" "message": "Dodaj <kbd>background: lavender;</kbd>"
},
{
"type": "contains",
"value": "blue",
"message": "Set the color value to <kbd>blue</kbd>"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "padding", "expected": "1rem" },
"property": "color", "message": "Dodaj <kbd>padding: 1rem;</kbd>"
"expected": "blue"
},
"message": "Use <kbd>color: blue</kbd> to set the text color"
},
{
"type": "regex",
"value": "p\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": false
}
} }
] ]
}, },
{ {
"id": "type-selectors", "id": "type-selectors",
"title": "Type Selectors", "title": "Selektory typu",
"description": "Type selectors (also called tag name selectors or element selectors) target HTML elements based on their tag name. For example, <kbd>p</kbd> selects all paragraph elements, <kbd>h1</kbd> selects all level-one headings, and <kbd>div</kbd> selects all division elements. Type selectors are the most fundamental way to select elements, applying styles consistently to all instances of a particular HTML element throughout your document. You can define a variety of CSS properties with type selectors, such as <kbd>color</kbd> for text color, <kbd>background-color</kbd> for the background, and <kbd>font-weight</kbd> for text emphasis. They provide a broad approach for styling your page and are often the starting point for more specific styling using other selector types.", "description": "<strong>Selektor</strong> mówi przeglądarce, które elementy stylizować. Najprostszym selektorem jest <strong>selektor typu</strong> — po prostu nazwa tagu HTML.<br><br><pre>p {<br> color: steelblue;<br>}</pre><br>Ta reguła celuje w każdy element <kbd>&lt;p&gt;</kbd> na stronie. Selektory typu świetnie nadają się do ustawiania podstawowych stylów.",
"task": "Write three separate CSS rules using type selectors to target specific HTML elements: make <kbd>h2</kbd> headings <kbd>purple</kbd>, give <kbd>span</kbd> elements a <kbd>yellow</kbd> background, and make <kbd>strong</kbd> elements <kbd>red</kbd>.", "task": "Ostyluj wszystkie akapity. Napisz regułę z <kbd>p</kbd> jako selektorem i ustaw <kbd>color: steelblue</kbd>.",
"previewHTML": "<h2>Type Selectors Example</h2>\n<p>Regular paragraph text <span>with a highlighted span</span> that should have a yellow background.</p>\n<p>Another paragraph with <strong>strong important text</strong> that should be red.</p>\n<h2>Another Heading</h2>", "previewHTML": "<article>\n <h2>Fresh Roasted Coffee</h2>\n <p>Our beans are sourced from small farms in Colombia and Ethiopia.</p>\n <p>Each batch is roasted weekly to ensure peak freshness.</p>\n</article>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } h2 { margin: 0 0 1rem; }",
"sandboxCSS": "h2, p, span, strong { padding: 3px; }", "sandboxCSS": "",
"codePrefix": "/* Write three separate type selectors below */\n\n", "codePrefix": "",
"initialCode": "/* 1. Make h2 headings purple */\n\n\n/* 2. Give span elements a yellow background */\n\n\n/* 3. Make strong elements red */\n", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": "/* 1. Make h2 headings purple */\nh2 {\n color: purple;\n}\n\n/* 2. Give span elements a yellow background */\nspan {\n background-color: yellow;\n}\n\n/* 3. Make strong elements red */\nstrong {\n color: red;\n}", "solution": "p {\n color: steelblue;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^h2\\s*{", "value": "p\\s*\\{",
"message": "Include an <kbd>h2 { … }</kbd> selector" "message": "Zacznij od <kbd>p {</kbd> aby wybrać akapity"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "color", "expected": "steelblue" },
"property": "color", "message": "Ustaw <kbd>color: steelblue</kbd>"
"expected": "purple" }
}, ]
"message": "Set the <kbd>color</kbd> property to <kbd>purple</kbd> for h2 elements" },
}, {
"id": "styling-links",
"title": "Stylizowanie linków",
"description": "Selektory typu działają dla każdego elementu HTML. Selektor <kbd>a</kbd> celuje we wszystkie linki na stronie.<br><br>Linki domyślnie mają niebieski kolor i podkreślenie. Możesz zmienić oba z CSS — użyj <kbd>color</kbd> dla tekstu i <kbd>text-decoration: none</kbd> aby usunąć podkreślenie.",
"task": "Ostyluj linki nawigacji. Napisz regułę z <kbd>a</kbd> jako selektorem i ustaw <kbd>color: coral</kbd>.",
"previewHTML": "<nav>\n <a href=\"#\">Home</a>\n <a href=\"#\">Menu</a>\n <a href=\"#\">About</a>\n <a href=\"#\">Contact</a>\n</nav>",
"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", "type": "regex",
"value": "h2\\s*{[^}]*}", "value": "a\\s*\\{",
"message": "Make sure to close your h2 rule with a closing brace <kbd>}</kbd>" "message": "Zacznij od <kbd>a {</kbd> aby wybrać linki"
},
{
"type": "regex",
"value": "^span\\s*{",
"message": "Include a <kbd>span { … }</kbd> selector"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "color", "expected": "coral" },
"property": "background-color", "message": "Ustaw <kbd>color: coral</kbd>"
"expected": "yellow"
},
"message": "Set a <kbd>background-color: yellow</kbd> for span elements"
},
{
"type": "regex",
"value": "span\\s*{[^}]*}",
"message": "Make sure to close your span rule with a closing brace <kbd>}</kbd>"
},
{
"type": "regex",
"value": "^strong\\s*{",
"message": "Include a <kbd>strong { … }</kbd> selector"
},
{
"type": "regex",
"value": "strong\\s*{\\s*color:\\s*red;[^}]*}",
"message": "Set the <kbd>color: red</kbd> for strong elements"
} }
] ]
}, },
{ {
"id": "class-selectors", "id": "class-selectors",
"title": "Class Selectors", "title": "Selektory klas",
"description": "Class selectors target elements with a specific class attribute value. They begin with a dot (.) followed by the class name. Classes are powerful because they allow you to apply the same styles to multiple elements regardless of their type. An HTML element can have multiple classes (separated by spaces in the class attribute), and a class can be applied to any number of elements. When using class selectors, you can apply properties like <kbd>background-color</kbd> to set the background color of elements, and <kbd>font-weight</kbd> to control text thickness, making text bold or normal. This flexibility makes class selectors one of the most commonly used methods for applying styles in CSS, allowing for modular and reusable styling across your website.", "description": "Selektory typu stylizują <em>wszystkie</em> elementy danego typu. Ale co jeśli chcesz ostylować tylko niektóre z nich?<br><br><strong>Selektory klas</strong> celują w elementy z określonym atrybutem <kbd>class</kbd>. Zaczynają się od kropki:<br><br><pre>.badge {<br> background: coral;<br>}</pre><br>To stylizuje tylko elementy z <kbd>class=\"badge\"</kbd>.",
"task": "Create a CSS rule using a class selector that targets elements with the class <kbd>highlight</kbd>. Give these elements a <kbd>yellow</kbd> background and <kbd>bold</kbd> text.", "task": "Ostyluj badge powiadomień. Napisz regułę z <kbd>.badge</kbd> jako selektorem i ustaw <kbd>background: tomato</kbd>.",
"previewHTML": "<h2>Using Class Selectors</h2>\n<p>This is a regular paragraph, but <span class=\"highlight\">this span has the highlight class</span> applied to it.</p>\n<p class=\"highlight\">This entire paragraph has the highlight class.</p>\n<ul>\n <li>Regular list item</li>\n <li class=\"highlight\">This list item is highlighted</li>\n</ul>", "previewHTML": "<header>\n <h1>Dashboard</h1>\n <span class=\"badge\">3</span>\n</header>\n<p>You have new notifications waiting.</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "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": "h2, p, li { padding: 5px; margin-bottom: 10px; }",
"codePrefix": "/* Create a class selector for elements with the 'highlight' class */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^\\.highlight\\s*{",
"message": "Start your rule with <kbd>.highlight { … }</kbd> to create a class selector",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "background-color:",
"message": "Include the <kbd>background-color:</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "yellow"
},
"message": "Set the background color to <kbd>yellow</kbd>"
},
{
"type": "contains",
"value": "font-weight:",
"message": "Include the <kbd>font-weight:</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "font-weight",
"expected": "bold"
},
"message": "Set the font-weight to <kbd>bold</kbd>"
},
{
"type": "regex",
"value": "\\.highlight\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "multiple-classes",
"title": "Multiple Classes",
"description": "HTML elements can have multiple classes applied simultaneously, allowing for composable and modular CSS designs. When an element has multiple classes, it will receive styles from all matching class selectors. This approach enables you to build a library of reusable CSS classes that can be combined in different ways. You can also target elements that have a specific combination of classes by chaining class selectors together without spaces (e.g., <kbd>.class1.class2</kbd>). When styling these elements, you might use properties like <kbd>border-color</kbd> to change the color of element borders, and <kbd>background-color</kbd> to set the background color of elements. This technique lets you create conditional styles that only apply when certain classes appear together.",
"task": "Complete the CSS rule that targets elements with both <kbd>card</kbd> and <kbd>featured</kbd> classes by chaining the selectors. Set the border-color to gold and the background-color to lemonchiffon to make featured cards stand out.",
"previewHTML": "<h2>Multiple Class Combinations</h2>\n<div class=\"card\">Regular Card</div>\n<div class=\"card featured\">Featured Card</div>\n<div class=\"featured\">Just Featured (not a card)</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } .card { border: 2px solid gray; padding: 15px; margin-bottom: 10px; border-radius: 5px; }",
"sandboxCSS": "", "sandboxCSS": "",
"codePrefix": "/* The .card class already has basic styling */\n/* Now target elements with BOTH classes: 'card' AND 'featured' */\n", "codePrefix": "",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": ".card.featured { border-color: gold; background-color: lemonchiffon }", "solution": ".badge {\n background: tomato;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^\\.card\\.featured\\s*{", "value": "\\.badge\\s*\\{",
"message": "Chain the selectors as <kbd>.card.featured</kbd> (no space between them)", "message": "Zacznij od <kbd>.badge {</kbd> (nie zapomnij o kropce!)"
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "border-color:",
"message": "Include the <kbd>border-color</kbd> property"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "background", "expected": "tomato" },
"property": "border-color", "message": "Ustaw <kbd>background: tomato</kbd>"
"expected": "gold"
},
"message": "Set the border color to <kbd>gold</kbd>"
},
{
"type": "regex",
"value": "\\.card\\.featured\\s*{[^}]*;",
"message": "Make sure to end your CSS rule with a semicolon <kbd>;</kbd>"
},
{
"type": "contains",
"value": "background-color:",
"message": "Include the <kbd>background-color</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "lemonchiffon"
},
"message": "Set the background color to <kbd>lemonchiffon</kbd>"
},
{
"type": "regex",
"value": "\\.card\\.featured\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
} }
] ]
}, },
{ {
"id": "class-with-type", "id": "button-variants",
"title": "Combining Types", "title": "Warianty przycisków",
"description": "You can combine type selectors with class selectors to target specific HTML elements that have a certain class. This creates a more specific selector that only matches when both conditions are true: the element is of the specified type AND it has the specified class. For example, <kbd>p.note</kbd> would select paragraph elements with the class <kbd>note</kbd>, but would not select divs or spans with that same class. You can style these combined selections using properties like <kbd>background-color</kbd> to set a colored background for your elements. This approach allows you to apply different styles to the same class when it appears on different element types.", "description": "Elementy mogą mieć wiele klas. Gdy łączysz selektory klas bez spacji, celujesz w elementy które mają <em>wszystkie</em> te klasy:<br><br><pre>.btn.primary {<br> background: steelblue;<br>}</pre><br>To celuje w elementy z <kbd>class=\"btn primary\"</kbd>, nie tylko <kbd>.btn</kbd> lub tylko <kbd>.primary</kbd>.",
"task": "Create a CSS rule that specifically targets <kbd>&lt;span&gt;</kbd> elements with the class <kbd>highlight</kbd>. Make those elements have an orange background, while other elements with the highlight class remain untouched.", "task": "Ostyluj główny przycisk. Napisz regułę z <kbd>.btn.primary</kbd> jako selektorem i ustaw <kbd>background: steelblue</kbd>.",
"previewHTML": "<h2>Type and Class Combinations</h2>\n<p>This paragraph has a <span class=\"highlight\">highlighted span</span> that should have an orange background.</p>\n<p class=\"highlight\">This paragraph has the highlight class but should NOT have an orange background.</p>", "previewHTML": "<div class=\"actions\">\n <button class=\"btn\">Cancel</button>\n <button class=\"btn primary\">Save Changes</button>\n</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } .highlight { font-weight: bold; }", "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": "h2, p, span { padding: 5px; }",
"codePrefix": "/* The .highlight class already sets font-weight to bold */\n/* Now target ONLY span elements with the highlight class */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^span\\.highlight\\s*{",
"message": "Use <kbd>span.highlight</kbd> selector (no space between element and class)",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "background-color:",
"message": "Include the <kbd>background-color</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "orange"
},
"message": "Set the background color to <kbd>orange</kbd>"
},
{
"type": "regex",
"value": "span\\.highlight\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "id-selectors",
"title": "ID Selectors",
"description": "ID selectors target elements with a specific id attribute. They begin with a hash/pound sign (#) followed by the ID name. Unlike classes, IDs must be unique within a document—each ID value should be used only once per page. ID selectors have higher specificity than class or element selectors, meaning they override those selectors when conflicts arise. When styling with ID selectors, you can use properties like <kbd>color</kbd> to define text color, and <kbd>text-decoration</kbd> to control the appearance of text, such as adding underlines to elements. Because of their uniqueness requirement, IDs are best used for one-of-a-kind elements like page headers, main navigation, or specific unique components that appear only once on a page.",
"task": "Create a CSS rule with an ID selector that targets the element with the ID <kbd>main-title</kbd>. Set its color to purple and add an underline with <kbd>text-decoration: underline</kbd>.",
"previewHTML": "<h1 id=\"main-title\">Main Page Title</h1>\n<p>Regular paragraph content.</p>\n<h2>Secondary Heading</h2>\n<p id=\"intro\">Introduction paragraph (different ID).</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }",
"sandboxCSS": "h1, h2, p { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }",
"codePrefix": "/* Create an ID selector to target the element with id=\"main-title\" */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^#main-title\\s*{",
"message": "Start your rule with <kbd>#main-title</kbd> to create an ID selector",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "color:",
"message": "Include the <kbd>color</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "color",
"expected": "purple"
},
"message": "Set the color to <kbd>purple</kbd>"
},
{
"type": "contains",
"value": "text-decoration:",
"message": "Include the <kbd>text-decoration</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "text-decoration",
"expected": "underline"
},
"message": "Set the text-decoration to <kbd>underline</kbd>"
},
{
"type": "regex",
"value": "#main-title\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "id-with-type",
"title": "Type + ID",
"description": "Similar to how you can combine type and class selectors, you can also combine type selectors with ID selectors. For example, <kbd>h1#title</kbd> targets an h1 element with the ID 'title'. When using this combined approach, you can apply CSS properties like <kbd>font-style</kbd> to control the slant of the text, making it italic or normal. While this selector combination is more specific than using just the ID selector, it's often unnecessary since IDs should already be unique in a document. However, this technique can be useful for improving code readability or when you want to emphasize that a particular ID should only appear on a specific element type.",
"task": "Create a CSS rule that combines a type selector with an ID selector to target specifically a paragraph element with the ID <kbd>special</kbd>. Set its font style to italic.",
"previewHTML": "<h2 id=\"special\">Heading with ID \"special\" (should NOT be affected)</h2>\n<p id=\"special\">Paragraph with ID \"special\" (should become italic)</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }",
"sandboxCSS": "h2, p { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }",
"codePrefix": "/* Create a combined type+ID selector for a paragraph with id=\"special\" */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^p#special\\s*{",
"message": "Use <kbd>p#special</kbd> to target paragraphs with ID <kbd>special</kbd>",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "font-style:",
"message": "Include the <kbd>font-style</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "font-style",
"expected": "italic"
},
"message": "Set the font-style to <kbd>italic</kbd>"
},
{
"type": "regex",
"value": "p#special\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "selector-lists",
"title": "Selector Lists",
"description": "When multiple elements need the same styling, you can group them together using a selector list (also known as grouping selectors). Selector lists are created by separating individual selectors with commas. This approach reduces repetition in your CSS, making it more maintainable and efficient. For example, <kbd>h1, h2, h3 { color: blue; }</kbd> applies the same blue color to all three heading levels. When styling multiple selectors at once, you can apply properties like <kbd>background-color</kbd> to set the background, <kbd>border-left</kbd> to create a left border with a specific thickness, style, and color, and <kbd>padding-left</kbd> to create space between the content and the left border. Whitespace around commas is optional, and each selector in the list can be any valid selector type-elements, classes, IDs, or even more complex selectors.",
"task": "Create a selector list that applies the same styles to three different elements: paragraphs with class <kbd>note</kbd>, list items with class <kbd>important</kbd>, and the element with ID <kbd>summary</kbd>. Give them a <kbd>lightyellow</kbd> background, a <kbd>gold</kbd> left border, and some left <kbd>padding</kbd>.",
"previewHTML": "<p class=\"note\">This is a note paragraph.</p>\n<ul>\n <li>Regular list item</li>\n <li class=\"important\">Important list item</li>\n</ul>\n<div id=\"summary\">Summary section</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }",
"sandboxCSS": "p, li, div { padding: 8px; margin-bottom: 8px; border: 1px dashed gray; }",
"codePrefix": "/* Create a selector list to apply the same styles to multiple different elements */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"solution": "p.note,\nli.important,\n#summary {\n background-color: lightyellow;\n border-left: 3px solid gold;\n padding-left: 10px\n}",
"validations": [
{
"type": "contains",
"value": "p.note",
"message": "Include <kbd>p.note</kbd> in your selector list",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "li.important",
"message": "Include <kbd>li.important</kbd> in your selector list",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "#summary",
"message": "Include <kbd>#summary</kbd> in your selector list",
"options": {
"caseSensitive": true
}
},
{
"type": "regex",
"value": "(p\\.note|li\\.important|#summary)\\s*,\\s*(p\\.note|li\\.important|#summary)\\s*,\\s*(p\\.note|li\\.important|#summary)",
"message": "Create a comma-separated list with all three selectors",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "background-color:",
"message": "Include the <kbd>background-color</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "lightyellow"
},
"message": "Set the background color to <kbd>lightyellow</kbd>"
},
{
"type": "contains",
"value": "border-left:",
"message": "Include the <kbd>border-left</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "border-left",
"expected": "3px solid gold"
},
"message": "Use <kbd>border-left: 3px solid gold</kbd> to create a left border"
},
{
"type": "contains",
"value": "padding-left:",
"message": "Include the <kbd>padding-left</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "padding-left",
"expected": "10px"
},
"message": "Use <kbd>padding-left: 10px</kbd> to add left padding"
}
]
},
{
"id": "universal-selector",
"title": "Universal (*)",
"description": "The universal selector is denoted by an asterisk (*) and matches any element of any type. It selects everything in the document or, when combined with other selectors, everything within a specific context. For example, <kbd>* { margin: 0; }</kbd> removes margins from all elements, while <kbd>article *</kbd> selects all elements inside article elements. When using the universal selector in combination with other selectors, you can apply properties like <kbd>margin</kbd> to control the spacing around elements. The universal selector is powerful but should be used carefully due to its broad impact. It's commonly used in CSS resets, to override default browser styling, or to target all children of a particular element.",
"task": "Use the universal selector to remove margins from all elements inside the container div. Create a rule using <kbd>div.container *</kbd> as the selector and set <kbd>margin: 0</kbd>.",
"previewHTML": "<div class=\"container\">\n <h2>Inside Container</h2>\n <p>This paragraph is inside the container.</p>\n <ul>\n <li>List item inside container</li>\n </ul>\n</div>\n<p>This paragraph is outside the container and should not be affected.</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } div.container { border: 2px solid navy; padding: 15px; background-color: lavender; } h2, p, ul, li { margin: 15px 0; }",
"sandboxCSS": "", "sandboxCSS": "",
"codePrefix": "/* Use the universal selector to target all elements inside the container */\n", "codePrefix": "",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": ".btn.primary {\n background: steelblue;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^div\\.container\\s+\\*\\s*{", "value": "\\.btn\\.primary\\s*\\{",
"message": "Use <kbd>div.container *</kbd> selector (with a space between container and *)", "message": "Użyj <kbd>.btn.primary {</kbd> (bez spacji między klasami)"
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "margin:",
"message": "Include the <kbd>margin</kbd> property"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "background", "expected": "steelblue" },
"property": "margin", "message": "Ustaw <kbd>background: steelblue</kbd>"
"expected": "0"
},
"message": "Set margin to <kbd>0</kbd>"
},
{
"type": "regex",
"value": "div\\.container\\s+\\*\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
} }
] ]
}, },
{ {
"id": "specificity-basics", "id": "specific-elements",
"title": "Specificity", "title": "Celowanie w konkretne elementy",
"description": "CSS specificity determines which styles take precedence when multiple conflicting rules target the same element. Specificity follows a hierarchical system: inline styles have the highest specificity, followed by ID selectors, then class/attribute/pseudo-class selectors, and finally element/pseudo-element selectors. This can be conceptualized as a four-part score (inline, ID, class, element). When creating multiple rules that may target the same elements, you can use the <kbd>color</kbd> property to set text colors, and specificity will determine which color is actually applied. Understanding specificity is crucial for predictable styling and debugging CSS conflicts. When two selectors have equal specificity, the one that comes last in the stylesheet wins.", "description": "Czasem chcesz, żeby klasa wyglądała inaczej na różnych elementach. Połącz selektor typu z selektorem klasy (bez spacji) aby być bardziej specyficznym:<br><br><pre>a.btn {<br> text-decoration: none;<br>}</pre><br>To stylizuje tylko elementy <kbd>&lt;a&gt;</kbd> z klasą <kbd>btn</kbd>, nie elementy <kbd>&lt;button&gt;</kbd> z tą klasą.",
"task": "Examine the existing CSS rules and add a new rule with higher specificity to override the text color of the paragraph. Create a rule using '.content p' as the selector and set color: green.", "task": "Usuń podkreślenie z przycisków-linków. Napisz regułę z <kbd>a.btn</kbd> jako selektorem i ustaw <kbd>text-decoration: none</kbd>.",
"previewHTML": "<div class=\"content\">\n <p>What color will this paragraph be? Look at the CSS rules and their specificity.</p>\n</div>", "previewHTML": "<div class=\"actions\">\n <button class=\"btn\">Regular Button</button>\n <a href=\"#\" class=\"btn\">Link Button</a>\n</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "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": "p { border: 1px dashed gray; padding: 10px; }", "sandboxCSS": "",
"codePrefix": "/* These CSS rules target the same paragraph but have different specificity */\n\n/* Rule 1: Element selector (lowest specificity) */\np {\n color: red;\n}\n\n/* Rule 2: Descendant selector (higher specificity than just 'p') */\n", "codePrefix": "",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": "a.btn {\n text-decoration: none;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^\\.content\\s+p\\s*{", "value": "a\\.btn\\s*\\{",
"message": "Use <kbd>.content p</kbd> as your selector (note the space between)", "message": "Użyj <kbd>a.btn {</kbd> (typ + klasa, bez spacji)"
"options": {
"caseSensitive": true
}
}, },
{ {
"type": "contains", "type": "property_value",
"value": "color:", "value": { "property": "text-decoration", "expected": "none" },
"message": "Include the <kbd>color</kbd> property" "message": "Ustaw <kbd>text-decoration: none</kbd>"
}
]
},
{
"id": "grouping-selectors",
"title": "Grupowanie selektorów",
"description": "Gdy wiele elementów potrzebuje tych samych stylów, wymień je oddzielone przecinkami. To utrzymuje CSS czystym i łatwym w utrzymaniu.<br><br><pre>h1, h2, h3 {<br> color: steelblue;<br>}</pre><br>To stosuje ten sam kolor do wszystkich trzech poziomów nagłówków w jednej regule.",
"task": "Ostyluj wszystkie nagłówki jednolicie. Dodaj <kbd>color: steelblue</kbd> do zgrupowanego selektora <kbd>h1, h2, h3</kbd>.",
"previewHTML": "<article><h1>Main Title</h1><p>Introduction paragraph with some text.</p><h2>Section Heading</h2><p>More content here.</p><h3>Subsection</h3><p>Final paragraph.</p></article>",
"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": "Ustaw <kbd>color: steelblue</kbd>"
}
]
},
{
"id": "descendant-selectors",
"title": "Selektory potomków",
"description": "Celuj w elementy wewnątrz innych elementów używając spacji między selektorami. To jeden z najbardziej użytecznych wzorców w CSS.<br><br><pre>.nav a {<br> color: white;<br>}</pre><br>To stylizuje tylko linki wewnątrz <kbd>.nav</kbd>, pozostawiając inne linki bez zmian.",
"task": "Ostyluj linki nawigacji inaczej. Napisz regułę z <kbd>.nav a</kbd> jako selektorem i ustaw <kbd>color: white</kbd>.",
"previewHTML": "<nav class=\"nav\"><a href=\"#\">Home</a><a href=\"#\">About</a><a href=\"#\">Contact</a></nav><p>Read more in our <a href=\"#\">documentation</a>.</p>",
"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": "Użyj <kbd>.nav a {</kbd> (spacja między .nav a a)"
}, },
{ {
"type": "contains", "type": "property_value",
"value": "green", "value": { "property": "color", "expected": "white" },
"message": "" "message": "Ustaw <kbd>color: white</kbd>"
}
]
},
{
"id": "nested-styling",
"title": "Zagnieżdżone style",
"description": "Selektory potomków pozwalają tworzyć style kontekstowe. Ten sam element może wyglądać inaczej w zależności od tego gdzie się znajduje.<br><br>Na przykład, akapity w <kbd>.card</kbd> mogą być mniejsze niż akapity w <kbd>article</kbd>.",
"task": "Zmniejsz akapity wewnątrz karty. Napisz regułę z <kbd>.card p</kbd> jako selektorem i ustaw <kbd>font-size: 0.9rem</kbd>.",
"previewHTML": "<article><h2>Article Title</h2><p>This is a regular article paragraph with normal-sized text for comfortable reading.</p><div class=\"card\"><strong>Quick Tip</strong><p>Card paragraphs should be slightly smaller to fit the compact design.</p></div><p>Back to regular article text here.</p></article>",
"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": "Użyj <kbd>.card p {</kbd> (spacja między .card a p)"
},
{
"type": "property_value",
"value": { "property": "font-size", "expected": "0.9rem" },
"message": "Ustaw <kbd>font-size: 0.9rem</kbd>"
} }
] ]
} }

View File

@@ -1,548 +1,257 @@
{ {
"$schema": "../../schemas/code-crispies-module-schema.json", "$schema": "../../schemas/code-crispies-module-schema.json",
"id": "css-basic-selectors", "id": "css-basic-selectors",
"title": "CSS Selectors", "title": "Основи CSS",
"description": "CSS selectors are the foundation of styling web pages, allowing you to target specific HTML elements for styling. This module introduces fundamental selector types including element type selectors, class selectors, ID selectors, and the universal selector.", "description": "Вивчіть основні будівельні блоки CSS: властивості, значення та селектори. Цей модуль навчає правилам синтаксису, яких дотримується кожна декларація CSS.",
"difficulty": "beginner", "difficulty": "beginner",
"lessons": [ "lessons": [
{ {
"id": "introduction-to-selectors", "id": "css-properties",
"title": "What's a Selector?", "title": "Властивості CSS",
"description": "A CSS selector is the first part of a CSS rule that tells the browser which HTML elements should receive the styles defined in the declaration block. Selectors are essentially patterns that match against elements in your HTML document. Understanding selectors is fundamental because they determine which elements your CSS rules will affect. The element or elements targeted by a selector are referred to as the 'subject of the selector.' When writing a CSS rule, you first specify the selector, followed by curly braces that contain the style declarations.<br/>For example, to change the text color of elements, you can use the <kbd>color</kbd> property within your declaration block.<br><br><pre>/* Element selector */\np {\n color: orangered;\n /* │ └─── Indicates the value of the expression\n │ \n └─────────── Indicates the property of the expression */\n}</pre>", "description": "CSS стилізує елементи за допомогою <strong>декларацій</strong> - пар властивостей і значень. Кожна декларація має той самий шаблон:<br><br><pre>property: value;</pre><br><strong>Властивість</strong> - це те, що ви хочете змінити (як <kbd>color</kbd> або <kbd>background</kbd>). <strong>Значення</strong> - це те, на що ви це встановлюєте. Двокрапка їх розділяє, а крапка з комою закінчує рядок.<br><br>Значення бувають різних типів:<br>• <strong>Ключові слова:</strong> <kbd>red</kbd>, <kbd>bold</kbd>, <kbd>center</kbd><br>• <strong>Числа з одиницями:</strong> <kbd>16px</kbd>, <kbd>2rem</kbd>, <kbd>100%</kbd><br>• <strong>Кольори:</strong> <kbd>steelblue</kbd>, <kbd>#ff0000</kbd>",
"task": "Write a CSS rule using a type selector that targets all paragraph elements <kbd>p</kbd> in the document. Make the text blue by setting the <kbd>color</kbd> property to <kbd>blue</kbd>.", "task": "Завершіть декларацію, додавши <kbd>color: coral;</kbd> щоб змінити колір тексту.",
"previewHTML": "<h1>Introduction to CSS Selectors</h1>\n<p>This paragraph should turn blue.</p>\n<div>This div element should remain unchanged.</div>\n<p>This second paragraph should also turn blue.</p>", "previewHTML": "<p class=\"text\">This text should turn coral.</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .text { font-size: 1.25rem; }",
"sandboxCSS": "h1, p, div { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }", "sandboxCSS": "",
"codePrefix": "/* Write a type selector to target all paragraph elements */\n", "codePrefix": ".text {\n ",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "\n}",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": "p { color: blue }", "solution": "color: coral;",
"validations": [ "validations": [
{ {
"type": "regex", "type": "property_value",
"value": "^p\\s*{", "value": { "property": "color", "expected": "coral" },
"message": "Start your rule with <kbd>p { … }</kbd> to select all paragraph elements", "message": "Додайте <kbd>color: coral;</kbd>"
"options": { }
"caseSensitive": false ]
} },
}, {
"id": "multiple-properties",
"title": "Кілька властивостей",
"description": "Правило може мати кілька декларацій. Кожна йде в окремому рядку, і кожна потребує крапки з комою в кінці:<br><br><pre>.box {<br> background: gold;<br> color: navy;<br> padding: 1rem;<br>}</pre><br>Порядок зазвичай не має значення - CSS застосовує всі. При конфліктах перемагає остання.",
"task": "Додайте дві декларації: <kbd>background: lavender;</kbd> та <kbd>padding: 1rem;</kbd>",
"previewHTML": "<div class=\"card\">A styled card with background and padding.</div>",
"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": "contains", "type": "property_value",
"value": "color:", "value": { "property": "background", "expected": "lavender" },
"message": "Include the <kbd>color:</kbd> property in your CSS rule" "message": "Додайте <kbd>background: lavender;</kbd>"
},
{
"type": "contains",
"value": "blue",
"message": "Set the color value to <kbd>blue</kbd>"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "padding", "expected": "1rem" },
"property": "color", "message": "Додайте <kbd>padding: 1rem;</kbd>"
"expected": "blue"
},
"message": "Use <kbd>color: blue</kbd> to set the text color"
},
{
"type": "regex",
"value": "p\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": false
}
} }
] ]
}, },
{ {
"id": "type-selectors", "id": "type-selectors",
"title": "Type Selectors", "title": "Селектори типу",
"description": "Type selectors (also called tag name selectors or element selectors) target HTML elements based on their tag name. For example, <kbd>p</kbd> selects all paragraph elements, <kbd>h1</kbd> selects all level-one headings, and <kbd>div</kbd> selects all division elements. Type selectors are the most fundamental way to select elements, applying styles consistently to all instances of a particular HTML element throughout your document. You can define a variety of CSS properties with type selectors, such as <kbd>color</kbd> for text color, <kbd>background-color</kbd> for the background, and <kbd>font-weight</kbd> for text emphasis. They provide a broad approach for styling your page and are often the starting point for more specific styling using other selector types.", "description": "<strong>Селектор</strong> говорить браузеру, які елементи стилізувати. Найпростіший селектор - це <strong>селектор типу</strong> — просто назва HTML-тегу.<br><br><pre>p {<br> color: steelblue;<br>}</pre><br>Це правило націлюється на кожен елемент <kbd>&lt;p&gt;</kbd> на сторінці. Селектори типу чудово підходять для встановлення базових стилів.",
"task": "Write three separate CSS rules using type selectors to target specific HTML elements: make <kbd>h2</kbd> headings <kbd>purple</kbd>, give <kbd>span</kbd> elements a <kbd>yellow</kbd> background, and make <kbd>strong</kbd> elements <kbd>red</kbd>.", "task": "Стилізуйте всі абзаци. Напишіть правило з <kbd>p</kbd> як селектором і встановіть <kbd>color: steelblue</kbd>.",
"previewHTML": "<h2>Type Selectors Example</h2>\n<p>Regular paragraph text <span>with a highlighted span</span> that should have a yellow background.</p>\n<p>Another paragraph with <strong>strong important text</strong> that should be red.</p>\n<h2>Another Heading</h2>", "previewHTML": "<article>\n <h2>Fresh Roasted Coffee</h2>\n <p>Our beans are sourced from small farms in Colombia and Ethiopia.</p>\n <p>Each batch is roasted weekly to ensure peak freshness.</p>\n</article>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } h2 { margin: 0 0 1rem; }",
"sandboxCSS": "h2, p, span, strong { padding: 3px; }", "sandboxCSS": "",
"codePrefix": "/* Write three separate type selectors below */\n\n", "codePrefix": "",
"initialCode": "/* 1. Make h2 headings purple */\n\n\n/* 2. Give span elements a yellow background */\n\n\n/* 3. Make strong elements red */\n", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": "/* 1. Make h2 headings purple */\nh2 {\n color: purple;\n}\n\n/* 2. Give span elements a yellow background */\nspan {\n background-color: yellow;\n}\n\n/* 3. Make strong elements red */\nstrong {\n color: red;\n}", "solution": "p {\n color: steelblue;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^h2\\s*{", "value": "p\\s*\\{",
"message": "Include an <kbd>h2 { … }</kbd> selector" "message": "Почніть з <kbd>p {</kbd> щоб вибрати абзаци"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "color", "expected": "steelblue" },
"property": "color", "message": "Встановіть <kbd>color: steelblue</kbd>"
"expected": "purple" }
}, ]
"message": "Set the <kbd>color</kbd> property to <kbd>purple</kbd> for h2 elements" },
}, {
"id": "styling-links",
"title": "Стилізація посилань",
"description": "Селектори типу працюють для будь-якого HTML-елемента. Селектор <kbd>a</kbd> націлюється на всі посилання на сторінці.<br><br>Посилання мають синій колір і підкреслення за замовчуванням. Ви можете змінити обидва з CSS — використовуйте <kbd>color</kbd> для тексту і <kbd>text-decoration: none</kbd> щоб прибрати підкреслення.",
"task": "Стилізуйте навігаційні посилання. Напишіть правило з <kbd>a</kbd> як селектором і встановіть <kbd>color: coral</kbd>.",
"previewHTML": "<nav>\n <a href=\"#\">Home</a>\n <a href=\"#\">Menu</a>\n <a href=\"#\">About</a>\n <a href=\"#\">Contact</a>\n</nav>",
"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", "type": "regex",
"value": "h2\\s*{[^}]*}", "value": "a\\s*\\{",
"message": "Make sure to close your h2 rule with a closing brace <kbd>}</kbd>" "message": "Почніть з <kbd>a {</kbd> щоб вибрати посилання"
},
{
"type": "regex",
"value": "^span\\s*{",
"message": "Include a <kbd>span { … }</kbd> selector"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "color", "expected": "coral" },
"property": "background-color", "message": "Встановіть <kbd>color: coral</kbd>"
"expected": "yellow"
},
"message": "Set a <kbd>background-color: yellow</kbd> for span elements"
},
{
"type": "regex",
"value": "span\\s*{[^}]*}",
"message": "Make sure to close your span rule with a closing brace <kbd>}</kbd>"
},
{
"type": "regex",
"value": "^strong\\s*{",
"message": "Include a <kbd>strong { … }</kbd> selector"
},
{
"type": "regex",
"value": "strong\\s*{\\s*color:\\s*red;[^}]*}",
"message": "Set the <kbd>color: red</kbd> for strong elements"
} }
] ]
}, },
{ {
"id": "class-selectors", "id": "class-selectors",
"title": "Class Selectors", "title": "Селектори класів",
"description": "Class selectors target elements with a specific class attribute value. They begin with a dot (.) followed by the class name. Classes are powerful because they allow you to apply the same styles to multiple elements regardless of their type. An HTML element can have multiple classes (separated by spaces in the class attribute), and a class can be applied to any number of elements. When using class selectors, you can apply properties like <kbd>background-color</kbd> to set the background color of elements, and <kbd>font-weight</kbd> to control text thickness, making text bold or normal. This flexibility makes class selectors one of the most commonly used methods for applying styles in CSS, allowing for modular and reusable styling across your website.", "description": "Селектори типу стилізують <em>усі</em> елементи цього типу. Але що якщо ви хочете стилізувати лише деякі з них?<br><br><strong>Селектори класів</strong> націлюються на елементи з певним атрибутом <kbd>class</kbd>. Вони починаються з крапки:<br><br><pre>.badge {<br> background: coral;<br>}</pre><br>Це стилізує лише елементи з <kbd>class=\"badge\"</kbd>.",
"task": "Create a CSS rule using a class selector that targets elements with the class <kbd>highlight</kbd>. Give these elements a <kbd>yellow</kbd> background and <kbd>bold</kbd> text.", "task": "Стилізуйте значок сповіщень. Напишіть правило з <kbd>.badge</kbd> як селектором і встановіть <kbd>background: tomato</kbd>.",
"previewHTML": "<h2>Using Class Selectors</h2>\n<p>This is a regular paragraph, but <span class=\"highlight\">this span has the highlight class</span> applied to it.</p>\n<p class=\"highlight\">This entire paragraph has the highlight class.</p>\n<ul>\n <li>Regular list item</li>\n <li class=\"highlight\">This list item is highlighted</li>\n</ul>", "previewHTML": "<header>\n <h1>Dashboard</h1>\n <span class=\"badge\">3</span>\n</header>\n<p>You have new notifications waiting.</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "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": "h2, p, li { padding: 5px; margin-bottom: 10px; }",
"codePrefix": "/* Create a class selector for elements with the 'highlight' class */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^\\.highlight\\s*{",
"message": "Start your rule with <kbd>.highlight { … }</kbd> to create a class selector",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "background-color:",
"message": "Include the <kbd>background-color:</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "yellow"
},
"message": "Set the background color to <kbd>yellow</kbd>"
},
{
"type": "contains",
"value": "font-weight:",
"message": "Include the <kbd>font-weight:</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "font-weight",
"expected": "bold"
},
"message": "Set the font-weight to <kbd>bold</kbd>"
},
{
"type": "regex",
"value": "\\.highlight\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "multiple-classes",
"title": "Multiple Classes",
"description": "HTML elements can have multiple classes applied simultaneously, allowing for composable and modular CSS designs. When an element has multiple classes, it will receive styles from all matching class selectors. This approach enables you to build a library of reusable CSS classes that can be combined in different ways. You can also target elements that have a specific combination of classes by chaining class selectors together without spaces (e.g., <kbd>.class1.class2</kbd>). When styling these elements, you might use properties like <kbd>border-color</kbd> to change the color of element borders, and <kbd>background-color</kbd> to set the background color of elements. This technique lets you create conditional styles that only apply when certain classes appear together.",
"task": "Complete the CSS rule that targets elements with both <kbd>card</kbd> and <kbd>featured</kbd> classes by chaining the selectors. Set the border-color to gold and the background-color to lemonchiffon to make featured cards stand out.",
"previewHTML": "<h2>Multiple Class Combinations</h2>\n<div class=\"card\">Regular Card</div>\n<div class=\"card featured\">Featured Card</div>\n<div class=\"featured\">Just Featured (not a card)</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } .card { border: 2px solid gray; padding: 15px; margin-bottom: 10px; border-radius: 5px; }",
"sandboxCSS": "", "sandboxCSS": "",
"codePrefix": "/* The .card class already has basic styling */\n/* Now target elements with BOTH classes: 'card' AND 'featured' */\n", "codePrefix": "",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": ".card.featured { border-color: gold; background-color: lemonchiffon }", "solution": ".badge {\n background: tomato;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^\\.card\\.featured\\s*{", "value": "\\.badge\\s*\\{",
"message": "Chain the selectors as <kbd>.card.featured</kbd> (no space between them)", "message": "Почніть з <kbd>.badge {</kbd> (не забудьте крапку!)"
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "border-color:",
"message": "Include the <kbd>border-color</kbd> property"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "background", "expected": "tomato" },
"property": "border-color", "message": "Встановіть <kbd>background: tomato</kbd>"
"expected": "gold"
},
"message": "Set the border color to <kbd>gold</kbd>"
},
{
"type": "regex",
"value": "\\.card\\.featured\\s*{[^}]*;",
"message": "Make sure to end your CSS rule with a semicolon <kbd>;</kbd>"
},
{
"type": "contains",
"value": "background-color:",
"message": "Include the <kbd>background-color</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "lemonchiffon"
},
"message": "Set the background color to <kbd>lemonchiffon</kbd>"
},
{
"type": "regex",
"value": "\\.card\\.featured\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
} }
] ]
}, },
{ {
"id": "class-with-type", "id": "button-variants",
"title": "Combining Types", "title": "Варіанти кнопок",
"description": "You can combine type selectors with class selectors to target specific HTML elements that have a certain class. This creates a more specific selector that only matches when both conditions are true: the element is of the specified type AND it has the specified class. For example, <kbd>p.note</kbd> would select paragraph elements with the class <kbd>note</kbd>, but would not select divs or spans with that same class. You can style these combined selections using properties like <kbd>background-color</kbd> to set a colored background for your elements. This approach allows you to apply different styles to the same class when it appears on different element types.", "description": "Елементи можуть мати кілька класів. Коли ви з'єднуєте селектори класів без пробілів, ви націлюєтесь на елементи, які мають <em>усі</em> ці класи:<br><br><pre>.btn.primary {<br> background: steelblue;<br>}</pre><br>Це націлюється на елементи з <kbd>class=\"btn primary\"</kbd>, а не лише <kbd>.btn</kbd> або лише <kbd>.primary</kbd>.",
"task": "Create a CSS rule that specifically targets <kbd>&lt;span&gt;</kbd> elements with the class <kbd>highlight</kbd>. Make those elements have an orange background, while other elements with the highlight class remain untouched.", "task": "Стилізуйте основну кнопку. Напишіть правило з <kbd>.btn.primary</kbd> як селектором і встановіть <kbd>background: steelblue</kbd>.",
"previewHTML": "<h2>Type and Class Combinations</h2>\n<p>This paragraph has a <span class=\"highlight\">highlighted span</span> that should have an orange background.</p>\n<p class=\"highlight\">This paragraph has the highlight class but should NOT have an orange background.</p>", "previewHTML": "<div class=\"actions\">\n <button class=\"btn\">Cancel</button>\n <button class=\"btn primary\">Save Changes</button>\n</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } .highlight { font-weight: bold; }", "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": "h2, p, span { padding: 5px; }",
"codePrefix": "/* The .highlight class already sets font-weight to bold */\n/* Now target ONLY span elements with the highlight class */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^span\\.highlight\\s*{",
"message": "Use <kbd>span.highlight</kbd> selector (no space between element and class)",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "background-color:",
"message": "Include the <kbd>background-color</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "orange"
},
"message": "Set the background color to <kbd>orange</kbd>"
},
{
"type": "regex",
"value": "span\\.highlight\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "id-selectors",
"title": "ID Selectors",
"description": "ID selectors target elements with a specific id attribute. They begin with a hash/pound sign (#) followed by the ID name. Unlike classes, IDs must be unique within a document—each ID value should be used only once per page. ID selectors have higher specificity than class or element selectors, meaning they override those selectors when conflicts arise. When styling with ID selectors, you can use properties like <kbd>color</kbd> to define text color, and <kbd>text-decoration</kbd> to control the appearance of text, such as adding underlines to elements. Because of their uniqueness requirement, IDs are best used for one-of-a-kind elements like page headers, main navigation, or specific unique components that appear only once on a page.",
"task": "Create a CSS rule with an ID selector that targets the element with the ID <kbd>main-title</kbd>. Set its color to purple and add an underline with <kbd>text-decoration: underline</kbd>.",
"previewHTML": "<h1 id=\"main-title\">Main Page Title</h1>\n<p>Regular paragraph content.</p>\n<h2>Secondary Heading</h2>\n<p id=\"intro\">Introduction paragraph (different ID).</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }",
"sandboxCSS": "h1, h2, p { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }",
"codePrefix": "/* Create an ID selector to target the element with id=\"main-title\" */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^#main-title\\s*{",
"message": "Start your rule with <kbd>#main-title</kbd> to create an ID selector",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "color:",
"message": "Include the <kbd>color</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "color",
"expected": "purple"
},
"message": "Set the color to <kbd>purple</kbd>"
},
{
"type": "contains",
"value": "text-decoration:",
"message": "Include the <kbd>text-decoration</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "text-decoration",
"expected": "underline"
},
"message": "Set the text-decoration to <kbd>underline</kbd>"
},
{
"type": "regex",
"value": "#main-title\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "id-with-type",
"title": "Type + ID",
"description": "Similar to how you can combine type and class selectors, you can also combine type selectors with ID selectors. For example, <kbd>h1#title</kbd> targets an h1 element with the ID 'title'. When using this combined approach, you can apply CSS properties like <kbd>font-style</kbd> to control the slant of the text, making it italic or normal. While this selector combination is more specific than using just the ID selector, it's often unnecessary since IDs should already be unique in a document. However, this technique can be useful for improving code readability or when you want to emphasize that a particular ID should only appear on a specific element type.",
"task": "Create a CSS rule that combines a type selector with an ID selector to target specifically a paragraph element with the ID <kbd>special</kbd>. Set its font style to italic.",
"previewHTML": "<h2 id=\"special\">Heading with ID \"special\" (should NOT be affected)</h2>\n<p id=\"special\">Paragraph with ID \"special\" (should become italic)</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }",
"sandboxCSS": "h2, p { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }",
"codePrefix": "/* Create a combined type+ID selector for a paragraph with id=\"special\" */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"validations": [
{
"type": "regex",
"value": "^p#special\\s*{",
"message": "Use <kbd>p#special</kbd> to target paragraphs with ID <kbd>special</kbd>",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "font-style:",
"message": "Include the <kbd>font-style</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "font-style",
"expected": "italic"
},
"message": "Set the font-style to <kbd>italic</kbd>"
},
{
"type": "regex",
"value": "p#special\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
}
]
},
{
"id": "selector-lists",
"title": "Selector Lists",
"description": "When multiple elements need the same styling, you can group them together using a selector list (also known as grouping selectors). Selector lists are created by separating individual selectors with commas. This approach reduces repetition in your CSS, making it more maintainable and efficient. For example, <kbd>h1, h2, h3 { color: blue; }</kbd> applies the same blue color to all three heading levels. When styling multiple selectors at once, you can apply properties like <kbd>background-color</kbd> to set the background, <kbd>border-left</kbd> to create a left border with a specific thickness, style, and color, and <kbd>padding-left</kbd> to create space between the content and the left border. Whitespace around commas is optional, and each selector in the list can be any valid selector type-elements, classes, IDs, or even more complex selectors.",
"task": "Create a selector list that applies the same styles to three different elements: paragraphs with class <kbd>note</kbd>, list items with class <kbd>important</kbd>, and the element with ID <kbd>summary</kbd>. Give them a <kbd>lightyellow</kbd> background, a <kbd>gold</kbd> left border, and some left <kbd>padding</kbd>.",
"previewHTML": "<p class=\"note\">This is a note paragraph.</p>\n<ul>\n <li>Regular list item</li>\n <li class=\"important\">Important list item</li>\n</ul>\n<div id=\"summary\">Summary section</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }",
"sandboxCSS": "p, li, div { padding: 8px; margin-bottom: 8px; border: 1px dashed gray; }",
"codePrefix": "/* Create a selector list to apply the same styles to multiple different elements */\n",
"initialCode": "",
"codeSuffix": "",
"previewContainer": "preview-area",
"solution": "p.note,\nli.important,\n#summary {\n background-color: lightyellow;\n border-left: 3px solid gold;\n padding-left: 10px\n}",
"validations": [
{
"type": "contains",
"value": "p.note",
"message": "Include <kbd>p.note</kbd> in your selector list",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "li.important",
"message": "Include <kbd>li.important</kbd> in your selector list",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "#summary",
"message": "Include <kbd>#summary</kbd> in your selector list",
"options": {
"caseSensitive": true
}
},
{
"type": "regex",
"value": "(p\\.note|li\\.important|#summary)\\s*,\\s*(p\\.note|li\\.important|#summary)\\s*,\\s*(p\\.note|li\\.important|#summary)",
"message": "Create a comma-separated list with all three selectors",
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "background-color:",
"message": "Include the <kbd>background-color</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "background-color",
"expected": "lightyellow"
},
"message": "Set the background color to <kbd>lightyellow</kbd>"
},
{
"type": "contains",
"value": "border-left:",
"message": "Include the <kbd>border-left</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "border-left",
"expected": "3px solid gold"
},
"message": "Use <kbd>border-left: 3px solid gold</kbd> to create a left border"
},
{
"type": "contains",
"value": "padding-left:",
"message": "Include the <kbd>padding-left</kbd> property"
},
{
"type": "property_value",
"value": {
"property": "padding-left",
"expected": "10px"
},
"message": "Use <kbd>padding-left: 10px</kbd> to add left padding"
}
]
},
{
"id": "universal-selector",
"title": "Universal (*)",
"description": "The universal selector is denoted by an asterisk (*) and matches any element of any type. It selects everything in the document or, when combined with other selectors, everything within a specific context. For example, <kbd>* { margin: 0; }</kbd> removes margins from all elements, while <kbd>article *</kbd> selects all elements inside article elements. When using the universal selector in combination with other selectors, you can apply properties like <kbd>margin</kbd> to control the spacing around elements. The universal selector is powerful but should be used carefully due to its broad impact. It's commonly used in CSS resets, to override default browser styling, or to target all children of a particular element.",
"task": "Use the universal selector to remove margins from all elements inside the container div. Create a rule using <kbd>div.container *</kbd> as the selector and set <kbd>margin: 0</kbd>.",
"previewHTML": "<div class=\"container\">\n <h2>Inside Container</h2>\n <p>This paragraph is inside the container.</p>\n <ul>\n <li>List item inside container</li>\n </ul>\n</div>\n<p>This paragraph is outside the container and should not be affected.</p>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } div.container { border: 2px solid navy; padding: 15px; background-color: lavender; } h2, p, ul, li { margin: 15px 0; }",
"sandboxCSS": "", "sandboxCSS": "",
"codePrefix": "/* Use the universal selector to target all elements inside the container */\n", "codePrefix": "",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": ".btn.primary {\n background: steelblue;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^div\\.container\\s+\\*\\s*{", "value": "\\.btn\\.primary\\s*\\{",
"message": "Use <kbd>div.container *</kbd> selector (with a space between container and *)", "message": "Використовуйте <kbd>.btn.primary {</kbd> (без пробілу між класами)"
"options": {
"caseSensitive": true
}
},
{
"type": "contains",
"value": "margin:",
"message": "Include the <kbd>margin</kbd> property"
}, },
{ {
"type": "property_value", "type": "property_value",
"value": { "value": { "property": "background", "expected": "steelblue" },
"property": "margin", "message": "Встановіть <kbd>background: steelblue</kbd>"
"expected": "0"
},
"message": "Set margin to <kbd>0</kbd>"
},
{
"type": "regex",
"value": "div\\.container\\s+\\*\\s*{[^}]*}",
"message": "Make sure to close your CSS rule with a closing brace <kbd>}</kbd>",
"options": {
"caseSensitive": true
}
} }
] ]
}, },
{ {
"id": "specificity-basics", "id": "specific-elements",
"title": "Specificity", "title": "Націлювання на конкретні елементи",
"description": "CSS specificity determines which styles take precedence when multiple conflicting rules target the same element. Specificity follows a hierarchical system: inline styles have the highest specificity, followed by ID selectors, then class/attribute/pseudo-class selectors, and finally element/pseudo-element selectors. This can be conceptualized as a four-part score (inline, ID, class, element). When creating multiple rules that may target the same elements, you can use the <kbd>color</kbd> property to set text colors, and specificity will determine which color is actually applied. Understanding specificity is crucial for predictable styling and debugging CSS conflicts. When two selectors have equal specificity, the one that comes last in the stylesheet wins.", "description": "Іноді ви хочете, щоб клас виглядав по-різному на різних елементах. Поєднайте селектор типу з селектором класу (без пробілу) щоб бути більш специфічним:<br><br><pre>a.btn {<br> text-decoration: none;<br>}</pre><br>Це стилізує лише елементи <kbd>&lt;a&gt;</kbd> з класом <kbd>btn</kbd>, а не елементи <kbd>&lt;button&gt;</kbd> з цим класом.",
"task": "Examine the existing CSS rules and add a new rule with higher specificity to override the text color of the paragraph. Create a rule using '.content p' as the selector and set color: green.", "task": "Приберіть підкреслення з кнопок-посилань. Напишіть правило з <kbd>a.btn</kbd> як селектором і встановіть <kbd>text-decoration: none</kbd>.",
"previewHTML": "<div class=\"content\">\n <p>What color will this paragraph be? Look at the CSS rules and their specificity.</p>\n</div>", "previewHTML": "<div class=\"actions\">\n <button class=\"btn\">Regular Button</button>\n <a href=\"#\" class=\"btn\">Link Button</a>\n</div>",
"previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", "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": "p { border: 1px dashed gray; padding: 10px; }", "sandboxCSS": "",
"codePrefix": "/* These CSS rules target the same paragraph but have different specificity */\n\n/* Rule 1: Element selector (lowest specificity) */\np {\n color: red;\n}\n\n/* Rule 2: Descendant selector (higher specificity than just 'p') */\n", "codePrefix": "",
"initialCode": "", "initialCode": "",
"codeSuffix": "", "codeSuffix": "",
"previewContainer": "preview-area", "previewContainer": "preview-area",
"solution": "a.btn {\n text-decoration: none;\n}",
"validations": [ "validations": [
{ {
"type": "regex", "type": "regex",
"value": "^\\.content\\s+p\\s*{", "value": "a\\.btn\\s*\\{",
"message": "Use <kbd>.content p</kbd> as your selector (note the space between)", "message": "Використовуйте <kbd>a.btn {</kbd> (тип + клас, без пробілу)"
"options": {
"caseSensitive": true
}
}, },
{ {
"type": "contains", "type": "property_value",
"value": "color:", "value": { "property": "text-decoration", "expected": "none" },
"message": "Include the <kbd>color</kbd> property" "message": "Встановіть <kbd>text-decoration: none</kbd>"
}
]
},
{
"id": "grouping-selectors",
"title": "Групування селекторів",
"description": "Коли кільком елементам потрібні однакові стилі, перелічіть їх через кому. Це тримає ваш CSS чистим і підтримуваним.<br><br><pre>h1, h2, h3 {<br> color: steelblue;<br>}</pre><br>Це застосовує однаковий колір до всіх трьох рівнів заголовків в одному правилі.",
"task": "Стилізуйте всі заголовки однаково. Додайте <kbd>color: steelblue</kbd> до згрупованого селектора <kbd>h1, h2, h3</kbd>.",
"previewHTML": "<article><h1>Main Title</h1><p>Introduction paragraph with some text.</p><h2>Section Heading</h2><p>More content here.</p><h3>Subsection</h3><p>Final paragraph.</p></article>",
"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": "Встановіть <kbd>color: steelblue</kbd>"
}
]
},
{
"id": "descendant-selectors",
"title": "Селектори нащадків",
"description": "Націлюйтесь на елементи всередині інших елементів використовуючи пробіл між селекторами. Це один з найкорисніших патернів у CSS.<br><br><pre>.nav a {<br> color: white;<br>}</pre><br>Це стилізує лише посилання всередині <kbd>.nav</kbd>, залишаючи інші посилання без змін.",
"task": "Стилізуйте навігаційні посилання по-іншому. Напишіть правило з <kbd>.nav a</kbd> як селектором і встановіть <kbd>color: white</kbd>.",
"previewHTML": "<nav class=\"nav\"><a href=\"#\">Home</a><a href=\"#\">About</a><a href=\"#\">Contact</a></nav><p>Read more in our <a href=\"#\">documentation</a>.</p>",
"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": "Використовуйте <kbd>.nav a {</kbd> (пробіл між .nav і a)"
}, },
{ {
"type": "contains", "type": "property_value",
"value": "green", "value": { "property": "color", "expected": "white" },
"message": "" "message": "Встановіть <kbd>color: white</kbd>"
}
]
},
{
"id": "nested-styling",
"title": "Вкладені стилі",
"description": "Селектори нащадків дозволяють створювати контекстні стилі. Один і той самий елемент може виглядати по-різному залежно від того, де він з'являється.<br><br>Наприклад, абзаци в <kbd>.card</kbd> можуть бути меншими ніж абзаци в <kbd>article</kbd>.",
"task": "Зробіть абзаци всередині картки меншими. Напишіть правило з <kbd>.card p</kbd> як селектором і встановіть <kbd>font-size: 0.9rem</kbd>.",
"previewHTML": "<article><h2>Article Title</h2><p>This is a regular article paragraph with normal-sized text for comfortable reading.</p><div class=\"card\"><strong>Quick Tip</strong><p>Card paragraphs should be slightly smaller to fit the compact design.</p></div><p>Back to regular article text here.</p></article>",
"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": "Використовуйте <kbd>.card p {</kbd> (пробіл між .card і p)"
},
{
"type": "property_value",
"value": { "property": "font-size", "expected": "0.9rem" },
"message": "Встановіть <kbd>font-size: 0.9rem</kbd>"
} }
] ]
} }