From 74ccf32e761637217ff6fab8fbe55ed8e769b916 Mon Sep 17 00:00:00 2001 From: Michael Czechowski Date: Wed, 14 Jan 2026 11:55:30 +0100 Subject: [PATCH] feat: sync all language files to match English CSS Basics lessons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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) --- lessons/ar/00-basic-selectors.json | 649 ++++++++--------------------- lessons/de/00-basic-selectors.json | 649 ++++++++--------------------- lessons/es/00-basic-selectors.json | 649 ++++++++--------------------- lessons/pl/00-basic-selectors.json | 649 ++++++++--------------------- lessons/uk/00-basic-selectors.json | 649 ++++++++--------------------- 5 files changed, 895 insertions(+), 2350 deletions(-) diff --git a/lessons/ar/00-basic-selectors.json b/lessons/ar/00-basic-selectors.json index 6e55337..97f4f04 100644 --- a/lessons/ar/00-basic-selectors.json +++ b/lessons/ar/00-basic-selectors.json @@ -1,548 +1,257 @@ { "$schema": "../../schemas/code-crispies-module-schema.json", "id": "css-basic-selectors", - "title": "CSS Selectors", - "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.", + "title": "أساسيات CSS", + "description": "تعلم اللبنات الأساسية لـ CSS: الخصائص والقيم والمحددات. يعلمك هذا الوحدة قواعد الصياغة التي يتبعها كل إعلان CSS.", "difficulty": "beginner", "lessons": [ { - "id": "introduction-to-selectors", - "title": "What's a Selector?", - "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.
For example, to change the text color of elements, you can use the color property within your declaration block.

/* Element selector */\np {\n  color: orangered;\n  /* │       └─── Indicates the value of the expression\n     │                                                     \n     └─────────── Indicates the property of the expression */\n}
", - "task": "Write a CSS rule using a type selector that targets all paragraph elements p in the document. Make the text blue by setting the color property to blue.", - "previewHTML": "

Introduction to CSS Selectors

\n

This paragraph should turn blue.

\n
This div element should remain unchanged.
\n

This second paragraph should also turn blue.

", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "sandboxCSS": "h1, p, div { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }", - "codePrefix": "/* Write a type selector to target all paragraph elements */\n", + "id": "css-properties", + "title": "خصائص CSS", + "description": "تقوم CSS بتنسيق العناصر باستخدام الإعلانات - أزواج من الخصائص والقيم. كل إعلان يتبع نفس النمط:

property: value;

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

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

This text should turn coral.

", + "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .text { font-size: 1.25rem; }", + "sandboxCSS": "", + "codePrefix": ".text {\n ", "initialCode": "", - "codeSuffix": "", + "codeSuffix": "\n}", "previewContainer": "preview-area", - "solution": "p { color: blue }", + "solution": "color: coral;", "validations": [ { - "type": "regex", - "value": "^p\\s*{", - "message": "Start your rule with p { … } to select all paragraph elements", - "options": { - "caseSensitive": false - } - }, + "type": "property_value", + "value": { "property": "color", "expected": "coral" }, + "message": "أضف color: coral;" + } + ] + }, + { + "id": "multiple-properties", + "title": "خصائص متعددة", + "description": "يمكن أن تحتوي القاعدة على إعلانات متعددة. كل واحدة تذهب في سطرها الخاص، وكل واحدة تحتاج فاصلة منقوطة في النهاية:

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

الترتيب عادةً لا يهم - CSS تطبقها جميعًا. عند التعارض، الأخيرة تفوز.", + "task": "أضف إعلانين: background: lavender; و padding: 1rem;", + "previewHTML": "
A styled card with background and padding.
", + "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .card { border-radius: 8px; }", + "sandboxCSS": "", + "codePrefix": ".card {\n ", + "initialCode": "", + "codeSuffix": "\n}", + "previewContainer": "preview-area", + "solution": "background: lavender;\n padding: 1rem;", + "validations": [ { - "type": "contains", - "value": "color:", - "message": "Include the color: property in your CSS rule" - }, - { - "type": "contains", - "value": "blue", - "message": "Set the color value to blue" + "type": "property_value", + "value": { "property": "background", "expected": "lavender" }, + "message": "أضف background: lavender;" }, { "type": "property_value", - "value": { - "property": "color", - "expected": "blue" - }, - "message": "Use color: blue to set the text color" - }, - { - "type": "regex", - "value": "p\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "options": { - "caseSensitive": false - } + "value": { "property": "padding", "expected": "1rem" }, + "message": "أضف padding: 1rem;" } ] }, { "id": "type-selectors", - "title": "Type Selectors", - "description": "Type selectors (also called tag name selectors or element selectors) target HTML elements based on their tag name. For example, p selects all paragraph elements, h1 selects all level-one headings, and div 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 color for text color, background-color for the background, and font-weight 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.", - "task": "Write three separate CSS rules using type selectors to target specific HTML elements: make h2 headings purple, give span elements a yellow background, and make strong elements red.", - "previewHTML": "

Type Selectors Example

\n

Regular paragraph text with a highlighted span that should have a yellow background.

\n

Another paragraph with strong important text that should be red.

\n

Another Heading

", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "sandboxCSS": "h2, p, span, strong { padding: 3px; }", - "codePrefix": "/* Write three separate type selectors below */\n\n", - "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", + "title": "محددات النوع", + "description": "المحدد يخبر المتصفح أي العناصر يجب تنسيقها. أبسط محدد هو محدد النوع — مجرد اسم وسم HTML.

p {
color: steelblue;
}

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

Fresh Roasted Coffee

\n

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

\n

Each batch is roasted weekly to ensure peak freshness.

\n
", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } h2 { margin: 0 0 1rem; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", - "solution": "/* 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": [ { "type": "regex", - "value": "^h2\\s*{", - "message": "Include an h2 { … } selector" + "value": "p\\s*\\{", + "message": "ابدأ بـ p { لاختيار الفقرات" }, { "type": "property_value", - "value": { - "property": "color", - "expected": "purple" - }, - "message": "Set the color property to purple for h2 elements" - }, + "value": { "property": "color", "expected": "steelblue" }, + "message": "اضبط color: steelblue" + } + ] + }, + { + "id": "styling-links", + "title": "تنسيق الروابط", + "description": "محددات النوع تعمل مع أي عنصر HTML. المحدد a يستهدف جميع الروابط في الصفحة.

الروابط لها لون أزرق وخط تحتها افتراضيًا. يمكنك تغيير كليهما مع CSS — استخدم color للنص و text-decoration: none لإزالة الخط.", + "task": "نسق روابط التنقل. اكتب قاعدة مع a كمحدد واضبط color: coral.", + "previewHTML": "", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } nav { display: flex; gap: 1.5rem; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", + "codeSuffix": "", + "previewContainer": "preview-area", + "solution": "a {\n color: coral;\n}", + "validations": [ { "type": "regex", - "value": "h2\\s*{[^}]*}", - "message": "Make sure to close your h2 rule with a closing brace }" - }, - { - "type": "regex", - "value": "^span\\s*{", - "message": "Include a span { … } selector" + "value": "a\\s*\\{", + "message": "ابدأ بـ a { لاختيار الروابط" }, { "type": "property_value", - "value": { - "property": "background-color", - "expected": "yellow" - }, - "message": "Set a background-color: yellow for span elements" - }, - { - "type": "regex", - "value": "span\\s*{[^}]*}", - "message": "Make sure to close your span rule with a closing brace }" - }, - { - "type": "regex", - "value": "^strong\\s*{", - "message": "Include a strong { … } selector" - }, - { - "type": "regex", - "value": "strong\\s*{\\s*color:\\s*red;[^}]*}", - "message": "Set the color: red for strong elements" + "value": { "property": "color", "expected": "coral" }, + "message": "اضبط color: coral" } ] }, { "id": "class-selectors", - "title": "Class Selectors", - "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 background-color to set the background color of elements, and font-weight 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.", - "task": "Create a CSS rule using a class selector that targets elements with the class highlight. Give these elements a yellow background and bold text.", - "previewHTML": "

Using Class Selectors

\n

This is a regular paragraph, but this span has the highlight class applied to it.

\n

This entire paragraph has the highlight class.

\n", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "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 .highlight { … } to create a class selector", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "background-color:", - "message": "Include the background-color: property" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "yellow" - }, - "message": "Set the background color to yellow" - }, - { - "type": "contains", - "value": "font-weight:", - "message": "Include the font-weight: property" - }, - { - "type": "property_value", - "value": { - "property": "font-weight", - "expected": "bold" - }, - "message": "Set the font-weight to bold" - }, - { - "type": "regex", - "value": "\\.highlight\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "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., .class1.class2). When styling these elements, you might use properties like border-color to change the color of element borders, and background-color 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 card and featured classes by chaining the selectors. Set the border-color to gold and the background-color to lemonchiffon to make featured cards stand out.", - "previewHTML": "

Multiple Class Combinations

\n
Regular Card
\n
Featured Card
\n
Just Featured (not a card)
", - "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; }", + "title": "محددات الفئة", + "description": "محددات النوع تنسق جميع العناصر من ذلك النوع. لكن ماذا لو أردت تنسيق بعضها فقط؟

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

.badge {
background: coral;
}

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

Dashboard

\n 3\n
\n

You have new notifications waiting.

", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } header { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; } h1 { margin: 0; font-size: 1.5rem; } .badge { color: white; padding: 0.25rem 0.5rem; border-radius: 999px; font-size: 0.875rem; } p { color: #555; margin: 0; }", "sandboxCSS": "", - "codePrefix": "/* The .card class already has basic styling */\n/* Now target elements with BOTH classes: 'card' AND 'featured' */\n", + "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", - "solution": ".card.featured { border-color: gold; background-color: lemonchiffon }", + "solution": ".badge {\n background: tomato;\n}", "validations": [ { "type": "regex", - "value": "^\\.card\\.featured\\s*{", - "message": "Chain the selectors as .card.featured (no space between them)", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "border-color:", - "message": "Include the border-color property" + "value": "\\.badge\\s*\\{", + "message": "ابدأ بـ .badge { (لا تنسَ النقطة!)" }, { "type": "property_value", - "value": { - "property": "border-color", - "expected": "gold" - }, - "message": "Set the border color to gold" - }, - { - "type": "regex", - "value": "\\.card\\.featured\\s*{[^}]*;", - "message": "Make sure to end your CSS rule with a semicolon ;" - }, - { - "type": "contains", - "value": "background-color:", - "message": "Include the background-color property" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "lemonchiffon" - }, - "message": "Set the background color to lemonchiffon" - }, - { - "type": "regex", - "value": "\\.card\\.featured\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "options": { - "caseSensitive": true - } + "value": { "property": "background", "expected": "tomato" }, + "message": "اضبط background: tomato" } ] }, { - "id": "class-with-type", - "title": "Combining Types", - "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, p.note would select paragraph elements with the class note, but would not select divs or spans with that same class. You can style these combined selections using properties like background-color 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.", - "task": "Create a CSS rule that specifically targets <span> elements with the class highlight. Make those elements have an orange background, while other elements with the highlight class remain untouched.", - "previewHTML": "

Type and Class Combinations

\n

This paragraph has a highlighted span that should have an orange background.

\n

This paragraph has the highlight class but should NOT have an orange background.

", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } .highlight { font-weight: bold; }", - "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 span.highlight selector (no space between element and class)", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "background-color:", - "message": "Include the background-color property" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "orange" - }, - "message": "Set the background color to orange" - }, - { - "type": "regex", - "value": "span\\.highlight\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "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 color to define text color, and text-decoration 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 main-title. Set its color to purple and add an underline with text-decoration: underline.", - "previewHTML": "

Main Page Title

\n

Regular paragraph content.

\n

Secondary Heading

\n

Introduction paragraph (different ID).

", - "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 #main-title to create an ID selector", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "color:", - "message": "Include the color property" - }, - { - "type": "property_value", - "value": { - "property": "color", - "expected": "purple" - }, - "message": "Set the color to purple" - }, - { - "type": "contains", - "value": "text-decoration:", - "message": "Include the text-decoration property" - }, - { - "type": "property_value", - "value": { - "property": "text-decoration", - "expected": "underline" - }, - "message": "Set the text-decoration to underline" - }, - { - "type": "regex", - "value": "#main-title\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "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, h1#title targets an h1 element with the ID 'title'. When using this combined approach, you can apply CSS properties like font-style 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 special. Set its font style to italic.", - "previewHTML": "

Heading with ID \"special\" (should NOT be affected)

\n

Paragraph with ID \"special\" (should become italic)

", - "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 p#special to target paragraphs with ID special", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "font-style:", - "message": "Include the font-style property" - }, - { - "type": "property_value", - "value": { - "property": "font-style", - "expected": "italic" - }, - "message": "Set the font-style to italic" - }, - { - "type": "regex", - "value": "p#special\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "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, h1, h2, h3 { color: blue; } applies the same blue color to all three heading levels. When styling multiple selectors at once, you can apply properties like background-color to set the background, border-left to create a left border with a specific thickness, style, and color, and padding-left 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 note, list items with class important, and the element with ID summary. Give them a lightyellow background, a gold left border, and some left padding.", - "previewHTML": "

This is a note paragraph.

\n\n
Summary section
", - "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 p.note in your selector list", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "li.important", - "message": "Include li.important in your selector list", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "#summary", - "message": "Include #summary 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 background-color property" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "lightyellow" - }, - "message": "Set the background color to lightyellow" - }, - { - "type": "contains", - "value": "border-left:", - "message": "Include the border-left property" - }, - { - "type": "property_value", - "value": { - "property": "border-left", - "expected": "3px solid gold" - }, - "message": "Use border-left: 3px solid gold to create a left border" - }, - { - "type": "contains", - "value": "padding-left:", - "message": "Include the padding-left property" - }, - { - "type": "property_value", - "value": { - "property": "padding-left", - "expected": "10px" - }, - "message": "Use padding-left: 10px 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, * { margin: 0; } removes margins from all elements, while article * selects all elements inside article elements. When using the universal selector in combination with other selectors, you can apply properties like margin 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 div.container * as the selector and set margin: 0.", - "previewHTML": "
\n

Inside Container

\n

This paragraph is inside the container.

\n \n
\n

This paragraph is outside the container and should not be affected.

", - "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; }", + "id": "button-variants", + "title": "متغيرات الأزرار", + "description": "يمكن أن تحتوي العناصر على فئات متعددة. عندما تسلسل محددات الفئة بدون مسافات، تستهدف العناصر التي لديها جميع تلك الفئات:

.btn.primary {
background: steelblue;
}

هذا يستهدف العناصر ذات class=\"btn primary\"، وليس فقط .btn أو فقط .primary.", + "task": "نسق الزر الأساسي. اكتب قاعدة مع .btn.primary كمحدد واضبط background: steelblue.", + "previewHTML": "
\n \n \n
", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } .actions { display: flex; gap: 0.75rem; } .btn { padding: 0.5rem 1rem; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; background: #e0e0e0; color: #333; }", "sandboxCSS": "", - "codePrefix": "/* Use the universal selector to target all elements inside the container */\n", + "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", + "solution": ".btn.primary {\n background: steelblue;\n}", "validations": [ { "type": "regex", - "value": "^div\\.container\\s+\\*\\s*{", - "message": "Use div.container * selector (with a space between container and *)", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "margin:", - "message": "Include the margin property" + "value": "\\.btn\\.primary\\s*\\{", + "message": "استخدم .btn.primary { (بدون مسافة بين الفئات)" }, { "type": "property_value", - "value": { - "property": "margin", - "expected": "0" - }, - "message": "Set margin to 0" - }, - { - "type": "regex", - "value": "div\\.container\\s+\\*\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "options": { - "caseSensitive": true - } + "value": { "property": "background", "expected": "steelblue" }, + "message": "اضبط background: steelblue" } ] }, { - "id": "specificity-basics", - "title": "Specificity", - "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 color 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.", - "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.", - "previewHTML": "
\n

What color will this paragraph be? Look at the CSS rules and their specificity.

\n
", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "sandboxCSS": "p { border: 1px dashed gray; padding: 10px; }", - "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", + "id": "specific-elements", + "title": "استهداف عناصر محددة", + "description": "أحيانًا تريد أن تبدو الفئة مختلفة على عناصر مختلفة. اجمع محدد النوع مع محدد الفئة (بدون مسافة) لتكون أكثر تحديدًا:

a.btn {
text-decoration: none;
}

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

h1, h2, h3 {
color: steelblue;
}

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

Main Title

Introduction paragraph with some text.

Section Heading

More content here.

Subsection

Final paragraph.

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

.nav a {
color: white;
}

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

Read more in our documentation.

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

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

Article Title

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

Quick Tip

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

Back to regular article text here.

", + "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } article { max-width: 500px; } h2 { color: steelblue; margin-top: 0; } p { line-height: 1.6; color: #444; } .card { background: #f0f4f8; padding: 1rem; border-radius: 8px; border-left: 4px solid steelblue; } .card strong { color: steelblue; display: block; margin-bottom: 0.5rem; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", + "codeSuffix": "", + "previewContainer": "preview-area", + "solution": ".card p {\n font-size: 0.9rem;\n}", + "validations": [ + { + "type": "regex", + "value": "\\.card\\s+p\\s*\\{", + "message": "استخدم .card p { (مسافة بين .card و p)" + }, + { + "type": "property_value", + "value": { "property": "font-size", "expected": "0.9rem" }, + "message": "اضبط font-size: 0.9rem" } ] } diff --git a/lessons/de/00-basic-selectors.json b/lessons/de/00-basic-selectors.json index 592852c..b9ff9b3 100644 --- a/lessons/de/00-basic-selectors.json +++ b/lessons/de/00-basic-selectors.json @@ -1,548 +1,257 @@ { "$schema": "../../schemas/code-crispies-module-schema.json", "id": "css-basic-selectors", - "title": "CSS Selektoren", - "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.", + "title": "CSS Grundlagen", + "description": "Lerne die grundlegenden Bausteine von CSS: Eigenschaften, Werte und Selektoren. Dieses Modul vermittelt dir die Syntaxregeln, denen jede CSS-Deklaration folgt.", "difficulty": "beginner", "lessons": [ { - "id": "introduction-to-selectors", - "title": "Was ist ein CSS-Selektor?", - "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.
Um beispielsweise die Textfarbe von Elementen zu ändern, kannst du die color-Eigenschaft in deinem Deklarationsblock verwenden.

/* Element-Selektor */\np {\n  color: orangered;\n  /* │       └─── Gibt den Wert des Ausdrucks an\n     │                                                     \n     └─────────── Gibt die Eigenschaft des Ausdrucks an */\n}
", - "task": "Schreibe eine CSS-Regel mit einem Typ-Selektor, die alle Absatz-Elemente p im Dokument anvisiert. Mache den Text blau, indem du die color-Eigenschaft auf blue setzt.", - "previewHTML": "

Einführung in CSS-Selektoren

\n

Dieser Absatz sollte blau werden.

\n
Dieses div-Element sollte unverändert bleiben.
\n

Dieser zweite Absatz sollte ebenfalls blau werden.

", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "sandboxCSS": "h1, p, div { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }", - "codePrefix": "/* Schreibe einen Typ-Selektor, um alle Absatz-Elemente anzuvisieren */\n", + "id": "css-properties", + "title": "CSS-Eigenschaften", + "description": "CSS gestaltet Elemente mit Deklarationen - Paaren aus Eigenschaften und Werten. Jede Deklaration folgt dem gleichen Muster:

property: value;

Die Eigenschaft ist das, was du ändern möchtest (wie color oder background). Der Wert ist das, worauf du es setzt. Ein Doppelpunkt trennt sie, und ein Semikolon beendet die Zeile.

Werte gibt es in verschiedenen Typen:
Schlüsselwörter: red, bold, center
Zahlen mit Einheiten: 16px, 2rem, 100%
Farben: steelblue, #ff0000", + "task": "Vervollständige die Deklaration, indem du color: coral; hinzufügst, um die Textfarbe zu ändern.", + "previewHTML": "

This text should turn coral.

", + "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .text { font-size: 1.25rem; }", + "sandboxCSS": "", + "codePrefix": ".text {\n ", "initialCode": "", - "codeSuffix": "", + "codeSuffix": "\n}", "previewContainer": "preview-area", - "solution": "p { color: blue }", + "solution": "color: coral;", "validations": [ { - "type": "regex", - "value": "^p\\s*{", - "message": "Beginne deine Regel mit p { … }, um alle Absatz-Elemente auszuwählen", - "options": { - "caseSensitive": false - } - }, + "type": "property_value", + "value": { "property": "color", "expected": "coral" }, + "message": "Füge color: coral; hinzu" + } + ] + }, + { + "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:

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

Die Reihenfolge spielt normalerweise keine Rolle - CSS wendet alle an. Bei Konflikten gewinnt die letzte.", + "task": "Füge zwei Deklarationen hinzu: background: lavender; und padding: 1rem;", + "previewHTML": "
A styled card with background and padding.
", + "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .card { border-radius: 8px; }", + "sandboxCSS": "", + "codePrefix": ".card {\n ", + "initialCode": "", + "codeSuffix": "\n}", + "previewContainer": "preview-area", + "solution": "background: lavender;\n padding: 1rem;", + "validations": [ { - "type": "contains", - "value": "color:", - "message": "Füge die color:-Eigenschaft in deine CSS-Regel ein" - }, - { - "type": "contains", - "value": "blue", - "message": "Setze den Farbwert auf blue" + "type": "property_value", + "value": { "property": "background", "expected": "lavender" }, + "message": "Füge background: lavender; hinzu" }, { "type": "property_value", - "value": { - "property": "color", - "expected": "blue" - }, - "message": "Verwende color: blue, um die Textfarbe zu setzen" - }, - { - "type": "regex", - "value": "p\\s*{[^}]*}", - "message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer } zu beenden", - "options": { - "caseSensitive": false - } + "value": { "property": "padding", "expected": "1rem" }, + "message": "Füge padding: 1rem; hinzu" } ] }, { "id": "type-selectors", - "title": "Typ-Selektoren: HTML-Elemente anvisieren", - "description": "Typ-Selektoren (auch Tag-Name-Selektoren oder Element-Selektoren genannt) visieren HTML-Elemente basierend auf ihrem Tag-Namen an. Zum Beispiel wählt p alle Absatz-Elemente, h1 alle Überschriften der ersten Ebene und div 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 color für Textfarbe, background-color für den Hintergrund und font-weight 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.", - "task": "Schreibe drei separate CSS-Regeln mit Typ-Selektoren, um bestimmte HTML-Elemente anzuvisieren: mache h2-Überschriften purple, gib span-Elementen einen yellow-Hintergrund und mache strong-Elemente red.", - "previewHTML": "

Typ-Selektoren Beispiel

\n

Normaler Absatztext mit einem hervorgehobenen Span, der einen gelben Hintergrund haben sollte.

\n

Ein weiterer Absatz mit wichtigem, fetten Text, der rot sein sollte.

\n

Eine weitere Überschrift

", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "sandboxCSS": "h2, p, span, strong { padding: 3px; }", - "codePrefix": "/* Schreibe drei separate Typ-Selektoren unten */\n\n", - "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", + "title": "Typ-Selektoren", + "description": "Ein Selektor sagt dem Browser, welche Elemente gestylt werden sollen. Der einfachste Selektor ist ein Typ-Selektor — einfach der HTML-Tag-Name.

p {
color: steelblue;
}

Diese Regel zielt auf jedes <p>-Element auf der Seite. Typ-Selektoren eignen sich hervorragend für Basis-Styles.", + "task": "Style alle Absätze. Schreibe eine Regel mit p als Selektor und setze color: steelblue.", + "previewHTML": "
\n

Fresh Roasted Coffee

\n

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

\n

Each batch is roasted weekly to ensure peak freshness.

\n
", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } h2 { margin: 0 0 1rem; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", - "solution": "/* 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": [ { "type": "regex", - "value": "^h2\\s*{", - "message": "Füge einen h2 { … }-Selektor hinzu" + "value": "p\\s*\\{", + "message": "Beginne mit p {, um Absätze auszuwählen" }, { "type": "property_value", - "value": { - "property": "color", - "expected": "purple" - }, - "message": "Setze die color-Eigenschaft auf purple für h2-Elemente" - }, + "value": { "property": "color", "expected": "steelblue" }, + "message": "Setze color: steelblue" + } + ] + }, + { + "id": "styling-links", + "title": "Links stylen", + "description": "Typ-Selektoren funktionieren für jedes HTML-Element. Der a-Selektor zielt auf alle Links einer Seite.

Links haben standardmäßig eine blaue Farbe und Unterstreichung. Du kannst beides mit CSS ändern — verwende color für den Text und text-decoration: none, um die Unterstreichung zu entfernen.", + "task": "Style die Navigationslinks. Schreibe eine Regel mit a als Selektor und setze color: coral.", + "previewHTML": "", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } nav { display: flex; gap: 1.5rem; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", + "codeSuffix": "", + "previewContainer": "preview-area", + "solution": "a {\n color: coral;\n}", + "validations": [ { "type": "regex", - "value": "h2\\s*{[^}]*}", - "message": "Vergiss nicht, deine h2-Regel mit einer schließenden Klammer } zu beenden" - }, - { - "type": "regex", - "value": "^span\\s*{", - "message": "Füge einen span { … }-Selektor hinzu" + "value": "a\\s*\\{", + "message": "Beginne mit a {, um Links auszuwählen" }, { "type": "property_value", - "value": { - "property": "background-color", - "expected": "yellow" - }, - "message": "Setze background-color: yellow für span-Elemente" - }, - { - "type": "regex", - "value": "span\\s*{[^}]*}", - "message": "Vergiss nicht, deine span-Regel mit einer schließenden Klammer } zu beenden" - }, - { - "type": "regex", - "value": "^strong\\s*{", - "message": "Füge einen strong { … }-Selektor hinzu" - }, - { - "type": "regex", - "value": "strong\\s*{\\s*color:\\s*red;[^}]*}", - "message": "Setze color: red für strong-Elemente" + "value": { "property": "color", "expected": "coral" }, + "message": "Setze color: coral" } ] }, { "id": "class-selectors", - "title": "Klassen-Selektoren: Elementgruppen stylen", - "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 background-color zum Setzen der Hintergrundfarbe und font-weight 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.", - "task": "Erstelle eine CSS-Regel mit einem Klassen-Selektor, die Elemente mit der Klasse highlight anvisiert. Gib diesen Elementen einen yellow-Hintergrund und bold-Text.", - "previewHTML": "

Verwendung von Klassen-Selektoren

\n

Dies ist ein normaler Absatz, aber dieser Span hat die highlight-Klasse angewendet.

\n

Dieser gesamte Absatz hat die highlight-Klasse.

\n", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "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 .highlight { … }, um einen Klassen-Selektor zu erstellen", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "background-color:", - "message": "Füge die background-color:-Eigenschaft hinzu" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "yellow" - }, - "message": "Setze die Hintergrundfarbe auf yellow" - }, - { - "type": "contains", - "value": "font-weight:", - "message": "Füge die font-weight:-Eigenschaft hinzu" - }, - { - "type": "property_value", - "value": { - "property": "font-weight", - "expected": "bold" - }, - "message": "Setze font-weight auf bold" - }, - { - "type": "regex", - "value": "\\.highlight\\s*{[^}]*}", - "message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer } 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. .class1.class2). Beim Stylen dieser Elemente könntest du Eigenschaften wie border-color verwenden, um die Farbe von Element-Rahmen zu ändern, und background-color, 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 card als auch featured-Klassen anvisiert, indem du die Selektoren verkettest. Setze border-color auf gold und background-color auf lemonchiffon, um hervorgehobene Karten hervorzuheben.", - "previewHTML": "

Mehrfach-Klassen-Kombinationen

\n
Normale Karte
\n
Hervorgehobene Karte
\n
Nur hervorgehoben (keine Karte)
", - "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; }", + "title": "Klassen-Selektoren", + "description": "Typ-Selektoren stylen alle Elemente dieses Typs. Aber was, wenn du nur einige davon stylen möchtest?

Klassen-Selektoren zielen auf Elemente mit einem bestimmten class-Attribut. Sie beginnen mit einem Punkt:

.badge {
background: coral;
}

Das stylt nur Elemente mit class=\"badge\".", + "task": "Style das Benachrichtigungs-Badge. Schreibe eine Regel mit .badge als Selektor und setze background: tomato.", + "previewHTML": "
\n

Dashboard

\n 3\n
\n

You have new notifications waiting.

", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } header { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; } h1 { margin: 0; font-size: 1.5rem; } .badge { color: white; padding: 0.25rem 0.5rem; border-radius: 999px; font-size: 0.875rem; } p { color: #555; margin: 0; }", "sandboxCSS": "", - "codePrefix": "/* Die .card-Klasse hat bereits grundlegendes Styling */\n/* Visiere jetzt Elemente mit BEIDEN Klassen an: 'card' UND 'featured' */\n", + "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", - "solution": ".card.featured { border-color: gold; background-color: lemonchiffon }", + "solution": ".badge {\n background: tomato;\n}", "validations": [ { "type": "regex", - "value": "^\\.card\\.featured\\s*{", - "message": "Verkette die Selektoren als .card.featured (kein Leerzeichen dazwischen)", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "border-color:", - "message": "Füge die border-color-Eigenschaft hinzu" + "value": "\\.badge\\s*\\{", + "message": "Beginne mit .badge { (vergiss den Punkt nicht!)" }, { "type": "property_value", - "value": { - "property": "border-color", - "expected": "gold" - }, - "message": "Setze die Rahmenfarbe auf gold" - }, - { - "type": "regex", - "value": "\\.card\\.featured\\s*{[^}]*;", - "message": "Vergiss nicht, deine CSS-Regel mit einem Semikolon ; zu beenden" - }, - { - "type": "contains", - "value": "background-color:", - "message": "Füge die background-color-Eigenschaft hinzu" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "lemonchiffon" - }, - "message": "Setze die Hintergrundfarbe auf lemonchiffon" - }, - { - "type": "regex", - "value": "\\.card\\.featured\\s*{[^}]*}", - "message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer } zu beenden", - "options": { - "caseSensitive": true - } + "value": { "property": "background", "expected": "tomato" }, + "message": "Setze background: tomato" } ] }, { - "id": "class-with-type", - "title": "Typ- und Klassen-Selektoren kombinieren", - "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 p.note Absatz-Elemente mit der Klasse note auswählen, aber keine divs oder spans mit derselben Klasse. Du kannst diese kombinierten Selektionen mit Eigenschaften wie background-color 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.", - "task": "Erstelle eine CSS-Regel, die speziell <span>-Elemente mit der Klasse highlight anvisiert. Gib diesen Elementen einen orangen Hintergrund, während andere Elemente mit der highlight-Klasse unverändert bleiben.", - "previewHTML": "

Typ- und Klassen-Kombinationen

\n

Dieser Absatz hat einen hervorgehobenen Span, der einen orangen Hintergrund haben sollte.

\n

Dieser Absatz hat die highlight-Klasse, sollte aber KEINEN orangen Hintergrund haben.

", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } .highlight { font-weight: bold; }", - "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 span.highlight-Selektor (kein Leerzeichen zwischen Element und Klasse)", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "background-color:", - "message": "Füge die background-color-Eigenschaft hinzu" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "orange" - }, - "message": "Setze die Hintergrundfarbe auf orange" - }, - { - "type": "regex", - "value": "span\\.highlight\\s*{[^}]*}", - "message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer } 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 color verwenden, um die Textfarbe zu definieren, und text-decoration, 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 main-title anvisiert. Setze seine Farbe auf purple und füge eine Unterstreichung mit text-decoration: underline hinzu.", - "previewHTML": "

Haupt-Seitentitel

\n

Normaler Absatzinhalt.

\n

Sekundäre Überschrift

\n

Einführungsabsatz (andere ID).

", - "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 #main-title, um einen ID-Selektor zu erstellen", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "color:", - "message": "Füge die color-Eigenschaft hinzu" - }, - { - "type": "property_value", - "value": { - "property": "color", - "expected": "purple" - }, - "message": "Setze die Farbe auf purple" - }, - { - "type": "contains", - "value": "text-decoration:", - "message": "Füge die text-decoration-Eigenschaft hinzu" - }, - { - "type": "property_value", - "value": { - "property": "text-decoration", - "expected": "underline" - }, - "message": "Setze text-decoration auf underline" - }, - { - "type": "regex", - "value": "#main-title\\s*{[^}]*}", - "message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer } 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 h1#title ein h1-Element mit der ID 'title' an. Bei diesem kombinierten Ansatz kannst du CSS-Eigenschaften wie font-style 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 special anzuvisieren. Setze seinen Schriftstil auf kursiv.", - "previewHTML": "

Überschrift mit ID \"special\" (sollte NICHT betroffen sein)

\n

Absatz mit ID \"special\" (sollte kursiv werden)

", - "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 p#special, um Absätze mit ID special anzuvisieren", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "font-style:", - "message": "Füge die font-style-Eigenschaft hinzu" - }, - { - "type": "property_value", - "value": { - "property": "font-style", - "expected": "italic" - }, - "message": "Setze font-style auf italic" - }, - { - "type": "regex", - "value": "p#special\\s*{[^}]*}", - "message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer } 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 h1, h2, h3 { color: blue; } die gleiche blaue Farbe auf alle drei Überschriftenebenen an. Beim Stylen mehrerer Selektoren gleichzeitig kannst du Eigenschaften wie background-color für den Hintergrund, border-left für einen linken Rahmen mit bestimmter Dicke, Stil und Farbe, und padding-left 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 note, Listenelemente mit der Klasse important und das Element mit der ID summary. Gib ihnen einen lightyellow-Hintergrund, einen gold-linken Rahmen und etwas linkes padding.", - "previewHTML": "

Dies ist ein Notiz-Absatz.

\n\n
Zusammenfassungs-Abschnitt
", - "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 p.note in deine Selektor-Liste ein", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "li.important", - "message": "Füge li.important in deine Selektor-Liste ein", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "#summary", - "message": "Füge #summary 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 background-color-Eigenschaft hinzu" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "lightyellow" - }, - "message": "Setze die Hintergrundfarbe auf lightyellow" - }, - { - "type": "contains", - "value": "border-left:", - "message": "Füge die border-left-Eigenschaft hinzu" - }, - { - "type": "property_value", - "value": { - "property": "border-left", - "expected": "3px solid gold" - }, - "message": "Verwende border-left: 3px solid gold, um einen linken Rahmen zu erstellen" - }, - { - "type": "contains", - "value": "padding-left:", - "message": "Füge die padding-left-Eigenschaft hinzu" - }, - { - "type": "property_value", - "value": { - "property": "padding-left", - "expected": "10px" - }, - "message": "Verwende padding-left: 10px, 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 * { margin: 0; } Ränder von allen Elementen, während article * alle Elemente innerhalb von article-Elementen auswählt. Bei der Verwendung des universellen Selektors in Kombination mit anderen Selektoren kannst du Eigenschaften wie margin 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 div.container * als Selektor und setze margin: 0.", - "previewHTML": "
\n

Innerhalb des Containers

\n

Dieser Absatz ist innerhalb des Containers.

\n \n
\n

Dieser Absatz ist außerhalb des Containers und sollte nicht betroffen sein.

", - "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; }", + "id": "button-variants", + "title": "Button-Varianten", + "description": "Elemente können mehrere Klassen haben. Wenn du Klassen-Selektoren ohne Leerzeichen verkettst, zielst du auf Elemente, die alle diese Klassen haben:

.btn.primary {
background: steelblue;
}

Das zielt auf Elemente mit class=\"btn primary\", nicht nur auf .btn oder nur .primary.", + "task": "Style den primären Button. Schreibe eine Regel mit .btn.primary als Selektor und setze background: steelblue.", + "previewHTML": "
\n \n \n
", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } .actions { display: flex; gap: 0.75rem; } .btn { padding: 0.5rem 1rem; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; background: #e0e0e0; color: #333; }", "sandboxCSS": "", - "codePrefix": "/* Verwende den universellen Selektor, um alle Elemente innerhalb des Containers anzuvisieren */\n", + "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", + "solution": ".btn.primary {\n background: steelblue;\n}", "validations": [ { "type": "regex", - "value": "^div\\.container\\s+\\*\\s*{", - "message": "Verwende div.container *-Selektor (mit einem Leerzeichen zwischen container und *)", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "margin:", - "message": "Füge die margin-Eigenschaft hinzu" + "value": "\\.btn\\.primary\\s*\\{", + "message": "Verwende .btn.primary { (kein Leerzeichen zwischen den Klassen)" }, { "type": "property_value", - "value": { - "property": "margin", - "expected": "0" - }, - "message": "Setze margin auf 0" - }, - { - "type": "regex", - "value": "div\\.container\\s+\\*\\s*{[^}]*}", - "message": "Vergiss nicht, deine CSS-Regel mit einer schließenden Klammer } zu beenden", - "options": { - "caseSensitive": true - } + "value": { "property": "background", "expected": "steelblue" }, + "message": "Setze background: steelblue" } ] }, { - "id": "specificity-basics", - "title": "Selektor-Spezifität verstehen", - "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 color-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.", - "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.", - "previewHTML": "
\n

Welche Farbe wird dieser Absatz haben? Schau dir die CSS-Regeln und ihre Spezifität an.

\n
", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "sandboxCSS": "p { border: 1px dashed gray; padding: 10px; }", - "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", + "id": "specific-elements", + "title": "Spezifische Elemente ansprechen", + "description": "Manchmal soll eine Klasse auf verschiedenen Elementen unterschiedlich aussehen. Kombiniere einen Typ-Selektor mit einem Klassen-Selektor (ohne Leerzeichen), um spezifischer zu sein:

a.btn {
text-decoration: none;
}

Das stylt nur <a>-Elemente mit der btn-Klasse, nicht <button>-Elemente mit dieser Klasse.", + "task": "Entferne die Unterstreichung von Link-Buttons. Schreibe eine Regel mit a.btn als Selektor und setze text-decoration: none.", + "previewHTML": "
\n \n Link Button\n
", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } .actions { display: flex; gap: 0.75rem; align-items: center; } .btn { padding: 0.5rem 1rem; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; background: steelblue; color: white; }", + "sandboxCSS": "", + "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", + "solution": "a.btn {\n text-decoration: none;\n}", "validations": [ { "type": "regex", - "value": "^\\.content\\s+p\\s*{", - "message": "Verwende .content p als deinen Selektor (beachte das Leerzeichen dazwischen)", - "options": { - "caseSensitive": true - } + "value": "a\\.btn\\s*\\{", + "message": "Verwende a.btn { (Typ + Klasse, kein Leerzeichen)" }, { - "type": "contains", - "value": "color:", - "message": "Füge die color-Eigenschaft hinzu" + "type": "property_value", + "value": { "property": "text-decoration", "expected": "none" }, + "message": "Setze text-decoration: none" + } + ] + }, + { + "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.

h1, h2, h3 {
color: steelblue;
}

Das wendet die gleiche Farbe auf alle drei Überschriftenebenen in einer Regel an.", + "task": "Style alle Überschriften einheitlich. Füge color: steelblue zum gruppierten h1, h2, h3-Selektor hinzu.", + "previewHTML": "

Main Title

Introduction paragraph with some text.

Section Heading

More content here.

Subsection

Final paragraph.

", + "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } article { max-width: 500px; } p { color: #555; line-height: 1.6; }", + "sandboxCSS": "", + "codePrefix": "h1, h2, h3 {\n ", + "initialCode": "", + "codeSuffix": "\n}", + "previewContainer": "preview-area", + "solution": "color: steelblue;", + "validations": [ + { + "type": "property_value", + "value": { "property": "color", "expected": "steelblue" }, + "message": "Setze color: steelblue" + } + ] + }, + { + "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.

.nav a {
color: white;
}

Das stylt nur Links innerhalb von .nav und lässt andere Links unverändert.", + "task": "Style Navigationslinks anders. Schreibe eine Regel mit .nav a als Selektor und setze color: white.", + "previewHTML": "

Read more in our documentation.

", + "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; margin: 0; } .nav { background: steelblue; padding: 1rem; display: flex; gap: 1rem; border-radius: 8px; margin-bottom: 1rem; } .nav a { text-decoration: none; } p a { color: steelblue; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", + "codeSuffix": "", + "previewContainer": "preview-area", + "solution": ".nav a {\n color: white;\n}", + "validations": [ + { + "type": "regex", + "value": "\\.nav\\s+a\\s*\\{", + "message": "Verwende .nav a { (Leerzeichen zwischen .nav und a)" }, { - "type": "contains", - "value": "green", - "message": "" + "type": "property_value", + "value": { "property": "color", "expected": "white" }, + "message": "Setze color: white" + } + ] + }, + { + "id": "nested-styling", + "title": "Verschachtelte Styles", + "description": "Nachfahren-Selektoren ermöglichen kontextabhängige Styles. Das gleiche Element kann je nach Position unterschiedlich aussehen.

Zum Beispiel könnten Absätze in einer .card kleiner sein als Absätze in einem article.", + "task": "Mache Absätze innerhalb der Karte kleiner. Schreibe eine Regel mit .card p als Selektor und setze font-size: 0.9rem.", + "previewHTML": "

Article Title

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

Quick Tip

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

Back to regular article text here.

", + "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } article { max-width: 500px; } h2 { color: steelblue; margin-top: 0; } p { line-height: 1.6; color: #444; } .card { background: #f0f4f8; padding: 1rem; border-radius: 8px; border-left: 4px solid steelblue; } .card strong { color: steelblue; display: block; margin-bottom: 0.5rem; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", + "codeSuffix": "", + "previewContainer": "preview-area", + "solution": ".card p {\n font-size: 0.9rem;\n}", + "validations": [ + { + "type": "regex", + "value": "\\.card\\s+p\\s*\\{", + "message": "Verwende .card p { (Leerzeichen zwischen .card und p)" + }, + { + "type": "property_value", + "value": { "property": "font-size", "expected": "0.9rem" }, + "message": "Setze font-size: 0.9rem" } ] } diff --git a/lessons/es/00-basic-selectors.json b/lessons/es/00-basic-selectors.json index 6e55337..32d2462 100644 --- a/lessons/es/00-basic-selectors.json +++ b/lessons/es/00-basic-selectors.json @@ -1,548 +1,257 @@ { "$schema": "../../schemas/code-crispies-module-schema.json", "id": "css-basic-selectors", - "title": "CSS Selectors", - "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.", + "title": "Fundamentos de CSS", + "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", "lessons": [ { - "id": "introduction-to-selectors", - "title": "What's a Selector?", - "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.
For example, to change the text color of elements, you can use the color property within your declaration block.

/* Element selector */\np {\n  color: orangered;\n  /* │       └─── Indicates the value of the expression\n     │                                                     \n     └─────────── Indicates the property of the expression */\n}
", - "task": "Write a CSS rule using a type selector that targets all paragraph elements p in the document. Make the text blue by setting the color property to blue.", - "previewHTML": "

Introduction to CSS Selectors

\n

This paragraph should turn blue.

\n
This div element should remain unchanged.
\n

This second paragraph should also turn blue.

", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "sandboxCSS": "h1, p, div { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }", - "codePrefix": "/* Write a type selector to target all paragraph elements */\n", + "id": "css-properties", + "title": "Propiedades CSS", + "description": "CSS estiliza elementos usando declaraciones - pares de propiedades y valores. Cada declaración sigue el mismo patrón:

property: value;

La propiedad es lo que quieres cambiar (como color o background). El valor es a lo que lo estableces. Dos puntos los separan, y un punto y coma termina la línea.

Los valores vienen en diferentes tipos:
Palabras clave: red, bold, center
Números con unidades: 16px, 2rem, 100%
Colores: steelblue, #ff0000", + "task": "Completa la declaración añadiendo color: coral; para cambiar el color del texto.", + "previewHTML": "

This text should turn coral.

", + "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .text { font-size: 1.25rem; }", + "sandboxCSS": "", + "codePrefix": ".text {\n ", "initialCode": "", - "codeSuffix": "", + "codeSuffix": "\n}", "previewContainer": "preview-area", - "solution": "p { color: blue }", + "solution": "color: coral;", "validations": [ { - "type": "regex", - "value": "^p\\s*{", - "message": "Start your rule with p { … } to select all paragraph elements", - "options": { - "caseSensitive": false - } - }, + "type": "property_value", + "value": { "property": "color", "expected": "coral" }, + "message": "Añade color: coral;" + } + ] + }, + { + "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:

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

El orden normalmente no importa - CSS las aplica todas. Cuando hay conflictos, la última gana.", + "task": "Añade dos declaraciones: background: lavender; y padding: 1rem;", + "previewHTML": "
A styled card with background and padding.
", + "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .card { border-radius: 8px; }", + "sandboxCSS": "", + "codePrefix": ".card {\n ", + "initialCode": "", + "codeSuffix": "\n}", + "previewContainer": "preview-area", + "solution": "background: lavender;\n padding: 1rem;", + "validations": [ { - "type": "contains", - "value": "color:", - "message": "Include the color: property in your CSS rule" - }, - { - "type": "contains", - "value": "blue", - "message": "Set the color value to blue" + "type": "property_value", + "value": { "property": "background", "expected": "lavender" }, + "message": "Añade background: lavender;" }, { "type": "property_value", - "value": { - "property": "color", - "expected": "blue" - }, - "message": "Use color: blue to set the text color" - }, - { - "type": "regex", - "value": "p\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "options": { - "caseSensitive": false - } + "value": { "property": "padding", "expected": "1rem" }, + "message": "Añade padding: 1rem;" } ] }, { "id": "type-selectors", - "title": "Type Selectors", - "description": "Type selectors (also called tag name selectors or element selectors) target HTML elements based on their tag name. For example, p selects all paragraph elements, h1 selects all level-one headings, and div 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 color for text color, background-color for the background, and font-weight 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.", - "task": "Write three separate CSS rules using type selectors to target specific HTML elements: make h2 headings purple, give span elements a yellow background, and make strong elements red.", - "previewHTML": "

Type Selectors Example

\n

Regular paragraph text with a highlighted span that should have a yellow background.

\n

Another paragraph with strong important text that should be red.

\n

Another Heading

", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "sandboxCSS": "h2, p, span, strong { padding: 3px; }", - "codePrefix": "/* Write three separate type selectors below */\n\n", - "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", + "title": "Selectores de tipo", + "description": "Un selector le dice al navegador qué elementos estilizar. El selector más simple es un selector de tipo — simplemente el nombre de la etiqueta HTML.

p {
color: steelblue;
}

Esta regla apunta a cada elemento <p> en la página. Los selectores de tipo son geniales para establecer estilos base.", + "task": "Estiliza todos los párrafos. Escribe una regla con p como selector y establece color: steelblue.", + "previewHTML": "
\n

Fresh Roasted Coffee

\n

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

\n

Each batch is roasted weekly to ensure peak freshness.

\n
", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } h2 { margin: 0 0 1rem; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", - "solution": "/* 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": [ { "type": "regex", - "value": "^h2\\s*{", - "message": "Include an h2 { … } selector" + "value": "p\\s*\\{", + "message": "Empieza con p { para seleccionar párrafos" }, { "type": "property_value", - "value": { - "property": "color", - "expected": "purple" - }, - "message": "Set the color property to purple for h2 elements" - }, + "value": { "property": "color", "expected": "steelblue" }, + "message": "Establece color: steelblue" + } + ] + }, + { + "id": "styling-links", + "title": "Estilizando enlaces", + "description": "Los selectores de tipo funcionan para cualquier elemento HTML. El selector a apunta a todos los enlaces de una página.

Los enlaces tienen un color azul y subrayado por defecto. Puedes cambiar ambos con CSS — usa color para el texto y text-decoration: none para quitar el subrayado.", + "task": "Estiliza los enlaces de navegación. Escribe una regla con a como selector y establece color: coral.", + "previewHTML": "", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } nav { display: flex; gap: 1.5rem; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", + "codeSuffix": "", + "previewContainer": "preview-area", + "solution": "a {\n color: coral;\n}", + "validations": [ { "type": "regex", - "value": "h2\\s*{[^}]*}", - "message": "Make sure to close your h2 rule with a closing brace }" - }, - { - "type": "regex", - "value": "^span\\s*{", - "message": "Include a span { … } selector" + "value": "a\\s*\\{", + "message": "Empieza con a { para seleccionar enlaces" }, { "type": "property_value", - "value": { - "property": "background-color", - "expected": "yellow" - }, - "message": "Set a background-color: yellow for span elements" - }, - { - "type": "regex", - "value": "span\\s*{[^}]*}", - "message": "Make sure to close your span rule with a closing brace }" - }, - { - "type": "regex", - "value": "^strong\\s*{", - "message": "Include a strong { … } selector" - }, - { - "type": "regex", - "value": "strong\\s*{\\s*color:\\s*red;[^}]*}", - "message": "Set the color: red for strong elements" + "value": { "property": "color", "expected": "coral" }, + "message": "Establece color: coral" } ] }, { "id": "class-selectors", - "title": "Class Selectors", - "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 background-color to set the background color of elements, and font-weight 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.", - "task": "Create a CSS rule using a class selector that targets elements with the class highlight. Give these elements a yellow background and bold text.", - "previewHTML": "

Using Class Selectors

\n

This is a regular paragraph, but this span has the highlight class applied to it.

\n

This entire paragraph has the highlight class.

\n", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "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 .highlight { … } to create a class selector", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "background-color:", - "message": "Include the background-color: property" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "yellow" - }, - "message": "Set the background color to yellow" - }, - { - "type": "contains", - "value": "font-weight:", - "message": "Include the font-weight: property" - }, - { - "type": "property_value", - "value": { - "property": "font-weight", - "expected": "bold" - }, - "message": "Set the font-weight to bold" - }, - { - "type": "regex", - "value": "\\.highlight\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "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., .class1.class2). When styling these elements, you might use properties like border-color to change the color of element borders, and background-color 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 card and featured classes by chaining the selectors. Set the border-color to gold and the background-color to lemonchiffon to make featured cards stand out.", - "previewHTML": "

Multiple Class Combinations

\n
Regular Card
\n
Featured Card
\n
Just Featured (not a card)
", - "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; }", + "title": "Selectores de clase", + "description": "Los selectores de tipo estilizan todos los elementos de ese tipo. ¿Pero qué si quieres estilizar solo algunos de ellos?

Los selectores de clase apuntan a elementos con un atributo class específico. Empiezan con un punto:

.badge {
background: coral;
}

Esto estiliza solo elementos con class=\"badge\".", + "task": "Estiliza el badge de notificación. Escribe una regla con .badge como selector y establece background: tomato.", + "previewHTML": "
\n

Dashboard

\n 3\n
\n

You have new notifications waiting.

", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } header { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; } h1 { margin: 0; font-size: 1.5rem; } .badge { color: white; padding: 0.25rem 0.5rem; border-radius: 999px; font-size: 0.875rem; } p { color: #555; margin: 0; }", "sandboxCSS": "", - "codePrefix": "/* The .card class already has basic styling */\n/* Now target elements with BOTH classes: 'card' AND 'featured' */\n", + "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", - "solution": ".card.featured { border-color: gold; background-color: lemonchiffon }", + "solution": ".badge {\n background: tomato;\n}", "validations": [ { "type": "regex", - "value": "^\\.card\\.featured\\s*{", - "message": "Chain the selectors as .card.featured (no space between them)", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "border-color:", - "message": "Include the border-color property" + "value": "\\.badge\\s*\\{", + "message": "Empieza con .badge { (¡no olvides el punto!)" }, { "type": "property_value", - "value": { - "property": "border-color", - "expected": "gold" - }, - "message": "Set the border color to gold" - }, - { - "type": "regex", - "value": "\\.card\\.featured\\s*{[^}]*;", - "message": "Make sure to end your CSS rule with a semicolon ;" - }, - { - "type": "contains", - "value": "background-color:", - "message": "Include the background-color property" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "lemonchiffon" - }, - "message": "Set the background color to lemonchiffon" - }, - { - "type": "regex", - "value": "\\.card\\.featured\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "options": { - "caseSensitive": true - } + "value": { "property": "background", "expected": "tomato" }, + "message": "Establece background: tomato" } ] }, { - "id": "class-with-type", - "title": "Combining Types", - "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, p.note would select paragraph elements with the class note, but would not select divs or spans with that same class. You can style these combined selections using properties like background-color 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.", - "task": "Create a CSS rule that specifically targets <span> elements with the class highlight. Make those elements have an orange background, while other elements with the highlight class remain untouched.", - "previewHTML": "

Type and Class Combinations

\n

This paragraph has a highlighted span that should have an orange background.

\n

This paragraph has the highlight class but should NOT have an orange background.

", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } .highlight { font-weight: bold; }", - "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 span.highlight selector (no space between element and class)", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "background-color:", - "message": "Include the background-color property" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "orange" - }, - "message": "Set the background color to orange" - }, - { - "type": "regex", - "value": "span\\.highlight\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "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 color to define text color, and text-decoration 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 main-title. Set its color to purple and add an underline with text-decoration: underline.", - "previewHTML": "

Main Page Title

\n

Regular paragraph content.

\n

Secondary Heading

\n

Introduction paragraph (different ID).

", - "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 #main-title to create an ID selector", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "color:", - "message": "Include the color property" - }, - { - "type": "property_value", - "value": { - "property": "color", - "expected": "purple" - }, - "message": "Set the color to purple" - }, - { - "type": "contains", - "value": "text-decoration:", - "message": "Include the text-decoration property" - }, - { - "type": "property_value", - "value": { - "property": "text-decoration", - "expected": "underline" - }, - "message": "Set the text-decoration to underline" - }, - { - "type": "regex", - "value": "#main-title\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "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, h1#title targets an h1 element with the ID 'title'. When using this combined approach, you can apply CSS properties like font-style 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 special. Set its font style to italic.", - "previewHTML": "

Heading with ID \"special\" (should NOT be affected)

\n

Paragraph with ID \"special\" (should become italic)

", - "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 p#special to target paragraphs with ID special", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "font-style:", - "message": "Include the font-style property" - }, - { - "type": "property_value", - "value": { - "property": "font-style", - "expected": "italic" - }, - "message": "Set the font-style to italic" - }, - { - "type": "regex", - "value": "p#special\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "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, h1, h2, h3 { color: blue; } applies the same blue color to all three heading levels. When styling multiple selectors at once, you can apply properties like background-color to set the background, border-left to create a left border with a specific thickness, style, and color, and padding-left 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 note, list items with class important, and the element with ID summary. Give them a lightyellow background, a gold left border, and some left padding.", - "previewHTML": "

This is a note paragraph.

\n\n
Summary section
", - "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 p.note in your selector list", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "li.important", - "message": "Include li.important in your selector list", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "#summary", - "message": "Include #summary 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 background-color property" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "lightyellow" - }, - "message": "Set the background color to lightyellow" - }, - { - "type": "contains", - "value": "border-left:", - "message": "Include the border-left property" - }, - { - "type": "property_value", - "value": { - "property": "border-left", - "expected": "3px solid gold" - }, - "message": "Use border-left: 3px solid gold to create a left border" - }, - { - "type": "contains", - "value": "padding-left:", - "message": "Include the padding-left property" - }, - { - "type": "property_value", - "value": { - "property": "padding-left", - "expected": "10px" - }, - "message": "Use padding-left: 10px 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, * { margin: 0; } removes margins from all elements, while article * selects all elements inside article elements. When using the universal selector in combination with other selectors, you can apply properties like margin 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 div.container * as the selector and set margin: 0.", - "previewHTML": "
\n

Inside Container

\n

This paragraph is inside the container.

\n \n
\n

This paragraph is outside the container and should not be affected.

", - "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; }", + "id": "button-variants", + "title": "Variantes de botón", + "description": "Los elementos pueden tener múltiples clases. Cuando encadenas selectores de clase sin espacios, apuntas a elementos que tienen todas esas clases:

.btn.primary {
background: steelblue;
}

Esto apunta a elementos con class=\"btn primary\", no solo .btn o solo .primary.", + "task": "Estiliza el botón primario. Escribe una regla con .btn.primary como selector y establece background: steelblue.", + "previewHTML": "
\n \n \n
", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } .actions { display: flex; gap: 0.75rem; } .btn { padding: 0.5rem 1rem; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; background: #e0e0e0; color: #333; }", "sandboxCSS": "", - "codePrefix": "/* Use the universal selector to target all elements inside the container */\n", + "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", + "solution": ".btn.primary {\n background: steelblue;\n}", "validations": [ { "type": "regex", - "value": "^div\\.container\\s+\\*\\s*{", - "message": "Use div.container * selector (with a space between container and *)", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "margin:", - "message": "Include the margin property" + "value": "\\.btn\\.primary\\s*\\{", + "message": "Usa .btn.primary { (sin espacio entre clases)" }, { "type": "property_value", - "value": { - "property": "margin", - "expected": "0" - }, - "message": "Set margin to 0" - }, - { - "type": "regex", - "value": "div\\.container\\s+\\*\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "options": { - "caseSensitive": true - } + "value": { "property": "background", "expected": "steelblue" }, + "message": "Establece background: steelblue" } ] }, { - "id": "specificity-basics", - "title": "Specificity", - "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 color 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.", - "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.", - "previewHTML": "
\n

What color will this paragraph be? Look at the CSS rules and their specificity.

\n
", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "sandboxCSS": "p { border: 1px dashed gray; padding: 10px; }", - "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", + "id": "specific-elements", + "title": "Apuntando a elementos específicos", + "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:

a.btn {
text-decoration: none;
}

Esto estiliza solo elementos <a> con la clase btn, no elementos <button> con esa clase.", + "task": "Quita el subrayado de los botones-enlace. Escribe una regla con a.btn como selector y establece text-decoration: none.", + "previewHTML": "
\n \n Link Button\n
", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } .actions { display: flex; gap: 0.75rem; align-items: center; } .btn { padding: 0.5rem 1rem; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; background: steelblue; color: white; }", + "sandboxCSS": "", + "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", + "solution": "a.btn {\n text-decoration: none;\n}", "validations": [ { "type": "regex", - "value": "^\\.content\\s+p\\s*{", - "message": "Use .content p as your selector (note the space between)", - "options": { - "caseSensitive": true - } + "value": "a\\.btn\\s*\\{", + "message": "Usa a.btn { (tipo + clase, sin espacio)" }, { - "type": "contains", - "value": "color:", - "message": "Include the color property" + "type": "property_value", + "value": { "property": "text-decoration", "expected": "none" }, + "message": "Establece text-decoration: none" + } + ] + }, + { + "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.

h1, h2, h3 {
color: steelblue;
}

Esto aplica el mismo color a los tres niveles de encabezado en una regla.", + "task": "Estiliza todos los encabezados consistentemente. Añade color: steelblue al selector agrupado h1, h2, h3.", + "previewHTML": "

Main Title

Introduction paragraph with some text.

Section Heading

More content here.

Subsection

Final paragraph.

", + "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } article { max-width: 500px; } p { color: #555; line-height: 1.6; }", + "sandboxCSS": "", + "codePrefix": "h1, h2, h3 {\n ", + "initialCode": "", + "codeSuffix": "\n}", + "previewContainer": "preview-area", + "solution": "color: steelblue;", + "validations": [ + { + "type": "property_value", + "value": { "property": "color", "expected": "steelblue" }, + "message": "Establece color: steelblue" + } + ] + }, + { + "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.

.nav a {
color: white;
}

Esto estiliza solo enlaces dentro de .nav, dejando otros enlaces sin cambios.", + "task": "Estiliza los enlaces de navegación diferente. Escribe una regla con .nav a como selector y establece color: white.", + "previewHTML": "

Read more in our documentation.

", + "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; margin: 0; } .nav { background: steelblue; padding: 1rem; display: flex; gap: 1rem; border-radius: 8px; margin-bottom: 1rem; } .nav a { text-decoration: none; } p a { color: steelblue; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", + "codeSuffix": "", + "previewContainer": "preview-area", + "solution": ".nav a {\n color: white;\n}", + "validations": [ + { + "type": "regex", + "value": "\\.nav\\s+a\\s*\\{", + "message": "Usa .nav a { (espacio entre .nav y a)" }, { - "type": "contains", - "value": "green", - "message": "" + "type": "property_value", + "value": { "property": "color", "expected": "white" }, + "message": "Establece color: white" + } + ] + }, + { + "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.

Por ejemplo, los párrafos en una .card podrían ser más pequeños que los párrafos en un article.", + "task": "Haz los párrafos dentro de la tarjeta más pequeños. Escribe una regla con .card p como selector y establece font-size: 0.9rem.", + "previewHTML": "

Article Title

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

Quick Tip

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

Back to regular article text here.

", + "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } article { max-width: 500px; } h2 { color: steelblue; margin-top: 0; } p { line-height: 1.6; color: #444; } .card { background: #f0f4f8; padding: 1rem; border-radius: 8px; border-left: 4px solid steelblue; } .card strong { color: steelblue; display: block; margin-bottom: 0.5rem; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", + "codeSuffix": "", + "previewContainer": "preview-area", + "solution": ".card p {\n font-size: 0.9rem;\n}", + "validations": [ + { + "type": "regex", + "value": "\\.card\\s+p\\s*\\{", + "message": "Usa .card p { (espacio entre .card y p)" + }, + { + "type": "property_value", + "value": { "property": "font-size", "expected": "0.9rem" }, + "message": "Establece font-size: 0.9rem" } ] } diff --git a/lessons/pl/00-basic-selectors.json b/lessons/pl/00-basic-selectors.json index 6e55337..5c43a8f 100644 --- a/lessons/pl/00-basic-selectors.json +++ b/lessons/pl/00-basic-selectors.json @@ -1,548 +1,257 @@ { "$schema": "../../schemas/code-crispies-module-schema.json", "id": "css-basic-selectors", - "title": "CSS Selectors", - "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.", + "title": "Podstawy CSS", + "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", "lessons": [ { - "id": "introduction-to-selectors", - "title": "What's a Selector?", - "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.
For example, to change the text color of elements, you can use the color property within your declaration block.

/* Element selector */\np {\n  color: orangered;\n  /* │       └─── Indicates the value of the expression\n     │                                                     \n     └─────────── Indicates the property of the expression */\n}
", - "task": "Write a CSS rule using a type selector that targets all paragraph elements p in the document. Make the text blue by setting the color property to blue.", - "previewHTML": "

Introduction to CSS Selectors

\n

This paragraph should turn blue.

\n
This div element should remain unchanged.
\n

This second paragraph should also turn blue.

", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "sandboxCSS": "h1, p, div { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }", - "codePrefix": "/* Write a type selector to target all paragraph elements */\n", + "id": "css-properties", + "title": "Właściwości CSS", + "description": "CSS stylizuje elementy za pomocą deklaracji - par właściwości i wartości. Każda deklaracja ma ten sam wzorzec:

property: value;

Właściwość to co chcesz zmienić (jak color lub background). Wartość to na co to ustawiasz. Dwukropek je rozdziela, a średnik kończy linię.

Wartości występują w różnych typach:
Słowa kluczowe: red, bold, center
Liczby z jednostkami: 16px, 2rem, 100%
Kolory: steelblue, #ff0000", + "task": "Uzupełnij deklarację dodając color: coral; aby zmienić kolor tekstu.", + "previewHTML": "

This text should turn coral.

", + "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .text { font-size: 1.25rem; }", + "sandboxCSS": "", + "codePrefix": ".text {\n ", "initialCode": "", - "codeSuffix": "", + "codeSuffix": "\n}", "previewContainer": "preview-area", - "solution": "p { color: blue }", + "solution": "color: coral;", "validations": [ { - "type": "regex", - "value": "^p\\s*{", - "message": "Start your rule with p { … } to select all paragraph elements", - "options": { - "caseSensitive": false - } - }, + "type": "property_value", + "value": { "property": "color", "expected": "coral" }, + "message": "Dodaj color: coral;" + } + ] + }, + { + "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:

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

Kolejność zwykle nie ma znaczenia - CSS stosuje wszystkie. Przy konfliktach wygrywa ostatnia.", + "task": "Dodaj dwie deklaracje: background: lavender; i padding: 1rem;", + "previewHTML": "
A styled card with background and padding.
", + "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .card { border-radius: 8px; }", + "sandboxCSS": "", + "codePrefix": ".card {\n ", + "initialCode": "", + "codeSuffix": "\n}", + "previewContainer": "preview-area", + "solution": "background: lavender;\n padding: 1rem;", + "validations": [ { - "type": "contains", - "value": "color:", - "message": "Include the color: property in your CSS rule" - }, - { - "type": "contains", - "value": "blue", - "message": "Set the color value to blue" + "type": "property_value", + "value": { "property": "background", "expected": "lavender" }, + "message": "Dodaj background: lavender;" }, { "type": "property_value", - "value": { - "property": "color", - "expected": "blue" - }, - "message": "Use color: blue to set the text color" - }, - { - "type": "regex", - "value": "p\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "options": { - "caseSensitive": false - } + "value": { "property": "padding", "expected": "1rem" }, + "message": "Dodaj padding: 1rem;" } ] }, { "id": "type-selectors", - "title": "Type Selectors", - "description": "Type selectors (also called tag name selectors or element selectors) target HTML elements based on their tag name. For example, p selects all paragraph elements, h1 selects all level-one headings, and div 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 color for text color, background-color for the background, and font-weight 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.", - "task": "Write three separate CSS rules using type selectors to target specific HTML elements: make h2 headings purple, give span elements a yellow background, and make strong elements red.", - "previewHTML": "

Type Selectors Example

\n

Regular paragraph text with a highlighted span that should have a yellow background.

\n

Another paragraph with strong important text that should be red.

\n

Another Heading

", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "sandboxCSS": "h2, p, span, strong { padding: 3px; }", - "codePrefix": "/* Write three separate type selectors below */\n\n", - "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", + "title": "Selektory typu", + "description": "Selektor mówi przeglądarce, które elementy stylizować. Najprostszym selektorem jest selektor typu — po prostu nazwa tagu HTML.

p {
color: steelblue;
}

Ta reguła celuje w każdy element <p> na stronie. Selektory typu świetnie nadają się do ustawiania podstawowych stylów.", + "task": "Ostyluj wszystkie akapity. Napisz regułę z p jako selektorem i ustaw color: steelblue.", + "previewHTML": "
\n

Fresh Roasted Coffee

\n

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

\n

Each batch is roasted weekly to ensure peak freshness.

\n
", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } h2 { margin: 0 0 1rem; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", - "solution": "/* 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": [ { "type": "regex", - "value": "^h2\\s*{", - "message": "Include an h2 { … } selector" + "value": "p\\s*\\{", + "message": "Zacznij od p { aby wybrać akapity" }, { "type": "property_value", - "value": { - "property": "color", - "expected": "purple" - }, - "message": "Set the color property to purple for h2 elements" - }, + "value": { "property": "color", "expected": "steelblue" }, + "message": "Ustaw color: steelblue" + } + ] + }, + { + "id": "styling-links", + "title": "Stylizowanie linków", + "description": "Selektory typu działają dla każdego elementu HTML. Selektor a celuje we wszystkie linki na stronie.

Linki domyślnie mają niebieski kolor i podkreślenie. Możesz zmienić oba z CSS — użyj color dla tekstu i text-decoration: none aby usunąć podkreślenie.", + "task": "Ostyluj linki nawigacji. Napisz regułę z a jako selektorem i ustaw color: coral.", + "previewHTML": "", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } nav { display: flex; gap: 1.5rem; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", + "codeSuffix": "", + "previewContainer": "preview-area", + "solution": "a {\n color: coral;\n}", + "validations": [ { "type": "regex", - "value": "h2\\s*{[^}]*}", - "message": "Make sure to close your h2 rule with a closing brace }" - }, - { - "type": "regex", - "value": "^span\\s*{", - "message": "Include a span { … } selector" + "value": "a\\s*\\{", + "message": "Zacznij od a { aby wybrać linki" }, { "type": "property_value", - "value": { - "property": "background-color", - "expected": "yellow" - }, - "message": "Set a background-color: yellow for span elements" - }, - { - "type": "regex", - "value": "span\\s*{[^}]*}", - "message": "Make sure to close your span rule with a closing brace }" - }, - { - "type": "regex", - "value": "^strong\\s*{", - "message": "Include a strong { … } selector" - }, - { - "type": "regex", - "value": "strong\\s*{\\s*color:\\s*red;[^}]*}", - "message": "Set the color: red for strong elements" + "value": { "property": "color", "expected": "coral" }, + "message": "Ustaw color: coral" } ] }, { "id": "class-selectors", - "title": "Class Selectors", - "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 background-color to set the background color of elements, and font-weight 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.", - "task": "Create a CSS rule using a class selector that targets elements with the class highlight. Give these elements a yellow background and bold text.", - "previewHTML": "

Using Class Selectors

\n

This is a regular paragraph, but this span has the highlight class applied to it.

\n

This entire paragraph has the highlight class.

\n", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "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 .highlight { … } to create a class selector", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "background-color:", - "message": "Include the background-color: property" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "yellow" - }, - "message": "Set the background color to yellow" - }, - { - "type": "contains", - "value": "font-weight:", - "message": "Include the font-weight: property" - }, - { - "type": "property_value", - "value": { - "property": "font-weight", - "expected": "bold" - }, - "message": "Set the font-weight to bold" - }, - { - "type": "regex", - "value": "\\.highlight\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "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., .class1.class2). When styling these elements, you might use properties like border-color to change the color of element borders, and background-color 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 card and featured classes by chaining the selectors. Set the border-color to gold and the background-color to lemonchiffon to make featured cards stand out.", - "previewHTML": "

Multiple Class Combinations

\n
Regular Card
\n
Featured Card
\n
Just Featured (not a card)
", - "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; }", + "title": "Selektory klas", + "description": "Selektory typu stylizują wszystkie elementy danego typu. Ale co jeśli chcesz ostylować tylko niektóre z nich?

Selektory klas celują w elementy z określonym atrybutem class. Zaczynają się od kropki:

.badge {
background: coral;
}

To stylizuje tylko elementy z class=\"badge\".", + "task": "Ostyluj badge powiadomień. Napisz regułę z .badge jako selektorem i ustaw background: tomato.", + "previewHTML": "
\n

Dashboard

\n 3\n
\n

You have new notifications waiting.

", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } header { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; } h1 { margin: 0; font-size: 1.5rem; } .badge { color: white; padding: 0.25rem 0.5rem; border-radius: 999px; font-size: 0.875rem; } p { color: #555; margin: 0; }", "sandboxCSS": "", - "codePrefix": "/* The .card class already has basic styling */\n/* Now target elements with BOTH classes: 'card' AND 'featured' */\n", + "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", - "solution": ".card.featured { border-color: gold; background-color: lemonchiffon }", + "solution": ".badge {\n background: tomato;\n}", "validations": [ { "type": "regex", - "value": "^\\.card\\.featured\\s*{", - "message": "Chain the selectors as .card.featured (no space between them)", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "border-color:", - "message": "Include the border-color property" + "value": "\\.badge\\s*\\{", + "message": "Zacznij od .badge { (nie zapomnij o kropce!)" }, { "type": "property_value", - "value": { - "property": "border-color", - "expected": "gold" - }, - "message": "Set the border color to gold" - }, - { - "type": "regex", - "value": "\\.card\\.featured\\s*{[^}]*;", - "message": "Make sure to end your CSS rule with a semicolon ;" - }, - { - "type": "contains", - "value": "background-color:", - "message": "Include the background-color property" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "lemonchiffon" - }, - "message": "Set the background color to lemonchiffon" - }, - { - "type": "regex", - "value": "\\.card\\.featured\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "options": { - "caseSensitive": true - } + "value": { "property": "background", "expected": "tomato" }, + "message": "Ustaw background: tomato" } ] }, { - "id": "class-with-type", - "title": "Combining Types", - "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, p.note would select paragraph elements with the class note, but would not select divs or spans with that same class. You can style these combined selections using properties like background-color 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.", - "task": "Create a CSS rule that specifically targets <span> elements with the class highlight. Make those elements have an orange background, while other elements with the highlight class remain untouched.", - "previewHTML": "

Type and Class Combinations

\n

This paragraph has a highlighted span that should have an orange background.

\n

This paragraph has the highlight class but should NOT have an orange background.

", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } .highlight { font-weight: bold; }", - "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 span.highlight selector (no space between element and class)", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "background-color:", - "message": "Include the background-color property" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "orange" - }, - "message": "Set the background color to orange" - }, - { - "type": "regex", - "value": "span\\.highlight\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "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 color to define text color, and text-decoration 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 main-title. Set its color to purple and add an underline with text-decoration: underline.", - "previewHTML": "

Main Page Title

\n

Regular paragraph content.

\n

Secondary Heading

\n

Introduction paragraph (different ID).

", - "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 #main-title to create an ID selector", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "color:", - "message": "Include the color property" - }, - { - "type": "property_value", - "value": { - "property": "color", - "expected": "purple" - }, - "message": "Set the color to purple" - }, - { - "type": "contains", - "value": "text-decoration:", - "message": "Include the text-decoration property" - }, - { - "type": "property_value", - "value": { - "property": "text-decoration", - "expected": "underline" - }, - "message": "Set the text-decoration to underline" - }, - { - "type": "regex", - "value": "#main-title\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "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, h1#title targets an h1 element with the ID 'title'. When using this combined approach, you can apply CSS properties like font-style 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 special. Set its font style to italic.", - "previewHTML": "

Heading with ID \"special\" (should NOT be affected)

\n

Paragraph with ID \"special\" (should become italic)

", - "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 p#special to target paragraphs with ID special", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "font-style:", - "message": "Include the font-style property" - }, - { - "type": "property_value", - "value": { - "property": "font-style", - "expected": "italic" - }, - "message": "Set the font-style to italic" - }, - { - "type": "regex", - "value": "p#special\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "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, h1, h2, h3 { color: blue; } applies the same blue color to all three heading levels. When styling multiple selectors at once, you can apply properties like background-color to set the background, border-left to create a left border with a specific thickness, style, and color, and padding-left 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 note, list items with class important, and the element with ID summary. Give them a lightyellow background, a gold left border, and some left padding.", - "previewHTML": "

This is a note paragraph.

\n\n
Summary section
", - "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 p.note in your selector list", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "li.important", - "message": "Include li.important in your selector list", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "#summary", - "message": "Include #summary 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 background-color property" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "lightyellow" - }, - "message": "Set the background color to lightyellow" - }, - { - "type": "contains", - "value": "border-left:", - "message": "Include the border-left property" - }, - { - "type": "property_value", - "value": { - "property": "border-left", - "expected": "3px solid gold" - }, - "message": "Use border-left: 3px solid gold to create a left border" - }, - { - "type": "contains", - "value": "padding-left:", - "message": "Include the padding-left property" - }, - { - "type": "property_value", - "value": { - "property": "padding-left", - "expected": "10px" - }, - "message": "Use padding-left: 10px 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, * { margin: 0; } removes margins from all elements, while article * selects all elements inside article elements. When using the universal selector in combination with other selectors, you can apply properties like margin 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 div.container * as the selector and set margin: 0.", - "previewHTML": "
\n

Inside Container

\n

This paragraph is inside the container.

\n \n
\n

This paragraph is outside the container and should not be affected.

", - "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; }", + "id": "button-variants", + "title": "Warianty przycisków", + "description": "Elementy mogą mieć wiele klas. Gdy łączysz selektory klas bez spacji, celujesz w elementy które mają wszystkie te klasy:

.btn.primary {
background: steelblue;
}

To celuje w elementy z class=\"btn primary\", nie tylko .btn lub tylko .primary.", + "task": "Ostyluj główny przycisk. Napisz regułę z .btn.primary jako selektorem i ustaw background: steelblue.", + "previewHTML": "
\n \n \n
", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } .actions { display: flex; gap: 0.75rem; } .btn { padding: 0.5rem 1rem; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; background: #e0e0e0; color: #333; }", "sandboxCSS": "", - "codePrefix": "/* Use the universal selector to target all elements inside the container */\n", + "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", + "solution": ".btn.primary {\n background: steelblue;\n}", "validations": [ { "type": "regex", - "value": "^div\\.container\\s+\\*\\s*{", - "message": "Use div.container * selector (with a space between container and *)", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "margin:", - "message": "Include the margin property" + "value": "\\.btn\\.primary\\s*\\{", + "message": "Użyj .btn.primary { (bez spacji między klasami)" }, { "type": "property_value", - "value": { - "property": "margin", - "expected": "0" - }, - "message": "Set margin to 0" - }, - { - "type": "regex", - "value": "div\\.container\\s+\\*\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "options": { - "caseSensitive": true - } + "value": { "property": "background", "expected": "steelblue" }, + "message": "Ustaw background: steelblue" } ] }, { - "id": "specificity-basics", - "title": "Specificity", - "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 color 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.", - "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.", - "previewHTML": "
\n

What color will this paragraph be? Look at the CSS rules and their specificity.

\n
", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "sandboxCSS": "p { border: 1px dashed gray; padding: 10px; }", - "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", + "id": "specific-elements", + "title": "Celowanie w konkretne elementy", + "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:

a.btn {
text-decoration: none;
}

To stylizuje tylko elementy <a> z klasą btn, nie elementy <button> z tą klasą.", + "task": "Usuń podkreślenie z przycisków-linków. Napisz regułę z a.btn jako selektorem i ustaw text-decoration: none.", + "previewHTML": "
\n \n Link Button\n
", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } .actions { display: flex; gap: 0.75rem; align-items: center; } .btn { padding: 0.5rem 1rem; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; background: steelblue; color: white; }", + "sandboxCSS": "", + "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", + "solution": "a.btn {\n text-decoration: none;\n}", "validations": [ { "type": "regex", - "value": "^\\.content\\s+p\\s*{", - "message": "Use .content p as your selector (note the space between)", - "options": { - "caseSensitive": true - } + "value": "a\\.btn\\s*\\{", + "message": "Użyj a.btn { (typ + klasa, bez spacji)" }, { - "type": "contains", - "value": "color:", - "message": "Include the color property" + "type": "property_value", + "value": { "property": "text-decoration", "expected": "none" }, + "message": "Ustaw text-decoration: none" + } + ] + }, + { + "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.

h1, h2, h3 {
color: steelblue;
}

To stosuje ten sam kolor do wszystkich trzech poziomów nagłówków w jednej regule.", + "task": "Ostyluj wszystkie nagłówki jednolicie. Dodaj color: steelblue do zgrupowanego selektora h1, h2, h3.", + "previewHTML": "

Main Title

Introduction paragraph with some text.

Section Heading

More content here.

Subsection

Final paragraph.

", + "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } article { max-width: 500px; } p { color: #555; line-height: 1.6; }", + "sandboxCSS": "", + "codePrefix": "h1, h2, h3 {\n ", + "initialCode": "", + "codeSuffix": "\n}", + "previewContainer": "preview-area", + "solution": "color: steelblue;", + "validations": [ + { + "type": "property_value", + "value": { "property": "color", "expected": "steelblue" }, + "message": "Ustaw color: steelblue" + } + ] + }, + { + "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.

.nav a {
color: white;
}

To stylizuje tylko linki wewnątrz .nav, pozostawiając inne linki bez zmian.", + "task": "Ostyluj linki nawigacji inaczej. Napisz regułę z .nav a jako selektorem i ustaw color: white.", + "previewHTML": "

Read more in our documentation.

", + "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; margin: 0; } .nav { background: steelblue; padding: 1rem; display: flex; gap: 1rem; border-radius: 8px; margin-bottom: 1rem; } .nav a { text-decoration: none; } p a { color: steelblue; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", + "codeSuffix": "", + "previewContainer": "preview-area", + "solution": ".nav a {\n color: white;\n}", + "validations": [ + { + "type": "regex", + "value": "\\.nav\\s+a\\s*\\{", + "message": "Użyj .nav a { (spacja między .nav a a)" }, { - "type": "contains", - "value": "green", - "message": "" + "type": "property_value", + "value": { "property": "color", "expected": "white" }, + "message": "Ustaw color: white" + } + ] + }, + { + "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.

Na przykład, akapity w .card mogą być mniejsze niż akapity w article.", + "task": "Zmniejsz akapity wewnątrz karty. Napisz regułę z .card p jako selektorem i ustaw font-size: 0.9rem.", + "previewHTML": "

Article Title

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

Quick Tip

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

Back to regular article text here.

", + "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } article { max-width: 500px; } h2 { color: steelblue; margin-top: 0; } p { line-height: 1.6; color: #444; } .card { background: #f0f4f8; padding: 1rem; border-radius: 8px; border-left: 4px solid steelblue; } .card strong { color: steelblue; display: block; margin-bottom: 0.5rem; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", + "codeSuffix": "", + "previewContainer": "preview-area", + "solution": ".card p {\n font-size: 0.9rem;\n}", + "validations": [ + { + "type": "regex", + "value": "\\.card\\s+p\\s*\\{", + "message": "Użyj .card p { (spacja między .card a p)" + }, + { + "type": "property_value", + "value": { "property": "font-size", "expected": "0.9rem" }, + "message": "Ustaw font-size: 0.9rem" } ] } diff --git a/lessons/uk/00-basic-selectors.json b/lessons/uk/00-basic-selectors.json index 6e55337..75b981e 100644 --- a/lessons/uk/00-basic-selectors.json +++ b/lessons/uk/00-basic-selectors.json @@ -1,548 +1,257 @@ { "$schema": "../../schemas/code-crispies-module-schema.json", "id": "css-basic-selectors", - "title": "CSS Selectors", - "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.", + "title": "Основи CSS", + "description": "Вивчіть основні будівельні блоки CSS: властивості, значення та селектори. Цей модуль навчає правилам синтаксису, яких дотримується кожна декларація CSS.", "difficulty": "beginner", "lessons": [ { - "id": "introduction-to-selectors", - "title": "What's a Selector?", - "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.
For example, to change the text color of elements, you can use the color property within your declaration block.

/* Element selector */\np {\n  color: orangered;\n  /* │       └─── Indicates the value of the expression\n     │                                                     \n     └─────────── Indicates the property of the expression */\n}
", - "task": "Write a CSS rule using a type selector that targets all paragraph elements p in the document. Make the text blue by setting the color property to blue.", - "previewHTML": "

Introduction to CSS Selectors

\n

This paragraph should turn blue.

\n
This div element should remain unchanged.
\n

This second paragraph should also turn blue.

", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "sandboxCSS": "h1, p, div { padding: 8px; margin-bottom: 10px; border: 1px dashed #ccc; }", - "codePrefix": "/* Write a type selector to target all paragraph elements */\n", + "id": "css-properties", + "title": "Властивості CSS", + "description": "CSS стилізує елементи за допомогою декларацій - пар властивостей і значень. Кожна декларація має той самий шаблон:

property: value;

Властивість - це те, що ви хочете змінити (як color або background). Значення - це те, на що ви це встановлюєте. Двокрапка їх розділяє, а крапка з комою закінчує рядок.

Значення бувають різних типів:
Ключові слова: red, bold, center
Числа з одиницями: 16px, 2rem, 100%
Кольори: steelblue, #ff0000", + "task": "Завершіть декларацію, додавши color: coral; щоб змінити колір тексту.", + "previewHTML": "

This text should turn coral.

", + "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .text { font-size: 1.25rem; }", + "sandboxCSS": "", + "codePrefix": ".text {\n ", "initialCode": "", - "codeSuffix": "", + "codeSuffix": "\n}", "previewContainer": "preview-area", - "solution": "p { color: blue }", + "solution": "color: coral;", "validations": [ { - "type": "regex", - "value": "^p\\s*{", - "message": "Start your rule with p { … } to select all paragraph elements", - "options": { - "caseSensitive": false - } - }, + "type": "property_value", + "value": { "property": "color", "expected": "coral" }, + "message": "Додайте color: coral;" + } + ] + }, + { + "id": "multiple-properties", + "title": "Кілька властивостей", + "description": "Правило може мати кілька декларацій. Кожна йде в окремому рядку, і кожна потребує крапки з комою в кінці:

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

Порядок зазвичай не має значення - CSS застосовує всі. При конфліктах перемагає остання.", + "task": "Додайте дві декларації: background: lavender; та padding: 1rem;", + "previewHTML": "
A styled card with background and padding.
", + "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .card { border-radius: 8px; }", + "sandboxCSS": "", + "codePrefix": ".card {\n ", + "initialCode": "", + "codeSuffix": "\n}", + "previewContainer": "preview-area", + "solution": "background: lavender;\n padding: 1rem;", + "validations": [ { - "type": "contains", - "value": "color:", - "message": "Include the color: property in your CSS rule" - }, - { - "type": "contains", - "value": "blue", - "message": "Set the color value to blue" + "type": "property_value", + "value": { "property": "background", "expected": "lavender" }, + "message": "Додайте background: lavender;" }, { "type": "property_value", - "value": { - "property": "color", - "expected": "blue" - }, - "message": "Use color: blue to set the text color" - }, - { - "type": "regex", - "value": "p\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "options": { - "caseSensitive": false - } + "value": { "property": "padding", "expected": "1rem" }, + "message": "Додайте padding: 1rem;" } ] }, { "id": "type-selectors", - "title": "Type Selectors", - "description": "Type selectors (also called tag name selectors or element selectors) target HTML elements based on their tag name. For example, p selects all paragraph elements, h1 selects all level-one headings, and div 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 color for text color, background-color for the background, and font-weight 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.", - "task": "Write three separate CSS rules using type selectors to target specific HTML elements: make h2 headings purple, give span elements a yellow background, and make strong elements red.", - "previewHTML": "

Type Selectors Example

\n

Regular paragraph text with a highlighted span that should have a yellow background.

\n

Another paragraph with strong important text that should be red.

\n

Another Heading

", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "sandboxCSS": "h2, p, span, strong { padding: 3px; }", - "codePrefix": "/* Write three separate type selectors below */\n\n", - "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", + "title": "Селектори типу", + "description": "Селектор говорить браузеру, які елементи стилізувати. Найпростіший селектор - це селектор типу — просто назва HTML-тегу.

p {
color: steelblue;
}

Це правило націлюється на кожен елемент <p> на сторінці. Селектори типу чудово підходять для встановлення базових стилів.", + "task": "Стилізуйте всі абзаци. Напишіть правило з p як селектором і встановіть color: steelblue.", + "previewHTML": "
\n

Fresh Roasted Coffee

\n

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

\n

Each batch is roasted weekly to ensure peak freshness.

\n
", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } h2 { margin: 0 0 1rem; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", - "solution": "/* 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": [ { "type": "regex", - "value": "^h2\\s*{", - "message": "Include an h2 { … } selector" + "value": "p\\s*\\{", + "message": "Почніть з p { щоб вибрати абзаци" }, { "type": "property_value", - "value": { - "property": "color", - "expected": "purple" - }, - "message": "Set the color property to purple for h2 elements" - }, + "value": { "property": "color", "expected": "steelblue" }, + "message": "Встановіть color: steelblue" + } + ] + }, + { + "id": "styling-links", + "title": "Стилізація посилань", + "description": "Селектори типу працюють для будь-якого HTML-елемента. Селектор a націлюється на всі посилання на сторінці.

Посилання мають синій колір і підкреслення за замовчуванням. Ви можете змінити обидва з CSS — використовуйте color для тексту і text-decoration: none щоб прибрати підкреслення.", + "task": "Стилізуйте навігаційні посилання. Напишіть правило з a як селектором і встановіть color: coral.", + "previewHTML": "", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } nav { display: flex; gap: 1.5rem; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", + "codeSuffix": "", + "previewContainer": "preview-area", + "solution": "a {\n color: coral;\n}", + "validations": [ { "type": "regex", - "value": "h2\\s*{[^}]*}", - "message": "Make sure to close your h2 rule with a closing brace }" - }, - { - "type": "regex", - "value": "^span\\s*{", - "message": "Include a span { … } selector" + "value": "a\\s*\\{", + "message": "Почніть з a { щоб вибрати посилання" }, { "type": "property_value", - "value": { - "property": "background-color", - "expected": "yellow" - }, - "message": "Set a background-color: yellow for span elements" - }, - { - "type": "regex", - "value": "span\\s*{[^}]*}", - "message": "Make sure to close your span rule with a closing brace }" - }, - { - "type": "regex", - "value": "^strong\\s*{", - "message": "Include a strong { … } selector" - }, - { - "type": "regex", - "value": "strong\\s*{\\s*color:\\s*red;[^}]*}", - "message": "Set the color: red for strong elements" + "value": { "property": "color", "expected": "coral" }, + "message": "Встановіть color: coral" } ] }, { "id": "class-selectors", - "title": "Class Selectors", - "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 background-color to set the background color of elements, and font-weight 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.", - "task": "Create a CSS rule using a class selector that targets elements with the class highlight. Give these elements a yellow background and bold text.", - "previewHTML": "

Using Class Selectors

\n

This is a regular paragraph, but this span has the highlight class applied to it.

\n

This entire paragraph has the highlight class.

\n", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "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 .highlight { … } to create a class selector", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "background-color:", - "message": "Include the background-color: property" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "yellow" - }, - "message": "Set the background color to yellow" - }, - { - "type": "contains", - "value": "font-weight:", - "message": "Include the font-weight: property" - }, - { - "type": "property_value", - "value": { - "property": "font-weight", - "expected": "bold" - }, - "message": "Set the font-weight to bold" - }, - { - "type": "regex", - "value": "\\.highlight\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "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., .class1.class2). When styling these elements, you might use properties like border-color to change the color of element borders, and background-color 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 card and featured classes by chaining the selectors. Set the border-color to gold and the background-color to lemonchiffon to make featured cards stand out.", - "previewHTML": "

Multiple Class Combinations

\n
Regular Card
\n
Featured Card
\n
Just Featured (not a card)
", - "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; }", + "title": "Селектори класів", + "description": "Селектори типу стилізують усі елементи цього типу. Але що якщо ви хочете стилізувати лише деякі з них?

Селектори класів націлюються на елементи з певним атрибутом class. Вони починаються з крапки:

.badge {
background: coral;
}

Це стилізує лише елементи з class=\"badge\".", + "task": "Стилізуйте значок сповіщень. Напишіть правило з .badge як селектором і встановіть background: tomato.", + "previewHTML": "
\n

Dashboard

\n 3\n
\n

You have new notifications waiting.

", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } header { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; } h1 { margin: 0; font-size: 1.5rem; } .badge { color: white; padding: 0.25rem 0.5rem; border-radius: 999px; font-size: 0.875rem; } p { color: #555; margin: 0; }", "sandboxCSS": "", - "codePrefix": "/* The .card class already has basic styling */\n/* Now target elements with BOTH classes: 'card' AND 'featured' */\n", + "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", - "solution": ".card.featured { border-color: gold; background-color: lemonchiffon }", + "solution": ".badge {\n background: tomato;\n}", "validations": [ { "type": "regex", - "value": "^\\.card\\.featured\\s*{", - "message": "Chain the selectors as .card.featured (no space between them)", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "border-color:", - "message": "Include the border-color property" + "value": "\\.badge\\s*\\{", + "message": "Почніть з .badge { (не забудьте крапку!)" }, { "type": "property_value", - "value": { - "property": "border-color", - "expected": "gold" - }, - "message": "Set the border color to gold" - }, - { - "type": "regex", - "value": "\\.card\\.featured\\s*{[^}]*;", - "message": "Make sure to end your CSS rule with a semicolon ;" - }, - { - "type": "contains", - "value": "background-color:", - "message": "Include the background-color property" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "lemonchiffon" - }, - "message": "Set the background color to lemonchiffon" - }, - { - "type": "regex", - "value": "\\.card\\.featured\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "options": { - "caseSensitive": true - } + "value": { "property": "background", "expected": "tomato" }, + "message": "Встановіть background: tomato" } ] }, { - "id": "class-with-type", - "title": "Combining Types", - "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, p.note would select paragraph elements with the class note, but would not select divs or spans with that same class. You can style these combined selections using properties like background-color 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.", - "task": "Create a CSS rule that specifically targets <span> elements with the class highlight. Make those elements have an orange background, while other elements with the highlight class remain untouched.", - "previewHTML": "

Type and Class Combinations

\n

This paragraph has a highlighted span that should have an orange background.

\n

This paragraph has the highlight class but should NOT have an orange background.

", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; } .highlight { font-weight: bold; }", - "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 span.highlight selector (no space between element and class)", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "background-color:", - "message": "Include the background-color property" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "orange" - }, - "message": "Set the background color to orange" - }, - { - "type": "regex", - "value": "span\\.highlight\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "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 color to define text color, and text-decoration 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 main-title. Set its color to purple and add an underline with text-decoration: underline.", - "previewHTML": "

Main Page Title

\n

Regular paragraph content.

\n

Secondary Heading

\n

Introduction paragraph (different ID).

", - "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 #main-title to create an ID selector", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "color:", - "message": "Include the color property" - }, - { - "type": "property_value", - "value": { - "property": "color", - "expected": "purple" - }, - "message": "Set the color to purple" - }, - { - "type": "contains", - "value": "text-decoration:", - "message": "Include the text-decoration property" - }, - { - "type": "property_value", - "value": { - "property": "text-decoration", - "expected": "underline" - }, - "message": "Set the text-decoration to underline" - }, - { - "type": "regex", - "value": "#main-title\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "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, h1#title targets an h1 element with the ID 'title'. When using this combined approach, you can apply CSS properties like font-style 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 special. Set its font style to italic.", - "previewHTML": "

Heading with ID \"special\" (should NOT be affected)

\n

Paragraph with ID \"special\" (should become italic)

", - "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 p#special to target paragraphs with ID special", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "font-style:", - "message": "Include the font-style property" - }, - { - "type": "property_value", - "value": { - "property": "font-style", - "expected": "italic" - }, - "message": "Set the font-style to italic" - }, - { - "type": "regex", - "value": "p#special\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "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, h1, h2, h3 { color: blue; } applies the same blue color to all three heading levels. When styling multiple selectors at once, you can apply properties like background-color to set the background, border-left to create a left border with a specific thickness, style, and color, and padding-left 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 note, list items with class important, and the element with ID summary. Give them a lightyellow background, a gold left border, and some left padding.", - "previewHTML": "

This is a note paragraph.

\n\n
Summary section
", - "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 p.note in your selector list", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "li.important", - "message": "Include li.important in your selector list", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "#summary", - "message": "Include #summary 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 background-color property" - }, - { - "type": "property_value", - "value": { - "property": "background-color", - "expected": "lightyellow" - }, - "message": "Set the background color to lightyellow" - }, - { - "type": "contains", - "value": "border-left:", - "message": "Include the border-left property" - }, - { - "type": "property_value", - "value": { - "property": "border-left", - "expected": "3px solid gold" - }, - "message": "Use border-left: 3px solid gold to create a left border" - }, - { - "type": "contains", - "value": "padding-left:", - "message": "Include the padding-left property" - }, - { - "type": "property_value", - "value": { - "property": "padding-left", - "expected": "10px" - }, - "message": "Use padding-left: 10px 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, * { margin: 0; } removes margins from all elements, while article * selects all elements inside article elements. When using the universal selector in combination with other selectors, you can apply properties like margin 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 div.container * as the selector and set margin: 0.", - "previewHTML": "
\n

Inside Container

\n

This paragraph is inside the container.

\n \n
\n

This paragraph is outside the container and should not be affected.

", - "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; }", + "id": "button-variants", + "title": "Варіанти кнопок", + "description": "Елементи можуть мати кілька класів. Коли ви з'єднуєте селектори класів без пробілів, ви націлюєтесь на елементи, які мають усі ці класи:

.btn.primary {
background: steelblue;
}

Це націлюється на елементи з class=\"btn primary\", а не лише .btn або лише .primary.", + "task": "Стилізуйте основну кнопку. Напишіть правило з .btn.primary як селектором і встановіть background: steelblue.", + "previewHTML": "
\n \n \n
", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } .actions { display: flex; gap: 0.75rem; } .btn { padding: 0.5rem 1rem; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; background: #e0e0e0; color: #333; }", "sandboxCSS": "", - "codePrefix": "/* Use the universal selector to target all elements inside the container */\n", + "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", + "solution": ".btn.primary {\n background: steelblue;\n}", "validations": [ { "type": "regex", - "value": "^div\\.container\\s+\\*\\s*{", - "message": "Use div.container * selector (with a space between container and *)", - "options": { - "caseSensitive": true - } - }, - { - "type": "contains", - "value": "margin:", - "message": "Include the margin property" + "value": "\\.btn\\.primary\\s*\\{", + "message": "Використовуйте .btn.primary { (без пробілу між класами)" }, { "type": "property_value", - "value": { - "property": "margin", - "expected": "0" - }, - "message": "Set margin to 0" - }, - { - "type": "regex", - "value": "div\\.container\\s+\\*\\s*{[^}]*}", - "message": "Make sure to close your CSS rule with a closing brace }", - "options": { - "caseSensitive": true - } + "value": { "property": "background", "expected": "steelblue" }, + "message": "Встановіть background: steelblue" } ] }, { - "id": "specificity-basics", - "title": "Specificity", - "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 color 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.", - "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.", - "previewHTML": "
\n

What color will this paragraph be? Look at the CSS rules and their specificity.

\n
", - "previewBaseCSS": "body { font-family: sans-serif; line-height: 1.5; padding: 20px; }", - "sandboxCSS": "p { border: 1px dashed gray; padding: 10px; }", - "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", + "id": "specific-elements", + "title": "Націлювання на конкретні елементи", + "description": "Іноді ви хочете, щоб клас виглядав по-різному на різних елементах. Поєднайте селектор типу з селектором класу (без пробілу) щоб бути більш специфічним:

a.btn {
text-decoration: none;
}

Це стилізує лише елементи <a> з класом btn, а не елементи <button> з цим класом.", + "task": "Приберіть підкреслення з кнопок-посилань. Напишіть правило з a.btn як селектором і встановіть text-decoration: none.", + "previewHTML": "
\n \n Link Button\n
", + "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } .actions { display: flex; gap: 0.75rem; align-items: center; } .btn { padding: 0.5rem 1rem; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; background: steelblue; color: white; }", + "sandboxCSS": "", + "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", + "solution": "a.btn {\n text-decoration: none;\n}", "validations": [ { "type": "regex", - "value": "^\\.content\\s+p\\s*{", - "message": "Use .content p as your selector (note the space between)", - "options": { - "caseSensitive": true - } + "value": "a\\.btn\\s*\\{", + "message": "Використовуйте a.btn { (тип + клас, без пробілу)" }, { - "type": "contains", - "value": "color:", - "message": "Include the color property" + "type": "property_value", + "value": { "property": "text-decoration", "expected": "none" }, + "message": "Встановіть text-decoration: none" + } + ] + }, + { + "id": "grouping-selectors", + "title": "Групування селекторів", + "description": "Коли кільком елементам потрібні однакові стилі, перелічіть їх через кому. Це тримає ваш CSS чистим і підтримуваним.

h1, h2, h3 {
color: steelblue;
}

Це застосовує однаковий колір до всіх трьох рівнів заголовків в одному правилі.", + "task": "Стилізуйте всі заголовки однаково. Додайте color: steelblue до згрупованого селектора h1, h2, h3.", + "previewHTML": "

Main Title

Introduction paragraph with some text.

Section Heading

More content here.

Subsection

Final paragraph.

", + "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } article { max-width: 500px; } p { color: #555; line-height: 1.6; }", + "sandboxCSS": "", + "codePrefix": "h1, h2, h3 {\n ", + "initialCode": "", + "codeSuffix": "\n}", + "previewContainer": "preview-area", + "solution": "color: steelblue;", + "validations": [ + { + "type": "property_value", + "value": { "property": "color", "expected": "steelblue" }, + "message": "Встановіть color: steelblue" + } + ] + }, + { + "id": "descendant-selectors", + "title": "Селектори нащадків", + "description": "Націлюйтесь на елементи всередині інших елементів використовуючи пробіл між селекторами. Це один з найкорисніших патернів у CSS.

.nav a {
color: white;
}

Це стилізує лише посилання всередині .nav, залишаючи інші посилання без змін.", + "task": "Стилізуйте навігаційні посилання по-іншому. Напишіть правило з .nav a як селектором і встановіть color: white.", + "previewHTML": "

Read more in our documentation.

", + "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; margin: 0; } .nav { background: steelblue; padding: 1rem; display: flex; gap: 1rem; border-radius: 8px; margin-bottom: 1rem; } .nav a { text-decoration: none; } p a { color: steelblue; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", + "codeSuffix": "", + "previewContainer": "preview-area", + "solution": ".nav a {\n color: white;\n}", + "validations": [ + { + "type": "regex", + "value": "\\.nav\\s+a\\s*\\{", + "message": "Використовуйте .nav a { (пробіл між .nav і a)" }, { - "type": "contains", - "value": "green", - "message": "" + "type": "property_value", + "value": { "property": "color", "expected": "white" }, + "message": "Встановіть color: white" + } + ] + }, + { + "id": "nested-styling", + "title": "Вкладені стилі", + "description": "Селектори нащадків дозволяють створювати контекстні стилі. Один і той самий елемент може виглядати по-різному залежно від того, де він з'являється.

Наприклад, абзаци в .card можуть бути меншими ніж абзаци в article.", + "task": "Зробіть абзаци всередині картки меншими. Напишіть правило з .card p як селектором і встановіть font-size: 0.9rem.", + "previewHTML": "

Article Title

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

Quick Tip

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

Back to regular article text here.

", + "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } article { max-width: 500px; } h2 { color: steelblue; margin-top: 0; } p { line-height: 1.6; color: #444; } .card { background: #f0f4f8; padding: 1rem; border-radius: 8px; border-left: 4px solid steelblue; } .card strong { color: steelblue; display: block; margin-bottom: 0.5rem; }", + "sandboxCSS": "", + "codePrefix": "", + "initialCode": "", + "codeSuffix": "", + "previewContainer": "preview-area", + "solution": ".card p {\n font-size: 0.9rem;\n}", + "validations": [ + { + "type": "regex", + "value": "\\.card\\s+p\\s*\\{", + "message": "Використовуйте .card p { (пробіл між .card і p)" + }, + { + "type": "property_value", + "value": { "property": "font-size", "expected": "0.9rem" }, + "message": "Встановіть font-size: 0.9rem" } ] }