{ "$schema": "../../schemas/code-crispies-module-schema.json", "id": "css-basic-selectors", "title": "Основи CSS", "description": "Вивчіть основні будівельні блоки CSS: властивості, значення та селектори. Цей модуль навчає правилам синтаксису, яких дотримується кожна декларація CSS.", "difficulty": "beginner", "lessons": [ { "id": "css-properties", "title": "Властивості CSS", "description": "CSS стилізує елементи за допомогою декларацій - пар властивостей і значень. Кожна декларація має той самий шаблон:

property: value;

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

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

This text should turn coral.

", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .text { font-size: 1.25rem; }", "sandboxCSS": "", "codePrefix": ".text {\n ", "initialCode": "", "codeSuffix": "\n}", "previewContainer": "preview-area", "solution": "color: coral;", "validations": [ { "type": "property_value", "value": { "property": "color", "expected": "coral" }, "message": "Додайте color: coral;" } ] }, { "id": "multiple-properties", "title": "Кілька властивостей", "description": "Правило може мати кілька декларацій. Кожна йде в окремому рядку, і кожна потребує крапки з комою в кінці:

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

Порядок зазвичай не має значення - CSS застосовує всі. При конфліктах перемагає остання.", "task": "Додайте дві декларації: background: lavender; та padding: 1rem;", "previewHTML": "
A styled card with background and padding.
", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } .card { border-radius: 8px; }", "sandboxCSS": "", "codePrefix": ".card {\n ", "initialCode": "", "codeSuffix": "\n}", "previewContainer": "preview-area", "solution": "background: lavender;\n padding: 1rem;", "validations": [ { "type": "property_value", "value": { "property": "background", "expected": "lavender" }, "message": "Додайте background: lavender;" }, { "type": "property_value", "value": { "property": "padding", "expected": "1rem" }, "message": "Додайте padding: 1rem;" } ] }, { "id": "type-selectors", "title": "Селектори типу", "description": "Селектор говорить браузеру, які елементи стилізувати. Найпростіший селектор - це селектор типу — просто назва HTML-тегу.

p {
color: steelblue;
}

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

Fresh Roasted Coffee

\n

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

\n

Each batch is roasted weekly to ensure peak freshness.

\n
", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } h2 { margin: 0 0 1rem; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "p {\n color: steelblue;\n}", "validations": [ { "type": "regex", "value": "p\\s*\\{", "message": "Почніть з p { щоб вибрати абзаци" }, { "type": "property_value", "value": { "property": "color", "expected": "steelblue" }, "message": "Встановіть color: steelblue" } ] }, { "id": "styling-links", "title": "Стилізація посилань", "description": "Селектори типу працюють для будь-якого HTML-елемента. Селектор a націлюється на всі посилання на сторінці.

Посилання мають синій колір і підкреслення за замовчуванням. Ви можете змінити обидва з CSS — використовуйте color для тексту і text-decoration: none щоб прибрати підкреслення.", "task": "Стилізуйте навігаційні посилання. Напишіть правило з a як селектором і встановіть color: coral.", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } nav { display: flex; gap: 1.5rem; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": "a {\n color: coral;\n}", "validations": [ { "type": "regex", "value": "a\\s*\\{", "message": "Почніть з a { щоб вибрати посилання" }, { "type": "property_value", "value": { "property": "color", "expected": "coral" }, "message": "Встановіть color: coral" } ] }, { "id": "class-selectors", "title": "Селектори класів", "description": "Селектори типу стилізують усі елементи цього типу. Але що якщо ви хочете стилізувати лише деякі з них?

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

.badge {
background: coral;
}

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

Dashboard

\n 3\n
\n

You have new notifications waiting.

", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } header { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; } h1 { margin: 0; font-size: 1.5rem; } .badge { color: white; padding: 0.25rem 0.5rem; border-radius: 999px; font-size: 0.875rem; } p { color: #555; margin: 0; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": ".badge {\n background: tomato;\n}", "validations": [ { "type": "regex", "value": "\\.badge\\s*\\{", "message": "Почніть з .badge { (не забудьте крапку!)" }, { "type": "property_value", "value": { "property": "background", "expected": "tomato" }, "message": "Встановіть background: tomato" } ] }, { "id": "button-variants", "title": "Варіанти кнопок", "description": "Елементи можуть мати кілька класів. Коли ви з'єднуєте селектори класів без пробілів, ви націлюєтесь на елементи, які мають усі ці класи:

.btn.primary {
background: steelblue;
}

Це націлюється на елементи з class=\"btn primary\", а не лише .btn або лише .primary.", "task": "Стилізуйте основну кнопку. Напишіть правило з .btn.primary як селектором і встановіть background: steelblue.", "previewHTML": "
\n \n \n
", "previewBaseCSS": "body { font-family: system-ui; padding: 1rem; } .actions { display: flex; gap: 0.75rem; } .btn { padding: 0.5rem 1rem; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; background: #e0e0e0; color: #333; }", "sandboxCSS": "", "codePrefix": "", "initialCode": "", "codeSuffix": "", "previewContainer": "preview-area", "solution": ".btn.primary {\n background: steelblue;\n}", "validations": [ { "type": "regex", "value": "\\.btn\\.primary\\s*\\{", "message": "Використовуйте .btn.primary { (без пробілу між класами)" }, { "type": "property_value", "value": { "property": "background", "expected": "steelblue" }, "message": "Встановіть background: steelblue" } ] }, { "id": "specific-elements", "title": "Націлювання на конкретні елементи", "description": "Іноді ви хочете, щоб клас виглядав по-різному на різних елементах. Поєднайте селектор типу з селектором класу (без пробілу) щоб бути більш специфічним:

a.btn {
text-decoration: none;
}

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

h1, h2, h3 {
color: steelblue;
}

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

Main Title

Introduction paragraph with some text.

Section Heading

More content here.

Subsection

Final paragraph.

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

.nav a {
color: white;
}

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

Read more in our documentation.

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

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

Article Title

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

Quick Tip

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

Back to regular article text here.

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