refactor: shorten lesson titles and improve content

- Shorten verbose lesson titles for better sidebar display
- Minor content improvements across lessons
This commit is contained in:
2025-12-30 16:22:48 +01:00
parent 23549f1e90
commit 15f10bcdf8
23 changed files with 79 additions and 79 deletions

View File

@@ -1,13 +1,13 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "css-basic-selectors", "id": "css-basic-selectors",
"title": "CSS: Basic Selectors", "title": "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.", "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.",
"difficulty": "beginner", "difficulty": "beginner",
"lessons": [ "lessons": [
{ {
"id": "introduction-to-selectors", "id": "introduction-to-selectors",
"title": "What is a CSS Selector?", "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.<br/>For example, to change the text color of elements, you can use the <kbd>color</kbd> property within your declaration block.<br><br><pre>/* Element selector */\np {\n color: orangered;\n /* │ └─── Indicates the value of the expression\n │ \n └─────────── Indicates the property of the expression */\n}</pre>", "description": "A CSS selector is the first part of a CSS rule that tells the browser which HTML elements should receive the styles defined in the declaration block. Selectors are essentially patterns that match against elements in your HTML document. Understanding selectors is fundamental because they determine which elements your CSS rules will affect. The element or elements targeted by a selector are referred to as the 'subject of the selector.' When writing a CSS rule, you first specify the selector, followed by curly braces that contain the style declarations.<br/>For example, to change the text color of elements, you can use the <kbd>color</kbd> property within your declaration block.<br><br><pre>/* Element selector */\np {\n color: orangered;\n /* │ └─── Indicates the value of the expression\n │ \n └─────────── Indicates the property of the expression */\n}</pre>",
"task": "Write a CSS rule using a type selector that targets all paragraph elements <kbd>p</kbd> in the document. Make the text blue by setting the <kbd>color</kbd> property to <kbd>blue</kbd>.", "task": "Write a CSS rule using a type selector that targets all paragraph elements <kbd>p</kbd> in the document. Make the text blue by setting the <kbd>color</kbd> property to <kbd>blue</kbd>.",
"previewHTML": "<h1>Introduction to CSS Selectors</h1>\n<p>This paragraph should turn blue.</p>\n<div>This div element should remain unchanged.</div>\n<p>This second paragraph should also turn blue.</p>", "previewHTML": "<h1>Introduction to CSS Selectors</h1>\n<p>This paragraph should turn blue.</p>\n<div>This div element should remain unchanged.</div>\n<p>This second paragraph should also turn blue.</p>",
@@ -57,7 +57,7 @@
}, },
{ {
"id": "type-selectors", "id": "type-selectors",
"title": "Type Selectors: Targeting HTML Elements", "title": "Type Selectors",
"description": "Type selectors (also called tag name selectors or element selectors) target HTML elements based on their tag name. For example, <kbd>p</kbd> selects all paragraph elements, <kbd>h1</kbd> selects all level-one headings, and <kbd>div</kbd> selects all division elements. Type selectors are the most fundamental way to select elements, applying styles consistently to all instances of a particular HTML element throughout your document. You can define a variety of CSS properties with type selectors, such as <kbd>color</kbd> for text color, <kbd>background-color</kbd> for the background, and <kbd>font-weight</kbd> for text emphasis. They provide a broad approach for styling your page and are often the starting point for more specific styling using other selector types.", "description": "Type selectors (also called tag name selectors or element selectors) target HTML elements based on their tag name. For example, <kbd>p</kbd> selects all paragraph elements, <kbd>h1</kbd> selects all level-one headings, and <kbd>div</kbd> selects all division elements. Type selectors are the most fundamental way to select elements, applying styles consistently to all instances of a particular HTML element throughout your document. You can define a variety of CSS properties with type selectors, such as <kbd>color</kbd> for text color, <kbd>background-color</kbd> for the background, and <kbd>font-weight</kbd> for text emphasis. They provide a broad approach for styling your page and are often the starting point for more specific styling using other selector types.",
"task": "Write three separate CSS rules using type selectors to target specific HTML elements: make <kbd>h2</kbd> headings <kbd>purple</kbd>, give <kbd>span</kbd> elements a <kbd>yellow</kbd> background, and make <kbd>strong</kbd> elements <kbd>red</kbd>.", "task": "Write three separate CSS rules using type selectors to target specific HTML elements: make <kbd>h2</kbd> headings <kbd>purple</kbd>, give <kbd>span</kbd> elements a <kbd>yellow</kbd> background, and make <kbd>strong</kbd> elements <kbd>red</kbd>.",
"previewHTML": "<h2>Type Selectors Example</h2>\n<p>Regular paragraph text <span>with a highlighted span</span> that should have a yellow background.</p>\n<p>Another paragraph with <strong>strong important text</strong> that should be red.</p>\n<h2>Another Heading</h2>", "previewHTML": "<h2>Type Selectors Example</h2>\n<p>Regular paragraph text <span>with a highlighted span</span> that should have a yellow background.</p>\n<p>Another paragraph with <strong>strong important text</strong> that should be red.</p>\n<h2>Another Heading</h2>",
@@ -119,7 +119,7 @@
}, },
{ {
"id": "class-selectors", "id": "class-selectors",
"title": "Class Selectors: Styling Element Groups", "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 <kbd>background-color</kbd> to set the background color of elements, and <kbd>font-weight</kbd> to control text thickness, making text bold or normal. This flexibility makes class selectors one of the most commonly used methods for applying styles in CSS, allowing for modular and reusable styling across your website.", "description": "Class selectors target elements with a specific class attribute value. They begin with a dot (.) followed by the class name. Classes are powerful because they allow you to apply the same styles to multiple elements regardless of their type. An HTML element can have multiple classes (separated by spaces in the class attribute), and a class can be applied to any number of elements. When using class selectors, you can apply properties like <kbd>background-color</kbd> to set the background color of elements, and <kbd>font-weight</kbd> to control text thickness, making text bold or normal. This flexibility makes class selectors one of the most commonly used methods for applying styles in CSS, allowing for modular and reusable styling across your website.",
"task": "Create a CSS rule using a class selector that targets elements with the class <kbd>highlight</kbd>. Give these elements a <kbd>yellow</kbd> background and <kbd>bold</kbd> text.", "task": "Create a CSS rule using a class selector that targets elements with the class <kbd>highlight</kbd>. Give these elements a <kbd>yellow</kbd> background and <kbd>bold</kbd> text.",
"previewHTML": "<h2>Using Class Selectors</h2>\n<p>This is a regular paragraph, but <span class=\"highlight\">this span has the highlight class</span> applied to it.</p>\n<p class=\"highlight\">This entire paragraph has the highlight class.</p>\n<ul>\n <li>Regular list item</li>\n <li class=\"highlight\">This list item is highlighted</li>\n</ul>", "previewHTML": "<h2>Using Class Selectors</h2>\n<p>This is a regular paragraph, but <span class=\"highlight\">this span has the highlight class</span> applied to it.</p>\n<p class=\"highlight\">This entire paragraph has the highlight class.</p>\n<ul>\n <li>Regular list item</li>\n <li class=\"highlight\">This list item is highlighted</li>\n</ul>",
@@ -176,7 +176,7 @@
}, },
{ {
"id": "multiple-classes", "id": "multiple-classes",
"title": "Working with Multiple Classes", "title": "Multiple Classes",
"description": "HTML elements can have multiple classes applied simultaneously, allowing for composable and modular CSS designs. When an element has multiple classes, it will receive styles from all matching class selectors. This approach enables you to build a library of reusable CSS classes that can be combined in different ways. You can also target elements that have a specific combination of classes by chaining class selectors together without spaces (e.g., <kbd>.class1.class2</kbd>). When styling these elements, you might use properties like <kbd>border-color</kbd> to change the color of element borders, and <kbd>background-color</kbd> to set the background color of elements. This technique lets you create conditional styles that only apply when certain classes appear together.", "description": "HTML elements can have multiple classes applied simultaneously, allowing for composable and modular CSS designs. When an element has multiple classes, it will receive styles from all matching class selectors. This approach enables you to build a library of reusable CSS classes that can be combined in different ways. You can also target elements that have a specific combination of classes by chaining class selectors together without spaces (e.g., <kbd>.class1.class2</kbd>). When styling these elements, you might use properties like <kbd>border-color</kbd> to change the color of element borders, and <kbd>background-color</kbd> to set the background color of elements. This technique lets you create conditional styles that only apply when certain classes appear together.",
"task": "Complete the CSS rule that targets elements with both <kbd>card</kbd> and <kbd>featured</kbd> classes by chaining the selectors. Set the border-color to gold and the background-color to lemonchiffon to make featured cards stand out.", "task": "Complete the CSS rule that targets elements with both <kbd>card</kbd> and <kbd>featured</kbd> classes by chaining the selectors. Set the border-color to gold and the background-color to lemonchiffon to make featured cards stand out.",
"previewHTML": "<h2>Multiple Class Combinations</h2>\n<div class=\"card\">Regular Card</div>\n<div class=\"card featured\">Featured Card</div>\n<div class=\"featured\">Just Featured (not a card)</div>", "previewHTML": "<h2>Multiple Class Combinations</h2>\n<div class=\"card\">Regular Card</div>\n<div class=\"card featured\">Featured Card</div>\n<div class=\"featured\">Just Featured (not a card)</div>",
@@ -239,7 +239,7 @@
}, },
{ {
"id": "class-with-type", "id": "class-with-type",
"title": "Combining Type and Class Selectors", "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, <kbd>p.note</kbd> would select paragraph elements with the class <kbd>note</kbd>, but would not select divs or spans with that same class. You can style these combined selections using properties like <kbd>background-color</kbd> to set a colored background for your elements. This approach allows you to apply different styles to the same class when it appears on different element types.", "description": "You can combine type selectors with class selectors to target specific HTML elements that have a certain class. This creates a more specific selector that only matches when both conditions are true: the element is of the specified type AND it has the specified class. For example, <kbd>p.note</kbd> would select paragraph elements with the class <kbd>note</kbd>, but would not select divs or spans with that same class. You can style these combined selections using properties like <kbd>background-color</kbd> to set a colored background for your elements. This approach allows you to apply different styles to the same class when it appears on different element types.",
"task": "Create a CSS rule that specifically targets <kbd>&lt;span&gt;</kbd> elements with the class <kbd>highlight</kbd>. Make those elements have an orange background, while other elements with the highlight class remain untouched.", "task": "Create a CSS rule that specifically targets <kbd>&lt;span&gt;</kbd> elements with the class <kbd>highlight</kbd>. Make those elements have an orange background, while other elements with the highlight class remain untouched.",
"previewHTML": "<h2>Type and Class Combinations</h2>\n<p>This paragraph has a <span class=\"highlight\">highlighted span</span> that should have an orange background.</p>\n<p class=\"highlight\">This paragraph has the highlight class but should NOT have an orange background.</p>", "previewHTML": "<h2>Type and Class Combinations</h2>\n<p>This paragraph has a <span class=\"highlight\">highlighted span</span> that should have an orange background.</p>\n<p class=\"highlight\">This paragraph has the highlight class but should NOT have an orange background.</p>",
@@ -283,7 +283,7 @@
}, },
{ {
"id": "id-selectors", "id": "id-selectors",
"title": "ID Selectors: Targeting Unique Elements", "title": "ID Selectors",
"description": "ID selectors target elements with a specific id attribute. They begin with a hash/pound sign (#) followed by the ID name. Unlike classes, IDs must be unique within a document—each ID value should be used only once per page. ID selectors have higher specificity than class or element selectors, meaning they override those selectors when conflicts arise. When styling with ID selectors, you can use properties like <kbd>color</kbd> to define text color, and <kbd>text-decoration</kbd> to control the appearance of text, such as adding underlines to elements. Because of their uniqueness requirement, IDs are best used for one-of-a-kind elements like page headers, main navigation, or specific unique components that appear only once on a page.", "description": "ID selectors target elements with a specific id attribute. They begin with a hash/pound sign (#) followed by the ID name. Unlike classes, IDs must be unique within a document—each ID value should be used only once per page. ID selectors have higher specificity than class or element selectors, meaning they override those selectors when conflicts arise. When styling with ID selectors, you can use properties like <kbd>color</kbd> to define text color, and <kbd>text-decoration</kbd> to control the appearance of text, such as adding underlines to elements. Because of their uniqueness requirement, IDs are best used for one-of-a-kind elements like page headers, main navigation, or specific unique components that appear only once on a page.",
"task": "Create a CSS rule with an ID selector that targets the element with the ID <kbd>main-title</kbd>. Set its color to purple and add an underline with <kbd>text-decoration: underline</kbd>.", "task": "Create a CSS rule with an ID selector that targets the element with the ID <kbd>main-title</kbd>. Set its color to purple and add an underline with <kbd>text-decoration: underline</kbd>.",
"previewHTML": "<h1 id=\"main-title\">Main Page Title</h1>\n<p>Regular paragraph content.</p>\n<h2>Secondary Heading</h2>\n<p id=\"intro\">Introduction paragraph (different ID).</p>", "previewHTML": "<h1 id=\"main-title\">Main Page Title</h1>\n<p>Regular paragraph content.</p>\n<h2>Secondary Heading</h2>\n<p id=\"intro\">Introduction paragraph (different ID).</p>",
@@ -340,7 +340,7 @@
}, },
{ {
"id": "id-with-type", "id": "id-with-type",
"title": "Combining Type and ID Selectors", "title": "Type + ID",
"description": "Similar to how you can combine type and class selectors, you can also combine type selectors with ID selectors. For example, <kbd>h1#title</kbd> targets an h1 element with the ID 'title'. When using this combined approach, you can apply CSS properties like <kbd>font-style</kbd> to control the slant of the text, making it italic or normal. While this selector combination is more specific than using just the ID selector, it's often unnecessary since IDs should already be unique in a document. However, this technique can be useful for improving code readability or when you want to emphasize that a particular ID should only appear on a specific element type.", "description": "Similar to how you can combine type and class selectors, you can also combine type selectors with ID selectors. For example, <kbd>h1#title</kbd> targets an h1 element with the ID 'title'. When using this combined approach, you can apply CSS properties like <kbd>font-style</kbd> to control the slant of the text, making it italic or normal. While this selector combination is more specific than using just the ID selector, it's often unnecessary since IDs should already be unique in a document. However, this technique can be useful for improving code readability or when you want to emphasize that a particular ID should only appear on a specific element type.",
"task": "Create a CSS rule that combines a type selector with an ID selector to target specifically a paragraph element with the ID <kbd>special</kbd>. Set its font style to italic.", "task": "Create a CSS rule that combines a type selector with an ID selector to target specifically a paragraph element with the ID <kbd>special</kbd>. Set its font style to italic.",
"previewHTML": "<h2 id=\"special\">Heading with ID \"special\" (should NOT be affected)</h2>\n<p id=\"special\">Paragraph with ID \"special\" (should become italic)</p>", "previewHTML": "<h2 id=\"special\">Heading with ID \"special\" (should NOT be affected)</h2>\n<p id=\"special\">Paragraph with ID \"special\" (should become italic)</p>",
@@ -384,7 +384,7 @@
}, },
{ {
"id": "selector-lists", "id": "selector-lists",
"title": "Selector Lists: Applying the Same Rules to Multiple Selectors", "title": "Selector Lists",
"description": "When multiple elements need the same styling, you can group them together using a selector list (also known as grouping selectors). Selector lists are created by separating individual selectors with commas. This approach reduces repetition in your CSS, making it more maintainable and efficient. For example, <kbd>h1, h2, h3 { color: blue; }</kbd> applies the same blue color to all three heading levels. When styling multiple selectors at once, you can apply properties like <kbd>background-color</kbd> to set the background, <kbd>border-left</kbd> to create a left border with a specific thickness, style, and color, and <kbd>padding-left</kbd> to create space between the content and the left border. Whitespace around commas is optional, and each selector in the list can be any valid selector type-elements, classes, IDs, or even more complex selectors.", "description": "When multiple elements need the same styling, you can group them together using a selector list (also known as grouping selectors). Selector lists are created by separating individual selectors with commas. This approach reduces repetition in your CSS, making it more maintainable and efficient. For example, <kbd>h1, h2, h3 { color: blue; }</kbd> applies the same blue color to all three heading levels. When styling multiple selectors at once, you can apply properties like <kbd>background-color</kbd> to set the background, <kbd>border-left</kbd> to create a left border with a specific thickness, style, and color, and <kbd>padding-left</kbd> to create space between the content and the left border. Whitespace around commas is optional, and each selector in the list can be any valid selector type-elements, classes, IDs, or even more complex selectors.",
"task": "Create a selector list that applies the same styles to three different elements: paragraphs with class <kbd>note</kbd>, list items with class <kbd>important</kbd>, and the element with ID <kbd>summary</kbd>. Give them a <kbd>lightyellow</kbd> background, a <kbd>gold</kbd> left border, and some left <kbd>padding</kbd>.", "task": "Create a selector list that applies the same styles to three different elements: paragraphs with class <kbd>note</kbd>, list items with class <kbd>important</kbd>, and the element with ID <kbd>summary</kbd>. Give them a <kbd>lightyellow</kbd> background, a <kbd>gold</kbd> left border, and some left <kbd>padding</kbd>.",
"previewHTML": "<p class=\"note\">This is a note paragraph.</p>\n<ul>\n <li>Regular list item</li>\n <li class=\"important\">Important list item</li>\n</ul>\n<div id=\"summary\">Summary section</div>", "previewHTML": "<p class=\"note\">This is a note paragraph.</p>\n<ul>\n <li>Regular list item</li>\n <li class=\"important\">Important list item</li>\n</ul>\n<div id=\"summary\">Summary section</div>",
@@ -471,7 +471,7 @@
}, },
{ {
"id": "universal-selector", "id": "universal-selector",
"title": "The Universal Selector: Targeting Everything", "title": "Universal (*)",
"description": "The universal selector is denoted by an asterisk (*) and matches any element of any type. It selects everything in the document or, when combined with other selectors, everything within a specific context. For example, <kbd>* { margin: 0; }</kbd> removes margins from all elements, while <kbd>article *</kbd> selects all elements inside article elements. When using the universal selector in combination with other selectors, you can apply properties like <kbd>margin</kbd> to control the spacing around elements. The universal selector is powerful but should be used carefully due to its broad impact. It's commonly used in CSS resets, to override default browser styling, or to target all children of a particular element.", "description": "The universal selector is denoted by an asterisk (*) and matches any element of any type. It selects everything in the document or, when combined with other selectors, everything within a specific context. For example, <kbd>* { margin: 0; }</kbd> removes margins from all elements, while <kbd>article *</kbd> selects all elements inside article elements. When using the universal selector in combination with other selectors, you can apply properties like <kbd>margin</kbd> to control the spacing around elements. The universal selector is powerful but should be used carefully due to its broad impact. It's commonly used in CSS resets, to override default browser styling, or to target all children of a particular element.",
"task": "Use the universal selector to remove margins from all elements inside the container div. Create a rule using <kbd>div.container *</kbd> as the selector and set <kbd>margin: 0</kbd>.", "task": "Use the universal selector to remove margins from all elements inside the container div. Create a rule using <kbd>div.container *</kbd> as the selector and set <kbd>margin: 0</kbd>.",
"previewHTML": "<div class=\"container\">\n <h2>Inside Container</h2>\n <p>This paragraph is inside the container.</p>\n <ul>\n <li>List item inside container</li>\n </ul>\n</div>\n<p>This paragraph is outside the container and should not be affected.</p>", "previewHTML": "<div class=\"container\">\n <h2>Inside Container</h2>\n <p>This paragraph is inside the container.</p>\n <ul>\n <li>List item inside container</li>\n </ul>\n</div>\n<p>This paragraph is outside the container and should not be affected.</p>",
@@ -515,7 +515,7 @@
}, },
{ {
"id": "specificity-basics", "id": "specificity-basics",
"title": "Understanding Selector Specificity", "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 <kbd>color</kbd> property to set text colors, and specificity will determine which color is actually applied. Understanding specificity is crucial for predictable styling and debugging CSS conflicts. When two selectors have equal specificity, the one that comes last in the stylesheet wins.", "description": "CSS specificity determines which styles take precedence when multiple conflicting rules target the same element. Specificity follows a hierarchical system: inline styles have the highest specificity, followed by ID selectors, then class/attribute/pseudo-class selectors, and finally element/pseudo-element selectors. This can be conceptualized as a four-part score (inline, ID, class, element). When creating multiple rules that may target the same elements, you can use the <kbd>color</kbd> property to set text colors, and specificity will determine which color is actually applied. Understanding specificity is crucial for predictable styling and debugging CSS conflicts. When two selectors have equal specificity, the one that comes last in the stylesheet wins.",
"task": "Examine the existing CSS rules and add a new rule with higher specificity to override the text color of the paragraph. Create a rule using '.content p' as the selector and set color: green.", "task": "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": "<div class=\"content\">\n <p>What color will this paragraph be? Look at the CSS rules and their specificity.</p>\n</div>", "previewHTML": "<div class=\"content\">\n <p>What color will this paragraph be? Look at the CSS rules and their specificity.</p>\n</div>",

View File

@@ -1,13 +1,13 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "css-fundamentals", "id": "css-fundamentals",
"title": "101 Rules and Selectors", "title": "CSS 101",
"description": "Cascading Style Sheets (CSS) form the cornerstone of modern web presentation. This module provides a comprehensive introduction to CSS syntax, selectors, properties, and core design concepts. You'll develop a deep understanding of how CSS empowers web developers to control visual aesthetics, layout, and responsive behavior across digital interfaces. Throughout these lessons, we'll build a robust foundation that prepares you for more advanced web engineering topics.", "description": "Cascading Style Sheets (CSS) form the cornerstone of modern web presentation. This module provides a comprehensive introduction to CSS syntax, selectors, properties, and core design concepts. You'll develop a deep understanding of how CSS empowers web developers to control visual aesthetics, layout, and responsive behavior across digital interfaces. Throughout these lessons, we'll build a robust foundation that prepares you for more advanced web engineering topics.",
"difficulty": "beginner", "difficulty": "beginner",
"lessons": [ "lessons": [
{ {
"id": "css-syntax-structure", "id": "css-syntax-structure",
"title": "CSS Syntax: The Building Blocks", "title": "Syntax Basics",
"description": "CSS (Cascading Style Sheets) follows a structured syntax that consists of selectors targeting HTML elements and declaration blocks defining their styling. A declaration block contains one or more declarations separated by semicolons, with each declaration consisting of a property and value pair. This fundamental structure forms the basis of all CSS rules and allows for precise control over web page presentation. Understanding this syntax is critical for effectively implementing any styling on the web.<br><br><pre>/* Element selector */\np {\n color: orangered;\n /* │ └─── Indicates the value of the expression\n │ \n └─────────── Indicates the property of the expression */\n}</pre>", "description": "CSS (Cascading Style Sheets) follows a structured syntax that consists of selectors targeting HTML elements and declaration blocks defining their styling. A declaration block contains one or more declarations separated by semicolons, with each declaration consisting of a property and value pair. This fundamental structure forms the basis of all CSS rules and allows for precise control over web page presentation. Understanding this syntax is critical for effectively implementing any styling on the web.<br><br><pre>/* Element selector */\np {\n color: orangered;\n /* │ └─── Indicates the value of the expression\n │ \n └─────────── Indicates the property of the expression */\n}</pre>",
"task": "Complete the CSS rule by providing a valid selector that targets all paragraph elements (p). This selector should apply to every paragraph on the page. Notice how the declaration block is already structured with the property-value pair 'color: blue;'.", "task": "Complete the CSS rule by providing a valid selector that targets all paragraph elements (p). This selector should apply to every paragraph on the page. Notice how the declaration block is already structured with the property-value pair 'color: blue;'.",
"previewHTML": "<p>This paragraph should be blue.</p><p>This paragraph should also be blue.</p><div>This div element should remain unchanged.</div>", "previewHTML": "<p>This paragraph should be blue.</p><p>This paragraph should also be blue.</p><div>This div element should remain unchanged.</div>",
@@ -30,7 +30,7 @@
}, },
{ {
"id": "css-selectors-element", "id": "css-selectors-element",
"title": "Element Selectors: Targeting HTML Elements", "title": "Type Selectors",
"description": "Element selectors target HTML elements directly by their tag name. For example, 'p' selects all paragraph elements, 'h1' selects all first-level headings, and 'div' selects all division elements. Element selectors are powerful for applying consistent styling to all instances of a particular HTML element throughout your document. They form the foundation of CSS selection and are often combined with other selectors to create more specific targeting patterns.", "description": "Element selectors target HTML elements directly by their tag name. For example, 'p' selects all paragraph elements, 'h1' selects all first-level headings, and 'div' selects all division elements. Element selectors are powerful for applying consistent styling to all instances of a particular HTML element throughout your document. They form the foundation of CSS selection and are often combined with other selectors to create more specific targeting patterns.",
"task": "Write an element selector to target all heading level 2 elements (h2). Then complete the code to give them a red text color and an underline. This will make them stand out clearly on the page.", "task": "Write an element selector to target all heading level 2 elements (h2). Then complete the code to give them a red text color and an underline. This will make them stand out clearly on the page.",
"previewHTML": "<h2>This is a heading that needs styling</h2><p>This is a paragraph that should remain unchanged.</p><h2>This is another heading that needs the same styling</h2>", "previewHTML": "<h2>This is a heading that needs styling</h2><p>This is a paragraph that should remain unchanged.</p><h2>This is another heading that needs the same styling</h2>",
@@ -53,7 +53,7 @@
}, },
{ {
"id": "css-selectors-class", "id": "css-selectors-class",
"title": "Class Selectors: Targeting Specific Element Groups", "title": "Class Selectors",
"description": "Class selectors target HTML elements that share the same class attribute value. They begin with a dot (.) followed by the class name. Classes provide a flexible way to apply styles to groups of elements that may not share the same HTML tag. A single element can have multiple classes, and a class can be applied to multiple elements, making class selectors a powerful tool for organizing and applying styles efficiently across your website.", "description": "Class selectors target HTML elements that share the same class attribute value. They begin with a dot (.) followed by the class name. Classes provide a flexible way to apply styles to groups of elements that may not share the same HTML tag. A single element can have multiple classes, and a class can be applied to multiple elements, making class selectors a powerful tool for organizing and applying styles efficiently across your website.",
"task": "Write a class selector to target elements with the class 'important-text'. Set their color to 'red' and give them a yellow background. Begin with a dot (.) followed by the class name to create a proper class selector.", "task": "Write a class selector to target elements with the class 'important-text'. Set their color to 'red' and give them a yellow background. Begin with a dot (.) followed by the class name to create a proper class selector.",
"previewHTML": "<p class='important-text'>This text should be red with yellow background.</p><p>This text remains unchanged.</p><span class='important-text'>This span should also be red with yellow background.</span>", "previewHTML": "<p class='important-text'>This text should be red with yellow background.</p><p>This text remains unchanged.</p><span class='important-text'>This span should also be red with yellow background.</span>",
@@ -76,7 +76,7 @@
}, },
{ {
"id": "css-selectors-id", "id": "css-selectors-id",
"title": "ID Selectors: Targeting Unique Elements", "title": "ID Selectors",
"description": "ID selectors target a single, unique HTML element that has a specific id attribute value. They begin with a hash symbol (#) followed by the ID name. Unlike classes, an ID should be unique within a page—it should only be used once. ID selectors have higher specificity than class selectors, which means they override class and element selectors when specificity conflicts arise. Because of their uniqueness constraint, IDs are ideal for styling one-of-a-kind elements.", "description": "ID selectors target a single, unique HTML element that has a specific id attribute value. They begin with a hash symbol (#) followed by the ID name. Unlike classes, an ID should be unique within a page—it should only be used once. ID selectors have higher specificity than class selectors, which means they override class and element selectors when specificity conflicts arise. Because of their uniqueness constraint, IDs are ideal for styling one-of-a-kind elements.",
"task": "Write an ID selector to target the element with the ID 'header-title'. Set its font-weight to 'bold'. Begin with a hash symbol (#) followed by the ID name.", "task": "Write an ID selector to target the element with the ID 'header-title'. Set its font-weight to 'bold'. Begin with a hash symbol (#) followed by the ID name.",
"previewHTML": "<h1 id='header-title'>This heading needs to be bold</h1><h2>This heading should remain unchanged</h2>", "previewHTML": "<h1 id='header-title'>This heading needs to be bold</h1><h2>This heading should remain unchanged</h2>",
@@ -99,7 +99,7 @@
}, },
{ {
"id": "css-pseudo-classes-hover", "id": "css-pseudo-classes-hover",
"title": "Pseudo-classes: Interactive States with :hover", "title": ":hover State",
"description": "Pseudo-classes select elements based on states that aren't explicitly part of the document tree, such as user interaction states. The :hover pseudo-class is triggered when a user hovers their cursor over an element. This provides a powerful way to create interactive elements that respond to user actions without requiring JavaScript. Other common pseudo-classes include :focus, :active, and :visited, each representing different interaction states.", "description": "Pseudo-classes select elements based on states that aren't explicitly part of the document tree, such as user interaction states. The :hover pseudo-class is triggered when a user hovers their cursor over an element. This provides a powerful way to create interactive elements that respond to user actions without requiring JavaScript. Other common pseudo-classes include :focus, :active, and :visited, each representing different interaction states.",
"task": "Add the :hover pseudo-class to the button selector to create an interactive effect when users hover over buttons. This will change the background color to 'green' when a user's cursor is positioned over any button element.", "task": "Add the :hover pseudo-class to the button selector to create an interactive effect when users hover over buttons. This will change the background color to 'green' when a user's cursor is positioned over any button element.",
"previewHTML": "<button>Hover over me!</button><p>Try hovering over the button to see the effect.</p>", "previewHTML": "<button>Hover over me!</button><p>Try hovering over the button to see the effect.</p>",
@@ -122,7 +122,7 @@
}, },
{ {
"id": "css-box-model-padding", "id": "css-box-model-padding",
"title": "CSS Box Model: Understanding Padding", "title": "Padding",
"description": "The CSS box model represents how elements are rendered in the browser. Every element is effectively a box with content at its core, surrounded by padding, border, and margin areas. Padding creates space between an element's content and its border, providing visual breathing room. You can control padding on all sides at once with the 'padding' property, or target specific sides with 'padding-top', 'padding-right', 'padding-bottom', and 'padding-left'. Proper padding is essential for visual hierarchy and readability.", "description": "The CSS box model represents how elements are rendered in the browser. Every element is effectively a box with content at its core, surrounded by padding, border, and margin areas. Padding creates space between an element's content and its border, providing visual breathing room. You can control padding on all sides at once with the 'padding' property, or target specific sides with 'padding-top', 'padding-right', 'padding-bottom', and 'padding-left'. Proper padding is essential for visual hierarchy and readability.",
"task": "Add padding to the content-box element. Set the padding to '20px' to create adequate space between the content and the element's border. This will improve readability and visual appeal.", "task": "Add padding to the content-box element. Set the padding to '20px' to create adequate space between the content and the element's border. This will improve readability and visual appeal.",
"previewHTML": "<div class='content-box'><p>This paragraph needs proper padding around it to improve readability and aesthetic appeal.</p><p>Without padding, text would touch the edges of the box, making it harder to read.</p></div>", "previewHTML": "<div class='content-box'><p>This paragraph needs proper padding around it to improve readability and aesthetic appeal.</p><p>Without padding, text would touch the edges of the box, making it harder to read.</p></div>",
@@ -156,7 +156,7 @@
}, },
{ {
"id": "css-box-model-margin", "id": "css-box-model-margin",
"title": "CSS Box Model: Understanding Margin", "title": "Margin",
"description": "Margin is the outermost layer of the CSS box model, creating space between an element and its neighboring elements. Unlike padding which affects the internal spacing, margins define the external spacing relationships between elements. Margins can be set for all sides with the 'margin' property or individually with 'margin-top', 'margin-right', 'margin-bottom', and 'margin-left'. Margins can also accept negative values to create overlapping effects, and they collapse in certain situations—an important behavior to understand for precise layout control.", "description": "Margin is the outermost layer of the CSS box model, creating space between an element and its neighboring elements. Unlike padding which affects the internal spacing, margins define the external spacing relationships between elements. Margins can be set for all sides with the 'margin' property or individually with 'margin-top', 'margin-right', 'margin-bottom', and 'margin-left'. Margins can also accept negative values to create overlapping effects, and they collapse in certain situations—an important behavior to understand for precise layout control.",
"task": "Add a bottom margin to the section-title element. Set margin-bottom to '30px' to create appropriate spacing between the title and subsequent content. This helps establish visual hierarchy in the document flow.", "task": "Add a bottom margin to the section-title element. Set margin-bottom to '30px' to create appropriate spacing between the title and subsequent content. This helps establish visual hierarchy in the document flow.",
"previewHTML": "<h2 class='section-title'>Important Section</h2><p>This paragraph should have space above it, separating it from the heading.</p>", "previewHTML": "<h2 class='section-title'>Important Section</h2><p>This paragraph should have space above it, separating it from the heading.</p>",
@@ -190,7 +190,7 @@
}, },
{ {
"id": "css-box-model-border", "id": "css-box-model-border",
"title": "CSS Box Model: Working with Borders", "title": "Borders",
"description": "Borders define the perimeter of an element in the CSS box model, positioned between the padding and margin areas. The 'border' property is shorthand that combines border-width, border-style, and border-color properties. You can apply borders to all sides of an element or target specific sides with 'border-top', 'border-right', 'border-bottom', and 'border-left'. Borders serve both functional and aesthetic purposes: they visually separate elements, highlight interactive components, and can become integral parts of your design language.", "description": "Borders define the perimeter of an element in the CSS box model, positioned between the padding and margin areas. The 'border' property is shorthand that combines border-width, border-style, and border-color properties. You can apply borders to all sides of an element or target specific sides with 'border-top', 'border-right', 'border-bottom', and 'border-left'. Borders serve both functional and aesthetic purposes: they visually separate elements, highlight interactive components, and can become integral parts of your design language.",
"task": "Add a border to the card element. Set the border property to '2px solid blue' to create a defined boundary with a distinctive color. This will help the card stand out visually from surrounding content.", "task": "Add a border to the card element. Set the border property to '2px solid blue' to create a defined boundary with a distinctive color. This will help the card stand out visually from surrounding content.",
"previewHTML": "<div class='card'><h3>Card Title</h3><p>This card element needs a defined border to enhance its visibility.</p></div>", "previewHTML": "<div class='card'><h3>Card Title</h3><p>This card element needs a defined border to enhance its visibility.</p></div>",
@@ -221,7 +221,7 @@
}, },
{ {
"id": "css-centering-techniques", "id": "css-centering-techniques",
"title": "Horizontal and Vertical Centering", "title": "Centering",
"description": "Centering elements in CSS has historically been challenging, but modern approaches have simplified this task. For horizontal centering, we can use 'margin: 0 auto' for block elements with a defined width, or 'text-align: center' for inline elements. Vertical centering often employs flexbox or grid layouts. Flexbox, in particular, offers a straightforward solution with 'display: flex', 'justify-content: center' (horizontal centering), and 'align-items: center' (vertical centering). Understanding centering techniques is crucial for creating balanced and visually appealing layouts.", "description": "Centering elements in CSS has historically been challenging, but modern approaches have simplified this task. For horizontal centering, we can use 'margin: 0 auto' for block elements with a defined width, or 'text-align: center' for inline elements. Vertical centering often employs flexbox or grid layouts. Flexbox, in particular, offers a straightforward solution with 'display: flex', 'justify-content: center' (horizontal centering), and 'align-items: center' (vertical centering). Understanding centering techniques is crucial for creating balanced and visually appealing layouts.",
"task": "Center the button both horizontally and vertically within its container by adding the correct flexbox properties. The container is already set to 'display: flex', so you need to add both 'justify-content: center' and 'align-items: center' properties.", "task": "Center the button both horizontally and vertically within its container by adding the correct flexbox properties. The container is already set to 'display: flex', so you need to add both 'justify-content: center' and 'align-items: center' properties.",
"previewHTML": "<div class='button-container'><button>Centered Button</button></div>", "previewHTML": "<div class='button-container'><button>Centered Button</button></div>",
@@ -274,7 +274,7 @@
}, },
{ {
"id": "css-colors-hex-rgb", "id": "css-colors-hex-rgb",
"title": "Color Systems: Hexadecimal and Named Colors", "title": "Color Values",
"description": "CSS supports multiple color representation systems. Hexadecimal notation uses a pound sign (#) followed by 3 or 6 characters representing RGB values in base-16 format (e.g., #f00 or #ff0000 for red). CSS also provides named colors like 'red', 'blue', and 'orange' for common colors. Named colors are easier to remember, while hex colors provide more precise control. Understanding different color systems is essential for controlling the visual appearance of your web elements.", "description": "CSS supports multiple color representation systems. Hexadecimal notation uses a pound sign (#) followed by 3 or 6 characters representing RGB values in base-16 format (e.g., #f00 or #ff0000 for red). CSS also provides named colors like 'red', 'blue', and 'orange' for common colors. Named colors are easier to remember, while hex colors provide more precise control. Understanding different color systems is essential for controlling the visual appearance of your web elements.",
"task": "Set the background color of the element to 'orange' using a named color. Named colors are more readable in code than hexadecimal values and are perfect for common colors.", "task": "Set the background color of the element to 'orange' using a named color. Named colors are more readable in code than hexadecimal values and are perfect for common colors.",
"previewHTML": "<div class='color-block'>This element needs an orange background color</div>", "previewHTML": "<div class='color-block'>This element needs an orange background color</div>",
@@ -305,7 +305,7 @@
}, },
{ {
"id": "css-typography-font-family", "id": "css-typography-font-family",
"title": "Typography: Font Family and Font Stacks", "title": "Font Family",
"description": "The font-family property defines the typeface used for text content. Best practice dictates providing a 'font stack'—a comma-separated list of fonts in descending order of preference. If the first font isn't available on the user's system, the browser moves to the next font in the stack. The stack typically ends with a generic font family (serif, sans-serif, monospace, etc.) as a reliable fallback. Well-designed font stacks ensure consistent typographic appearance across different operating systems and devices.", "description": "The font-family property defines the typeface used for text content. Best practice dictates providing a 'font stack'—a comma-separated list of fonts in descending order of preference. If the first font isn't available on the user's system, the browser moves to the next font in the stack. The stack typically ends with a generic font family (serif, sans-serif, monospace, etc.) as a reliable fallback. Well-designed font stacks ensure consistent typographic appearance across different operating systems and devices.",
"task": "Set the font family of the element to use 'Courier, monospace'. This creates a font stack where 'Courier' is the first choice and 'monospace' ensures a final generic fallback option is available, creating a typewriter-like effect for the text.", "task": "Set the font family of the element to use 'Courier, monospace'. This creates a font stack where 'Courier' is the first choice and 'monospace' ensures a final generic fallback option is available, creating a typewriter-like effect for the text.",
"previewHTML": "<p class='styled-text'>This text needs a monospace font applied to it. Notice how each character takes up the same width in monospace fonts.</p>", "previewHTML": "<p class='styled-text'>This text needs a monospace font applied to it. Notice how each character takes up the same width in monospace fonts.</p>",
@@ -336,7 +336,7 @@
}, },
{ {
"id": "css-units-relative-absolute", "id": "css-units-relative-absolute",
"title": "CSS Units: Comparing Relative and Absolute Measurements", "title": "Units",
"description": "CSS offers various measurement units, categorized as either relative or absolute. Relative units (like %, em, rem, vh, vw) scale based on other factors and are essential for responsive design. For instance, 'rem' units scale relative to the root element's font size, while '%' units are proportional to parent element dimensions. Absolute units (like px, pt, cm, in) maintain fixed dimensions regardless of context. Modern web development favors relative units for their adaptability across different screen sizes and user preferences, especially for accessible design.", "description": "CSS offers various measurement units, categorized as either relative or absolute. Relative units (like %, em, rem, vh, vw) scale based on other factors and are essential for responsive design. For instance, 'rem' units scale relative to the root element's font size, while '%' units are proportional to parent element dimensions. Absolute units (like px, pt, cm, in) maintain fixed dimensions regardless of context. Modern web development favors relative units for their adaptability across different screen sizes and user preferences, especially for accessible design.",
"task": "Set the width of the responsive element to '80%' of its parent container and its font-size to '18px'. Percentage width enables the element to adapt to different screen sizes, while pixel units provide precise control for font sizes.", "task": "Set the width of the responsive element to '80%' of its parent container and its font-size to '18px'. Percentage width enables the element to adapt to different screen sizes, while pixel units provide precise control for font sizes.",
"previewHTML": "<div class='container'><div class='responsive-element'>This element should have responsive width and font size.</div></div>", "previewHTML": "<div class='container'><div class='responsive-element'>This element should have responsive width and font size.</div></div>",
@@ -389,7 +389,7 @@
}, },
{ {
"id": "css-specificity", "id": "css-specificity",
"title": "CSS Specificity: Understanding Rule Precedence", "title": "Specificity",
"description": "CSS specificity determines which styles are applied 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. The specificity value can be conceptualized as a four-part score (inline, ID, class, element). Understanding specificity is crucial for predictable styling and debugging CSS conflicts.", "description": "CSS specificity determines which styles are applied 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. The specificity value can be conceptualized as a four-part score (inline, ID, class, element). Understanding specificity is crucial for predictable styling and debugging CSS conflicts.",
"task": "Look at the two rules targeting paragraph text. Based on CSS specificity, determine which text color will be applied to the paragraph with class 'highlight' by completing the rule using either '#ff0000' (red) or '#0000ff' (blue).", "task": "Look at the two rules targeting paragraph text. Based on CSS specificity, determine which text color will be applied to the paragraph with class 'highlight' by completing the rule using either '#ff0000' (red) or '#0000ff' (blue).",
"previewHTML": "<p class='highlight'>Which color will this paragraph have?</p>", "previewHTML": "<p class='highlight'>Which color will this paragraph have?</p>",
@@ -412,7 +412,7 @@
}, },
{ {
"id": "css-layout-display-property", "id": "css-layout-display-property",
"title": "CSS Layout: The Display Property", "title": "Display",
"description": "The 'display' property defines how an element behaves in the document flow and in relation to other elements. Common values include 'block', 'inline', 'inline-block', 'flex', 'grid', and 'none'. Block elements start on a new line and take up the full width available, inline elements flow within the text and only take up as much width as necessary, and inline-block elements combine aspects of both. The display property is fundamental to controlling layout in CSS and serves as the foundation for more complex positioning techniques.", "description": "The 'display' property defines how an element behaves in the document flow and in relation to other elements. Common values include 'block', 'inline', 'inline-block', 'flex', 'grid', and 'none'. Block elements start on a new line and take up the full width available, inline elements flow within the text and only take up as much width as necessary, and inline-block elements combine aspects of both. The display property is fundamental to controlling layout in CSS and serves as the foundation for more complex positioning techniques.",
"task": "Change the display property of the span element to 'block' to make it behave like a block-level element rather than an inline element. This will make it start on a new line and take up the full width available.", "task": "Change the display property of the span element to 'block' to make it behave like a block-level element rather than an inline element. This will make it start on a new line and take up the full width available.",
"previewHTML": "<p>This is a paragraph with <span class='block-me'>a span that should become</span> a block element.</p>", "previewHTML": "<p>This is a paragraph with <span class='block-me'>a span that should become</span> a block element.</p>",
@@ -446,7 +446,7 @@
}, },
{ {
"id": "css-flexbox-basics", "id": "css-flexbox-basics",
"title": "CSS Flexbox: Container and Items", "title": "Flex Basics",
"description": "Flexbox is a powerful layout model that makes it easier to design flexible responsive layouts. It consists of flex containers and flex items. The container is the parent element with 'display: flex' or 'display: inline-flex' set, while items are the direct children within. Flexbox provides properties for controlling direction, alignment, order, and proportions of items. With flexbox, complex layouts that would require tricky positioning and floats can be achieved with much cleaner and more maintainable code.", "description": "Flexbox is a powerful layout model that makes it easier to design flexible responsive layouts. It consists of flex containers and flex items. The container is the parent element with 'display: flex' or 'display: inline-flex' set, while items are the direct children within. Flexbox provides properties for controlling direction, alignment, order, and proportions of items. With flexbox, complex layouts that would require tricky positioning and floats can be achieved with much cleaner and more maintainable code.",
"task": "Create a basic flexbox container by adding 'display: flex' to the parent element. Then set flex-direction to 'row' to make the items display horizontally (this is the default behavior, but it's good to specify it explicitly).", "task": "Create a basic flexbox container by adding 'display: flex' to the parent element. Then set flex-direction to 'row' to make the items display horizontally (this is the default behavior, but it's good to specify it explicitly).",
"previewHTML": "<div class='flex-container'><div class='flex-item'>Item 1</div><div class='flex-item'>Item 2</div><div class='flex-item'>Item 3</div></div>", "previewHTML": "<div class='flex-container'><div class='flex-item'>Item 1</div><div class='flex-item'>Item 2</div><div class='flex-item'>Item 3</div></div>",

View File

@@ -1,13 +1,13 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "css-advanced-selectors", "id": "css-advanced-selectors",
"title": "CSS: Advanced Selectors", "title": "Adv. Selectors",
"description": "Master advanced CSS selector techniques including attribute selectors, combinators, and pseudo-classes. This module builds on basic selectors to give you precise control over element targeting, enabling sophisticated styling patterns and interactive effects.", "description": "Master advanced CSS selector techniques including attribute selectors, combinators, and pseudo-classes. This module builds on basic selectors to give you precise control over element targeting, enabling sophisticated styling patterns and interactive effects.",
"difficulty": "intermediate", "difficulty": "intermediate",
"lessons": [ "lessons": [
{ {
"id": "attribute-selectors", "id": "attribute-selectors",
"title": "Attribute Selectors: Targeting by HTML Attributes", "title": "[attribute]",
"description": "Attribute selectors allow you to target elements based on their HTML attributes and attribute values. They are incredibly powerful for styling forms, links, and other elements with specific attributes. The basic syntax uses square brackets: <kbd>[attribute]</kbd> selects elements with that attribute, <kbd>[attribute=\"value\"]</kbd> selects elements where the attribute equals exactly that value, and <kbd>[attribute^=\"value\"]</kbd> selects elements where the attribute starts with that value. You can style these selected elements using properties like <kbd>border</kbd> to add visual boundaries and <kbd>background-color</kbd> to highlight specific form fields or links.", "description": "Attribute selectors allow you to target elements based on their HTML attributes and attribute values. They are incredibly powerful for styling forms, links, and other elements with specific attributes. The basic syntax uses square brackets: <kbd>[attribute]</kbd> selects elements with that attribute, <kbd>[attribute=\"value\"]</kbd> selects elements where the attribute equals exactly that value, and <kbd>[attribute^=\"value\"]</kbd> selects elements where the attribute starts with that value. You can style these selected elements using properties like <kbd>border</kbd> to add visual boundaries and <kbd>background-color</kbd> to highlight specific form fields or links.",
"task": "Create a CSS rule using an attribute selector that targets all input elements with <kbd>type=\"text\"</kbd>. Give them a <kbd>lightblue</kbd> background and a <kbd>2px solid blue</kbd> border.", "task": "Create a CSS rule using an attribute selector that targets all input elements with <kbd>type=\"text\"</kbd>. Give them a <kbd>lightblue</kbd> background and a <kbd>2px solid blue</kbd> border.",
"previewHTML": "<form>\n <p><label>Name: <input type=\"text\" placeholder=\"Enter your name\"></label></p>\n <p><label>Email: <input type=\"email\" placeholder=\"Enter your email\"></label></p>\n <p><label>Password: <input type=\"password\" placeholder=\"Enter password\"></label></p>\n <p><button type=\"submit\">Submit</button></p>\n</form>", "previewHTML": "<form>\n <p><label>Name: <input type=\"text\" placeholder=\"Enter your name\"></label></p>\n <p><label>Email: <input type=\"email\" placeholder=\"Enter your email\"></label></p>\n <p><label>Password: <input type=\"password\" placeholder=\"Enter password\"></label></p>\n <p><button type=\"submit\">Submit</button></p>\n</form>",
@@ -70,7 +70,7 @@
}, },
{ {
"id": "attribute-partial-matching", "id": "attribute-partial-matching",
"title": "Attribute Partial Matching", "title": "Attr Matching",
"description": "Attribute selectors support partial matching patterns that let you target elements based on portions of attribute values. The <kbd>[attribute^=\"value\"]</kbd> selector matches elements where the attribute starts with the specified value, <kbd>[attribute$=\"value\"]</kbd> matches where it ends with the value, and <kbd>[attribute*=\"value\"]</kbd> matches where the value appears anywhere within the attribute. These patterns are particularly useful for styling external links, file types, or elements with class names that follow naming conventions. When styling these matched elements, you can use properties like <kbd>color</kbd> to change text color and <kbd>text-decoration</kbd> to add visual emphasis like underlines.", "description": "Attribute selectors support partial matching patterns that let you target elements based on portions of attribute values. The <kbd>[attribute^=\"value\"]</kbd> selector matches elements where the attribute starts with the specified value, <kbd>[attribute$=\"value\"]</kbd> matches where it ends with the value, and <kbd>[attribute*=\"value\"]</kbd> matches where the value appears anywhere within the attribute. These patterns are particularly useful for styling external links, file types, or elements with class names that follow naming conventions. When styling these matched elements, you can use properties like <kbd>color</kbd> to change text color and <kbd>text-decoration</kbd> to add visual emphasis like underlines.",
"task": "Create a CSS rule that targets all anchor elements (<kbd>a</kbd>) with <kbd>href</kbd> attributes starting with <kbd>\"https\"</kbd>. Style them with <kbd>green</kbd> text color and <kbd>underline</kbd> text decoration.", "task": "Create a CSS rule that targets all anchor elements (<kbd>a</kbd>) with <kbd>href</kbd> attributes starting with <kbd>\"https\"</kbd>. Style them with <kbd>green</kbd> text color and <kbd>underline</kbd> text decoration.",
"previewHTML": "<h2>Different Types of Links</h2>\n<ul>\n <li><a href=\"https://example.com\">External HTTPS link</a></li>\n <li><a href=\"http://oldsite.com\">External HTTP link</a></li>\n <li><a href=\"#section1\">Internal anchor link</a></li>\n <li><a href=\"/about\">Relative link</a></li>\n <li><a href=\"https://secure-site.org\">Another HTTPS link</a></li>\n</ul>", "previewHTML": "<h2>Different Types of Links</h2>\n<ul>\n <li><a href=\"https://example.com\">External HTTPS link</a></li>\n <li><a href=\"http://oldsite.com\">External HTTP link</a></li>\n <li><a href=\"#section1\">Internal anchor link</a></li>\n <li><a href=\"/about\">Relative link</a></li>\n <li><a href=\"https://secure-site.org\">Another HTTPS link</a></li>\n</ul>",
@@ -130,7 +130,7 @@
}, },
{ {
"id": "child-combinator", "id": "child-combinator",
"title": "Child Combinator: Direct Children Only", "title": "Child (>)",
"description": "The child combinator (<kbd>></kbd>) selects elements that are direct children of another element, not grandchildren or deeper descendants. This is crucial when you have nested structures where you want to style only the outer level. For example, in a navigation menu with dropdowns, you might want main menu items to have different styling than submenu items. The child combinator (<kbd>></kbd>) gives you surgical precision - <kbd>ul > li</kbd> targets only direct list items, while <kbd>ul li</kbd> would target ALL list items including nested ones. This prevents style inheritance chaos in complex layouts.", "description": "The child combinator (<kbd>></kbd>) selects elements that are direct children of another element, not grandchildren or deeper descendants. This is crucial when you have nested structures where you want to style only the outer level. For example, in a navigation menu with dropdowns, you might want main menu items to have different styling than submenu items. The child combinator (<kbd>></kbd>) gives you surgical precision - <kbd>ul > li</kbd> targets only direct list items, while <kbd>ul li</kbd> would target ALL list items including nested ones. This prevents style inheritance chaos in complex layouts.",
"task": "Use the child combinator to target only the direct <kbd>li</kbd> children of <kbd>.main-nav</kbd>. Give them a <kbd>cornflowerblue</kbd> background and <kbd>white</kbd> text color. Notice how the nested submenu items remain completely unstyled!", "task": "Use the child combinator to target only the direct <kbd>li</kbd> children of <kbd>.main-nav</kbd>. Give them a <kbd>cornflowerblue</kbd> background and <kbd>white</kbd> text color. Notice how the nested submenu items remain completely unstyled!",
"previewHTML": "<ul class=\"main-nav\">\n <li>🏠 Home</li>\n <li>📱 Products\n <ul>\n <li>💻 Laptops</li>\n <li>📱 Phones</li>\n <li>⌚ Watches</li>\n </ul>\n </li>\n <li> About\n <ul>\n <li>👥 Team</li>\n <li>📍 Location</li>\n </ul>\n </li>\n <li>📧 Contact</li>\n</ul>", "previewHTML": "<ul class=\"main-nav\">\n <li>🏠 Home</li>\n <li>📱 Products\n <ul>\n <li>💻 Laptops</li>\n <li>📱 Phones</li>\n <li>⌚ Watches</li>\n </ul>\n </li>\n <li> About\n <ul>\n <li>👥 Team</li>\n <li>📍 Location</li>\n </ul>\n </li>\n <li>📧 Contact</li>\n</ul>",
@@ -188,7 +188,7 @@
}, },
{ {
"id": "descendant-combinator", "id": "descendant-combinator",
"title": "Descendant Combinator: All Nested Elements", "title": "Descendant",
"description": "The descendant combinator uses a space between selectors to target elements that are nested anywhere inside other elements, regardless of how deeply nested they are. For example, <kbd>nav a</kbd> selects all anchor elements inside navigation elements, whether they're direct children or nested several levels deep. This is broader than the child combinator and is useful for applying consistent styling to all elements of a certain type within a container. When styling descendants, you can use properties like <kbd>text-decoration</kbd> to control link appearance and <kbd>color</kbd> to set consistent text colors throughout a section. The descendant combinator is one of the most commonly used combinators in CSS.", "description": "The descendant combinator uses a space between selectors to target elements that are nested anywhere inside other elements, regardless of how deeply nested they are. For example, <kbd>nav a</kbd> selects all anchor elements inside navigation elements, whether they're direct children or nested several levels deep. This is broader than the child combinator and is useful for applying consistent styling to all elements of a certain type within a container. When styling descendants, you can use properties like <kbd>text-decoration</kbd> to control link appearance and <kbd>color</kbd> to set consistent text colors throughout a section. The descendant combinator is one of the most commonly used combinators in CSS.",
"task": "Use the descendant combinator to target all anchor elements (<kbd>a</kbd>) inside the <kbd>nav</kbd> element. Remove their underlines with <kbd>text-decoration: none</kbd> and make them <kbd>blue</kbd>.", "task": "Use the descendant combinator to target all anchor elements (<kbd>a</kbd>) inside the <kbd>nav</kbd> element. Remove their underlines with <kbd>text-decoration: none</kbd> and make them <kbd>blue</kbd>.",
"previewHTML": "<nav>\n <ul>\n <li><a href=\"#\">Home</a></li>\n <li><a href=\"#\">About</a>\n <ul>\n <li><a href=\"#\">Our Team</a></li>\n <li><a href=\"#\">History</a></li>\n </ul>\n </li>\n <li><a href=\"#\">Contact</a></li>\n </ul>\n</nav>\n<p>This <a href=\"#\">link outside nav</a> should not be affected.</p>", "previewHTML": "<nav>\n <ul>\n <li><a href=\"#\">Home</a></li>\n <li><a href=\"#\">About</a>\n <ul>\n <li><a href=\"#\">Our Team</a></li>\n <li><a href=\"#\">History</a></li>\n </ul>\n </li>\n <li><a href=\"#\">Contact</a></li>\n </ul>\n</nav>\n<p>This <a href=\"#\">link outside nav</a> should not be affected.</p>",
@@ -246,7 +246,7 @@
}, },
{ {
"id": "adjacent-sibling-combinator", "id": "adjacent-sibling-combinator",
"title": "Adjacent Sibling Combinator: The Next Element", "title": "Adjacent (+)",
"description": "The adjacent sibling combinator (<kbd>+</kbd>) selects an element that immediately follows another element at the same level in the HTML structure. Both elements must share the same parent, and there can be no other elements between them. For example, <kbd>h1 + p</kbd> selects paragraph elements that come directly after h1 headings. This combinator is particularly useful for styling elements that have special relationships, like the first paragraph after a heading, or labels that follow form inputs. When styling adjacent siblings, you can use properties like <kbd>margin-top</kbd> to adjust spacing and <kbd>font-style</kbd> to add emphasis like italics to create visual hierarchy.", "description": "The adjacent sibling combinator (<kbd>+</kbd>) selects an element that immediately follows another element at the same level in the HTML structure. Both elements must share the same parent, and there can be no other elements between them. For example, <kbd>h1 + p</kbd> selects paragraph elements that come directly after h1 headings. This combinator is particularly useful for styling elements that have special relationships, like the first paragraph after a heading, or labels that follow form inputs. When styling adjacent siblings, you can use properties like <kbd>margin-top</kbd> to adjust spacing and <kbd>font-style</kbd> to add emphasis like italics to create visual hierarchy.",
"task": "Use the adjacent sibling combinator to target paragraphs that immediately follow <kbd>h2</kbd> headings. Remove their top margin with <kbd>margin-top: 0</kbd> and make them italic.", "task": "Use the adjacent sibling combinator to target paragraphs that immediately follow <kbd>h2</kbd> headings. Remove their top margin with <kbd>margin-top: 0</kbd> and make them italic.",
"previewHTML": "<h2>First Heading</h2>\n<p>This paragraph directly follows h2 (should be affected).</p>\n<p>This paragraph comes after another paragraph (should NOT be affected).</p>\n<h2>Second Heading</h2>\n<p>This paragraph also directly follows h2 (should be affected).</p>\n<div>This div comes after h2 but is not a paragraph.</div>\n<p>This paragraph comes after a div (should NOT be affected).</p>", "previewHTML": "<h2>First Heading</h2>\n<p>This paragraph directly follows h2 (should be affected).</p>\n<p>This paragraph comes after another paragraph (should NOT be affected).</p>\n<h2>Second Heading</h2>\n<p>This paragraph also directly follows h2 (should be affected).</p>\n<div>This div comes after h2 but is not a paragraph.</div>\n<p>This paragraph comes after a div (should NOT be affected).</p>",
@@ -304,7 +304,7 @@
}, },
{ {
"id": "general-sibling-combinator", "id": "general-sibling-combinator",
"title": "General Sibling Combinator: All Following Siblings", "title": "Sibling (~)",
"description": "The general sibling combinator (<kbd>~</kbd>) selects all elements that follow another element at the same level, not just the immediately adjacent one. Unlike the adjacent sibling combinator, there can be other elements between the target elements, as long as they all share the same parent and the selected elements come after the reference element. For example, <kbd>h2 ~ p</kbd> selects all paragraph elements that appear after any h2 heading at the same level. When styling general siblings, you can use properties like <kbd>color</kbd> to change text color and <kbd>padding-left</kbd> to create visual indentation, helping to show the relationship between related content sections.", "description": "The general sibling combinator (<kbd>~</kbd>) selects all elements that follow another element at the same level, not just the immediately adjacent one. Unlike the adjacent sibling combinator, there can be other elements between the target elements, as long as they all share the same parent and the selected elements come after the reference element. For example, <kbd>h2 ~ p</kbd> selects all paragraph elements that appear after any h2 heading at the same level. When styling general siblings, you can use properties like <kbd>color</kbd> to change text color and <kbd>padding-left</kbd> to create visual indentation, helping to show the relationship between related content sections.",
"task": "Use the general sibling combinator to target all paragraphs that come after the <kbd>h3</kbd> heading (at the same level). Give them a <kbd>gray</kbd> color and <kbd>20px</kbd> of left padding.", "task": "Use the general sibling combinator to target all paragraphs that come after the <kbd>h3</kbd> heading (at the same level). Give them a <kbd>gray</kbd> color and <kbd>20px</kbd> of left padding.",
"previewHTML": "<div>\n <p>This paragraph comes before h3 (should NOT be affected).</p>\n <h3>Section Title</h3>\n <p>First paragraph after h3 (should be affected).</p>\n <div>Some other content in between</div>\n <p>Second paragraph after h3 (should also be affected).</p>\n <span>More content</span>\n <p>Third paragraph after h3 (should also be affected).</p>\n</div>", "previewHTML": "<div>\n <p>This paragraph comes before h3 (should NOT be affected).</p>\n <h3>Section Title</h3>\n <p>First paragraph after h3 (should be affected).</p>\n <div>Some other content in between</div>\n <p>Second paragraph after h3 (should also be affected).</p>\n <span>More content</span>\n <p>Third paragraph after h3 (should also be affected).</p>\n</div>",
@@ -362,7 +362,7 @@
}, },
{ {
"id": "hover-pseudo-class", "id": "hover-pseudo-class",
"title": "The :hover Pseudo-Class", "title": ":hover",
"description": "The <kbd>:hover</kbd> pseudo-class applies styles when a user hovers their mouse over an element. This creates interactive feedback that improves user experience by providing visual cues about clickable or interactive elements. Hover effects are commonly used on links, buttons, and other interactive elements to indicate their interactive nature. When creating hover effects, you can use properties like <kbd>background-color</kbd> to change the background on hover and <kbd>color</kbd> to change text color, creating clear visual feedback. The <kbd>:hover</kbd> pseudo-class only applies while the mouse cursor is positioned over the element, reverting to the normal state when the cursor moves away.", "description": "The <kbd>:hover</kbd> pseudo-class applies styles when a user hovers their mouse over an element. This creates interactive feedback that improves user experience by providing visual cues about clickable or interactive elements. Hover effects are commonly used on links, buttons, and other interactive elements to indicate their interactive nature. When creating hover effects, you can use properties like <kbd>background-color</kbd> to change the background on hover and <kbd>color</kbd> to change text color, creating clear visual feedback. The <kbd>:hover</kbd> pseudo-class only applies while the mouse cursor is positioned over the element, reverting to the normal state when the cursor moves away.",
"task": "Create a hover effect for the button element. On hover, change the background to <kbd>darkblue</kbd> and the text color to <kbd>white</kbd>.", "task": "Create a hover effect for the button element. On hover, change the background to <kbd>darkblue</kbd> and the text color to <kbd>white</kbd>.",
"previewHTML": "<h2>Interactive Button</h2>\n<p>Hover over the button below to see the effect:</p>\n<button type=\"button\">Hover Over Me</button>\n<p>The button should change colors when you hover over it.</p>", "previewHTML": "<h2>Interactive Button</h2>\n<p>Hover over the button below to see the effect:</p>\n<button type=\"button\">Hover Over Me</button>\n<p>The button should change colors when you hover over it.</p>",
@@ -420,7 +420,7 @@
}, },
{ {
"id": "first-child-pseudo-class", "id": "first-child-pseudo-class",
"title": "The :first-child Pseudo-Class", "title": ":first-child",
"description": "The <kbd>:first-child</kbd> pseudo-class selects elements that are the first child of their parent element. This is useful for applying special styling to the first item in lists, the first paragraph in articles, or the first element in any container. For example, <kbd>li:first-child</kbd> selects the first list item in each list, while <kbd>p:first-child</kbd> selects paragraphs that are the first child element of their container. When styling first children, you can use properties like <kbd>font-weight</kbd> to make the first item bold and <kbd>margin-top</kbd> to adjust spacing, helping create visual hierarchy and improve the layout of your content.", "description": "The <kbd>:first-child</kbd> pseudo-class selects elements that are the first child of their parent element. This is useful for applying special styling to the first item in lists, the first paragraph in articles, or the first element in any container. For example, <kbd>li:first-child</kbd> selects the first list item in each list, while <kbd>p:first-child</kbd> selects paragraphs that are the first child element of their container. When styling first children, you can use properties like <kbd>font-weight</kbd> to make the first item bold and <kbd>margin-top</kbd> to adjust spacing, helping create visual hierarchy and improve the layout of your content.",
"task": "Use the <kbd>:first-child</kbd> pseudo-class to target the first list item in each list. Make it <kbd>bold</kbd> and remove its top margin.", "task": "Use the <kbd>:first-child</kbd> pseudo-class to target the first list item in each list. Make it <kbd>bold</kbd> and remove its top margin.",
"previewHTML": "<h2>Multiple Lists</h2>\n<h3>Fruits</h3>\n<ul>\n <li>Apple (first child)</li>\n <li>Banana</li>\n <li>Orange</li>\n</ul>\n<h3>Colors</h3>\n<ul>\n <li>Red (first child)</li>\n <li>Blue</li>\n <li>Green</li>\n</ul>", "previewHTML": "<h2>Multiple Lists</h2>\n<h3>Fruits</h3>\n<ul>\n <li>Apple (first child)</li>\n <li>Banana</li>\n <li>Orange</li>\n</ul>\n<h3>Colors</h3>\n<ul>\n <li>Red (first child)</li>\n <li>Blue</li>\n <li>Green</li>\n</ul>",

View File

@@ -1,13 +1,13 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "css-carousels", "id": "css-carousels",
"title": "CSS Carousels", "title": "Carousels",
"description": "Learn to create modern, accessible carousels using pure CSS with scroll snapping, scroll buttons, and scroll markers. This module covers advanced CSS features that enable interactive carousel components without JavaScript, focusing on responsive design and user accessibility.", "description": "Learn to create modern, accessible carousels using pure CSS with scroll snapping, scroll buttons, and scroll markers. This module covers advanced CSS features that enable interactive carousel components without JavaScript, focusing on responsive design and user accessibility.",
"difficulty": "intermediate", "difficulty": "intermediate",
"lessons": [ "lessons": [
{ {
"id": "basic-horizontal-scroll", "id": "basic-horizontal-scroll",
"title": "Creating a Basic Horizontal Scroll Container", "title": "Scroll Container",
"description": "Before building carousels, we need to understand how to create horizontally scrolling containers. A scroll container is created by setting the <kbd>overflow-x</kbd> property to <kbd>scroll</kbd> on a container element. This allows content that exceeds the container's width to be scrolled horizontally instead of breaking to new lines or being hidden.", "description": "Before building carousels, we need to understand how to create horizontally scrolling containers. A scroll container is created by setting the <kbd>overflow-x</kbd> property to <kbd>scroll</kbd> on a container element. This allows content that exceeds the container's width to be scrolled horizontally instead of breaking to new lines or being hidden.",
"task": "Create a horizontal scroll container by setting <kbd>overflow-x: scroll</kbd> on the <kbd>.container</kbd> element. This will allow the wide content inside to scroll horizontally.", "task": "Create a horizontal scroll container by setting <kbd>overflow-x: scroll</kbd> on the <kbd>.container</kbd> element. This will allow the wide content inside to scroll horizontally.",
"previewHTML": "<div class=\"container\">\n <div class=\"item\">Item 1</div>\n <div class=\"item\">Item 2</div>\n <div class=\"item\">Item 3</div>\n <div class=\"item\">Item 4</div>\n <div class=\"item\">Item 5</div>\n</div>", "previewHTML": "<div class=\"container\">\n <div class=\"item\">Item 1</div>\n <div class=\"item\">Item 2</div>\n <div class=\"item\">Item 3</div>\n <div class=\"item\">Item 4</div>\n <div class=\"item\">Item 5</div>\n</div>",
@@ -41,7 +41,7 @@
}, },
{ {
"id": "scroll-snap-introduction", "id": "scroll-snap-introduction",
"title": "Adding Scroll Snap Behavior", "title": "Scroll Snap",
"description": "Scroll snapping makes carousels feel more polished by ensuring that items align properly after scrolling. The <kbd>scroll-snap-type</kbd> property is applied to the scroll container, while <kbd>scroll-snap-align</kbd> is applied to the items inside. The <kbd>x mandatory</kbd> value means horizontal snapping is required.", "description": "Scroll snapping makes carousels feel more polished by ensuring that items align properly after scrolling. The <kbd>scroll-snap-type</kbd> property is applied to the scroll container, while <kbd>scroll-snap-align</kbd> is applied to the items inside. The <kbd>x mandatory</kbd> value means horizontal snapping is required.",
"task": "Add scroll snapping to the container by setting <kbd>scroll-snap-type: x mandatory</kbd>. Then add <kbd>scroll-snap-align: center</kbd> to the items so they snap to the center of the container.", "task": "Add scroll snapping to the container by setting <kbd>scroll-snap-type: x mandatory</kbd>. Then add <kbd>scroll-snap-align: center</kbd> to the items so they snap to the center of the container.",
"previewHTML": "<div class=\"container\">\n <div class=\"item\">Item 1</div>\n <div class=\"item\">Item 2</div>\n <div class=\"item\">Item 3</div>\n <div class=\"item\">Item 4</div>\n <div class=\"item\">Item 5</div>\n</div>\n<p>Try scrolling in the container above - items should snap into place!</p>", "previewHTML": "<div class=\"container\">\n <div class=\"item\">Item 1</div>\n <div class=\"item\">Item 2</div>\n <div class=\"item\">Item 3</div>\n <div class=\"item\">Item 4</div>\n <div class=\"item\">Item 5</div>\n</div>\n<p>Try scrolling in the container above - items should snap into place!</p>",
@@ -77,7 +77,7 @@
}, },
{ {
"id": "flexbox-carousel-layout", "id": "flexbox-carousel-layout",
"title": "Building a Full-Width Item Carousel with Flexbox", "title": "Full-Width Items",
"description": "For carousels where each item takes the full width (like image slideshows), we use flexbox with <kbd>flex: 0 0 100%</kbd> on each item. This means: no grow (0), no shrink (0), and take 100% of the container width. Combined with a horizontal gap, this creates distinct pages.", "description": "For carousels where each item takes the full width (like image slideshows), we use flexbox with <kbd>flex: 0 0 100%</kbd> on each item. This means: no grow (0), no shrink (0), and take 100% of the container width. Combined with a horizontal gap, this creates distinct pages.",
"task": "Create a full-width carousel layout using flexbox. Set <kbd>display: flex</kbd> and <kbd>gap: 20px</kbd> on the container, then <kbd>flex: 0 0 100%</kbd> on the items.", "task": "Create a full-width carousel layout using flexbox. Set <kbd>display: flex</kbd> and <kbd>gap: 20px</kbd> on the container, then <kbd>flex: 0 0 100%</kbd> on the items.",
"previewHTML": "<div class=\"carousel\">\n <div class=\"slide\">Slide 1</div>\n <div class=\"slide\">Slide 2</div>\n <div class=\"slide\">Slide 3</div>\n <div class=\"slide\">Slide 4</div>\n</div>", "previewHTML": "<div class=\"carousel\">\n <div class=\"slide\">Slide 1</div>\n <div class=\"slide\">Slide 2</div>\n <div class=\"slide\">Slide 3</div>\n <div class=\"slide\">Slide 4</div>\n</div>",
@@ -113,7 +113,7 @@
}, },
{ {
"id": "scroll-buttons-basic", "id": "scroll-buttons-basic",
"title": "Adding Scroll Buttons", "title": "Scroll Buttons",
"description": "CSS scroll buttons are created using the <kbd>::scroll-button()</kbd> pseudo-element. You specify the direction (left, right, up, down) and set content to make them visible. The browser automatically handles the scrolling behavior and disables buttons when they can't scroll further.", "description": "CSS scroll buttons are created using the <kbd>::scroll-button()</kbd> pseudo-element. You specify the direction (left, right, up, down) and set content to make them visible. The browser automatically handles the scrolling behavior and disables buttons when they can't scroll further.",
"task": "Add scroll buttons by creating <kbd>::scroll-button(left)</kbd> and <kbd>::scroll-button(right)</kbd> pseudo-elements. Set their <kbd>content</kbd> to arrow symbols and style them with a font size and color.", "task": "Add scroll buttons by creating <kbd>::scroll-button(left)</kbd> and <kbd>::scroll-button(right)</kbd> pseudo-elements. Set their <kbd>content</kbd> to arrow symbols and style them with a font size and color.",
"previewHTML": "<div class=\"carousel\">\n <div class=\"slide\">Slide 1</div>\n <div class=\"slide\">Slide 2</div>\n <div class=\"slide\">Slide 3</div>\n <div class=\"slide\">Slide 4</div>\n</div>", "previewHTML": "<div class=\"carousel\">\n <div class=\"slide\">Slide 1</div>\n <div class=\"slide\">Slide 2</div>\n <div class=\"slide\">Slide 3</div>\n <div class=\"slide\">Slide 4</div>\n</div>",
@@ -154,7 +154,7 @@
}, },
{ {
"id": "scroll-markers-introduction", "id": "scroll-markers-introduction",
"title": "Creating Scroll Markers", "title": "Scroll Markers",
"description": "Scroll markers are navigation dots that show your position in the carousel and allow jumping to specific slides. They're created using <kbd>::scroll-marker</kbd> pseudo-elements on the slide items, and collected in a <kbd>::scroll-marker-group</kbd>. The <kbd>scroll-marker-group</kbd> property must be set to <kbd>after</kbd> or <kbd>before</kbd> to enable them.", "description": "Scroll markers are navigation dots that show your position in the carousel and allow jumping to specific slides. They're created using <kbd>::scroll-marker</kbd> pseudo-elements on the slide items, and collected in a <kbd>::scroll-marker-group</kbd>. The <kbd>scroll-marker-group</kbd> property must be set to <kbd>after</kbd> or <kbd>before</kbd> to enable them.",
"task": "Enable scroll markers by setting <kbd>scroll-marker-group: after</kbd> on the carousel. Then style the markers using <kbd>::scroll-marker</kbd> pseudo-elements with circular appearance.", "task": "Enable scroll markers by setting <kbd>scroll-marker-group: after</kbd> on the carousel. Then style the markers using <kbd>::scroll-marker</kbd> pseudo-elements with circular appearance.",
"previewHTML": "<div class=\"carousel\">\n <div class=\"slide\">Slide 1</div>\n <div class=\"slide\">Slide 2</div>\n <div class=\"slide\">Slide 3</div>\n <div class=\"slide\">Slide 4</div>\n</div>", "previewHTML": "<div class=\"carousel\">\n <div class=\"slide\">Slide 1</div>\n <div class=\"slide\">Slide 2</div>\n <div class=\"slide\">Slide 3</div>\n <div class=\"slide\">Slide 4</div>\n</div>",
@@ -195,7 +195,7 @@
}, },
{ {
"id": "active-marker-styling", "id": "active-marker-styling",
"title": "Highlighting the Active Marker", "title": "Active Marker",
"description": "The <kbd>:target-current</kbd> pseudo-class automatically selects the scroll marker that corresponds to the currently visible slide. This is essential for user experience as it shows which slide is active. You can style it differently to indicate the current position.", "description": "The <kbd>:target-current</kbd> pseudo-class automatically selects the scroll marker that corresponds to the currently visible slide. This is essential for user experience as it shows which slide is active. You can style it differently to indicate the current position.",
"task": "Use the <kbd>:target-current</kbd> pseudo-class to highlight the active scroll marker. Change its background color to make it stand out from inactive markers.", "task": "Use the <kbd>:target-current</kbd> pseudo-class to highlight the active scroll marker. Change its background color to make it stand out from inactive markers.",
"previewHTML": "<div class=\"carousel\">\n <div class=\"slide\">Slide 1</div>\n <div class=\"slide\">Slide 2</div>\n <div class=\"slide\">Slide 3</div>\n <div class=\"slide\">Slide 4</div>\n</div>\n<p>Scroll or click markers to see the active state change!</p>", "previewHTML": "<div class=\"carousel\">\n <div class=\"slide\">Slide 1</div>\n <div class=\"slide\">Slide 2</div>\n <div class=\"slide\">Slide 3</div>\n <div class=\"slide\">Slide 4</div>\n</div>\n<p>Scroll or click markers to see the active state change!</p>",
@@ -226,7 +226,7 @@
}, },
{ {
"id": "multi-column-carousel", "id": "multi-column-carousel",
"title": "Multi-Item Carousel with CSS Columns", "title": "Multi-Item",
"description": "For responsive carousels showing multiple items per page, CSS multi-column layout is ideal. Using <kbd>columns: 1</kbd> creates full-width columns, and items flow naturally into each column. The <kbd>::column</kbd> pseudo-element represents each generated column and can have scroll-snap alignment.", "description": "For responsive carousels showing multiple items per page, CSS multi-column layout is ideal. Using <kbd>columns: 1</kbd> creates full-width columns, and items flow naturally into each column. The <kbd>::column</kbd> pseudo-element represents each generated column and can have scroll-snap alignment.",
"task": "Create a multi-item carousel using <kbd>columns: 1</kbd> for the layout and <kbd>scroll-snap-align: center</kbd> on the <kbd>::column</kbd> pseudo-elements to snap to each column.", "task": "Create a multi-item carousel using <kbd>columns: 1</kbd> for the layout and <kbd>scroll-snap-align: center</kbd> on the <kbd>::column</kbd> pseudo-elements to snap to each column.",
"previewHTML": "<div class=\"multi-carousel\">\n <div class=\"item\">Item 1</div>\n <div class=\"item\">Item 2</div>\n <div class=\"item\">Item 3</div>\n <div class=\"item\">Item 4</div>\n <div class=\"item\">Item 5</div>\n <div class=\"item\">Item 6</div>\n <div class=\"item\">Item 7</div>\n <div class=\"item\">Item 8</div>\n</div>", "previewHTML": "<div class=\"multi-carousel\">\n <div class=\"item\">Item 1</div>\n <div class=\"item\">Item 2</div>\n <div class=\"item\">Item 3</div>\n <div class=\"item\">Item 4</div>\n <div class=\"item\">Item 5</div>\n <div class=\"item\">Item 6</div>\n <div class=\"item\">Item 7</div>\n <div class=\"item\">Item 8</div>\n</div>",
@@ -262,7 +262,7 @@
}, },
{ {
"id": "complete-carousel-styling", "id": "complete-carousel-styling",
"title": "Creating a Complete Styled Carousel", "title": "Complete Carousel",
"description": "A professional carousel combines all the features we've learned: scroll snapping, scroll buttons, scroll markers, and proper styling for different states. This includes hover effects, disabled states for buttons, and positioning for optimal user experience.", "description": "A professional carousel combines all the features we've learned: scroll snapping, scroll buttons, scroll markers, and proper styling for different states. This includes hover effects, disabled states for buttons, and positioning for optimal user experience.",
"task": "Complete the carousel by adding hover effects to buttons using <kbd>:hover</kbd>, styling disabled buttons with <kbd>:disabled</kbd>, and ensuring the marker group has proper flexbox layout.", "task": "Complete the carousel by adding hover effects to buttons using <kbd>:hover</kbd>, styling disabled buttons with <kbd>:disabled</kbd>, and ensuring the marker group has proper flexbox layout.",
"previewHTML": "<div class=\"complete-carousel\">\n <div class=\"slide\">🌅 Slide 1</div>\n <div class=\"slide\">🌄 Slide 2</div>\n <div class=\"slide\">🏔️ Slide 3</div>\n <div class=\"slide\">🌊 Slide 4</div>\n <div class=\"slide\">🌆 Slide 5</div>\n</div>", "previewHTML": "<div class=\"complete-carousel\">\n <div class=\"slide\">🌅 Slide 1</div>\n <div class=\"slide\">🌄 Slide 2</div>\n <div class=\"slide\">🏔️ Slide 3</div>\n <div class=\"slide\">🌊 Slide 4</div>\n <div class=\"slide\">🌆 Slide 5</div>\n</div>",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "selectors", "id": "selectors",
"title": "WIP: Specificity", "title": "Specificity",
"description": "Master the art of targeting HTML elements using various CSS selectors, from basics to specificity rules.", "description": "Master the art of targeting HTML elements using various CSS selectors, from basics to specificity rules.",
"difficulty": "beginner", "difficulty": "beginner",
"lessons": [ "lessons": [

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "colors-backgrounds", "id": "colors-backgrounds",
"title": "WIP: Colors & Backgrounds", "title": "Colors",
"description": "Learn how to apply and manipulate colors, backgrounds, and graphical fills using CSS properties.", "description": "Learn how to apply and manipulate colors, backgrounds, and graphical fills using CSS properties.",
"difficulty": "beginner", "difficulty": "beginner",
"lessons": [ "lessons": [

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "typography-fonts", "id": "typography-fonts",
"title": "Typography & Fonts", "title": "Typography",
"description": "Learn how to control text appearance through font selection, sizing, spacing, and decorative effects.", "description": "Learn how to control text appearance through font selection, sizing, spacing, and decorative effects.",
"difficulty": "beginner", "difficulty": "beginner",
"lessons": [ "lessons": [

View File

@@ -1,13 +1,13 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "layouts", "id": "layouts",
"title": "Flexbox & Grid", "title": "Layouts",
"description": "Master modern CSS layout techniques with Flexbox and Grid for responsive, powerful designs.", "description": "Master modern CSS layout techniques with Flexbox and Grid for responsive, powerful designs.",
"difficulty": "intermediate", "difficulty": "intermediate",
"lessons": [ "lessons": [
{ {
"id": "layouts-1", "id": "layouts-1",
"title": "Flexbox Fundamentals", "title": "Flex Basics",
"description": "Learn the core properties of Flexbox to align, distribute space, and order items in a container.", "description": "Learn the core properties of Flexbox to align, distribute space, and order items in a container.",
"task": "Set .flex-container to display: flex, and center its children both horizontally and vertically.", "task": "Set .flex-container to display: flex, and center its children both horizontally and vertically.",
"previewHTML": "<div class=\"flex-container\"><div>1</div><div>2</div><div>3</div></div>", "previewHTML": "<div class=\"flex-container\"><div>1</div><div>2</div><div>3</div></div>",
@@ -25,7 +25,7 @@
}, },
{ {
"id": "layouts-2", "id": "layouts-2",
"title": "Flexbox Advanced Features", "title": "Flex Advanced",
"description": "Control wrapping, ordering, and flexible growth/shrink of items in a flex container.", "description": "Control wrapping, ordering, and flexible growth/shrink of items in a flex container.",
"task": "Allow items to wrap and set .flex-item to flex: 1 1 100px.", "task": "Allow items to wrap and set .flex-item to flex: 1 1 100px.",
"previewHTML": "<div class=\"flex-container\"><div class=\"flex-item\">A</div><div class=\"flex-item\">B</div><div class=\"flex-item\">C</div></div>", "previewHTML": "<div class=\"flex-container\"><div class=\"flex-item\">A</div><div class=\"flex-item\">B</div><div class=\"flex-item\">C</div></div>",
@@ -47,7 +47,7 @@
}, },
{ {
"id": "layouts-3", "id": "layouts-3",
"title": "Grid Layout Basics", "title": "Grid Basics",
"description": "Define grid containers, set rows and columns, and place items in a structured grid.", "description": "Define grid containers, set rows and columns, and place items in a structured grid.",
"task": "Set .grid-container to display: grid with three equal columns and a 1rem gap.", "task": "Set .grid-container to display: grid with three equal columns and a 1rem gap.",
"previewHTML": "<div class=\"grid-container\"><div>1</div><div>2</div><div>3</div><div>4</div></div>", "previewHTML": "<div class=\"grid-container\"><div>1</div><div>2</div><div>3</div><div>4</div></div>",
@@ -76,7 +76,7 @@
}, },
{ {
"id": "layouts-4", "id": "layouts-4",
"title": "Grid Item Placement", "title": "Grid Placement",
"description": "Control the span and position of grid items with grid-column and grid-row.", "description": "Control the span and position of grid items with grid-column and grid-row.",
"task": "Span the first grid item across 2 columns using grid-column: 1 / span 2.", "task": "Span the first grid item across 2 columns using grid-column: 1 / span 2.",
"previewHTML": "<div class=\"grid-container\"><div class=\"item1\">Featured</div><div>2</div><div>3</div><div>4</div></div>", "previewHTML": "<div class=\"grid-container\"><div class=\"item1\">Featured</div><div>2</div><div>3</div><div>4</div></div>",

View File

@@ -1,14 +1,14 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "tailwind-basics", "id": "tailwind-basics",
"title": "Tailwind: Basics", "title": "Tailwind",
"description": "Learn how Tailwind CSS revolutionizes styling by replacing traditional CSS selectors with utility-first classes. Understand the philosophy behind utility classes and how they solve common CSS problems like specificity conflicts and maintenance complexity.", "description": "Learn how Tailwind CSS revolutionizes styling by replacing traditional CSS selectors with utility-first classes. Understand the philosophy behind utility classes and how they solve common CSS problems like specificity conflicts and maintenance complexity.",
"mode": "tailwind", "mode": "tailwind",
"difficulty": "beginner", "difficulty": "beginner",
"lessons": [ "lessons": [
{ {
"id": "bg-colors", "id": "bg-colors",
"title": "Background Colors", "title": "Backgrounds",
"description": "Learn to apply background colors using Tailwind utilities.", "description": "Learn to apply background colors using Tailwind utilities.",
"task": "Add a blue background to the div using Tailwind classes.", "task": "Add a blue background to the div using Tailwind classes.",
"previewHTML": "<div class=\"{{USER_CLASSES}} p-8 rounded\">Hello Tailwind!</div>", "previewHTML": "<div class=\"{{USER_CLASSES}} p-8 rounded\">Hello Tailwind!</div>",
@@ -26,7 +26,7 @@
}, },
{ {
"id": "utility-first-philosophy", "id": "utility-first-philosophy",
"title": "Understanding Utility-First Design", "title": "Utility-First",
"description": "Tailwind CSS follows a utility-first approach where instead of writing custom CSS classes, you compose designs using small, single-purpose utility classes. Unlike traditional CSS where you might write <kbd>.card { background: white; padding: 1rem; border-radius: 0.5rem; }</kbd>, Tailwind provides pre-built utilities like <kbd>bg-white</kbd>, <kbd>p-4</kbd>, and <kbd>rounded</kbd>.<br><br>The <kbd>bg-white</kbd> utility sets <kbd>background-color: white</kbd>, <kbd>p-4</kbd> applies <kbd>padding: 1rem</kbd> on all sides, and <kbd>rounded</kbd> adds <kbd>border-radius: 0.25rem</kbd>. This approach eliminates the need to context-switch between HTML and CSS files.", "description": "Tailwind CSS follows a utility-first approach where instead of writing custom CSS classes, you compose designs using small, single-purpose utility classes. Unlike traditional CSS where you might write <kbd>.card { background: white; padding: 1rem; border-radius: 0.5rem; }</kbd>, Tailwind provides pre-built utilities like <kbd>bg-white</kbd>, <kbd>p-4</kbd>, and <kbd>rounded</kbd>.<br><br>The <kbd>bg-white</kbd> utility sets <kbd>background-color: white</kbd>, <kbd>p-4</kbd> applies <kbd>padding: 1rem</kbd> on all sides, and <kbd>rounded</kbd> adds <kbd>border-radius: 0.25rem</kbd>. This approach eliminates the need to context-switch between HTML and CSS files.",
"task": "Create a white card-like container with a small drop-shadow, 1rem padding and rounded corners.", "task": "Create a white card-like container with a small drop-shadow, 1rem padding and rounded corners.",
"previewHTML": "<div class=\"bg-gray-100 h-72 p-6\">\n <div class=\"{{USER_CLASSES}}\">\n <h3 class=\"text-lg font-semibold mb-2\">Card Title</h3>\n <p class=\"text-gray-600\">This is a card component built entirely with utility classes!</p>\n </div>\n</div>", "previewHTML": "<div class=\"bg-gray-100 h-72 p-6\">\n <div class=\"{{USER_CLASSES}}\">\n <h3 class=\"text-lg font-semibold mb-2\">Card Title</h3>\n <p class=\"text-gray-600\">This is a card component built entirely with utility classes!</p>\n </div>\n</div>",
@@ -59,7 +59,7 @@
}, },
{ {
"id": "text-utilities", "id": "text-utilities",
"title": "Text Color and Size Utilities", "title": "Text Utilities",
"description": "Tailwind provides comprehensive text utilities for styling typography. Text colors use the pattern <kbd>text-{color}-{shade}</kbd> where colors include red, blue, green, etc., and shades range from 50 (lightest) to 950 (darkest). For example, <kbd>text-blue-600</kbd> applies a medium blue color.<br><br>Text sizes follow the pattern <kbd>text-{size}</kbd> with options like <kbd>text-sm</kbd> (0.875rem), <kbd>text-base</kbd> (1rem), <kbd>text-lg</kbd> (1.125rem), <kbd>text-xl</kbd> (1.25rem), and larger sizes up to <kbd>text-9xl</kbd>. Font weights use <kbd>font-{weight}</kbd> such as <kbd>font-normal</kbd>, <kbd>font-medium</kbd>, <kbd>font-semibold</kbd>, and <kbd>font-bold</kbd>.", "description": "Tailwind provides comprehensive text utilities for styling typography. Text colors use the pattern <kbd>text-{color}-{shade}</kbd> where colors include red, blue, green, etc., and shades range from 50 (lightest) to 950 (darkest). For example, <kbd>text-blue-600</kbd> applies a medium blue color.<br><br>Text sizes follow the pattern <kbd>text-{size}</kbd> with options like <kbd>text-sm</kbd> (0.875rem), <kbd>text-base</kbd> (1rem), <kbd>text-lg</kbd> (1.125rem), <kbd>text-xl</kbd> (1.25rem), and larger sizes up to <kbd>text-9xl</kbd>. Font weights use <kbd>font-{weight}</kbd> such as <kbd>font-normal</kbd>, <kbd>font-medium</kbd>, <kbd>font-semibold</kbd>, and <kbd>font-bold</kbd>.",
"task": "Style the heading with <kbd>text-blue-600</kbd> for color, <kbd>text-2xl</kbd> for size, and <kbd>font-bold</kbd> for weight.", "task": "Style the heading with <kbd>text-blue-600</kbd> for color, <kbd>text-2xl</kbd> for size, and <kbd>font-bold</kbd> for weight.",
"previewHTML": "<div class=\"p-6 bg-gray-50\">\n <h1 class=\"{{USER_CLASSES}} mb-4\">Welcome to Tailwind CSS</h1>\n <p class=\"text-gray-700\">This heading demonstrates text utilities in action.</p>\n</div>", "previewHTML": "<div class=\"p-6 bg-gray-50\">\n <h1 class=\"{{USER_CLASSES}} mb-4\">Welcome to Tailwind CSS</h1>\n <p class=\"text-gray-700\">This heading demonstrates text utilities in action.</p>\n</div>",
@@ -87,7 +87,7 @@
}, },
{ {
"id": "spacing-utilities", "id": "spacing-utilities",
"title": "Spacing with Padding and Margin", "title": "Spacing",
"description": "Tailwind's spacing utilities follow a consistent pattern using a spacing scale where each unit represents 0.25rem (4px). Padding utilities use <kbd>p-{size}</kbd> for all sides, <kbd>px-{size}</kbd> for horizontal (left/right), <kbd>py-{size}</kbd> for vertical (top/bottom), or individual sides like <kbd>pt-{size}</kbd>, <kbd>pr-{size}</kbd>, <kbd>pb-{size}</kbd>, <kbd>pl-{size}</kbd>.<br><br>Common sizes include <kbd>p-2</kbd> (0.5rem), <kbd>p-4</kbd> (1rem), <kbd>p-6</kbd> (1.5rem), and <kbd>p-8</kbd> (2rem). Margin follows the same pattern but uses <kbd>m-</kbd> instead of <kbd>p-</kbd>. For example, <kbd>mx-auto</kbd> centers an element horizontally by applying automatic left and right margins.", "description": "Tailwind's spacing utilities follow a consistent pattern using a spacing scale where each unit represents 0.25rem (4px). Padding utilities use <kbd>p-{size}</kbd> for all sides, <kbd>px-{size}</kbd> for horizontal (left/right), <kbd>py-{size}</kbd> for vertical (top/bottom), or individual sides like <kbd>pt-{size}</kbd>, <kbd>pr-{size}</kbd>, <kbd>pb-{size}</kbd>, <kbd>pl-{size}</kbd>.<br><br>Common sizes include <kbd>p-2</kbd> (0.5rem), <kbd>p-4</kbd> (1rem), <kbd>p-6</kbd> (1.5rem), and <kbd>p-8</kbd> (2rem). Margin follows the same pattern but uses <kbd>m-</kbd> instead of <kbd>p-</kbd>. For example, <kbd>mx-auto</kbd> centers an element horizontally by applying automatic left and right margins.",
"task": "Style the button with <kbd>px-6</kbd> for horizontal padding, <kbd>py-3</kbd> for vertical padding, and <kbd>mx-auto</kbd> to center it.", "task": "Style the button with <kbd>px-6</kbd> for horizontal padding, <kbd>py-3</kbd> for vertical padding, and <kbd>mx-auto</kbd> to center it.",
"previewHTML": "<div class=\"p-6 bg-gray-100\">\n <button class=\"{{USER_CLASSES}} bg-blue-500 text-white rounded block\">\n Centered Button\n </button>\n</div>", "previewHTML": "<div class=\"p-6 bg-gray-100\">\n <button class=\"{{USER_CLASSES}} bg-blue-500 text-white rounded block\">\n Centered Button\n </button>\n</div>",
@@ -115,7 +115,7 @@
}, },
{ {
"id": "responsive-design", "id": "responsive-design",
"title": "Responsive Design with Breakpoint Prefixes", "title": "Breakpoints",
"description": "Tailwind uses a mobile-first responsive design approach with breakpoint prefixes. The base utilities apply to all screen sizes, then you add prefixes for larger screens: <kbd>sm:</kbd> (640px+), <kbd>md:</kbd> (768px+), <kbd>lg:</kbd> (1024px+), <kbd>xl:</kbd> (1280px+), and <kbd>2xl:</kbd> (1536px+).<br><br>For example, <kbd>text-base md:text-lg lg:text-xl</kbd> makes text normal size on mobile, larger on tablets (md), and even larger on desktop (lg). Each breakpoint overrides the previous one, so <kbd>p-4 md:p-6 lg:p-8</kbd> means 1rem padding on mobile, 1.5rem on tablets, and 2rem on desktop.<br><br>Width utilities like <kbd>w-full</kbd> (100% width), <kbd>w-1/2</kbd> (50% width), or fixed sizes like <kbd>w-64</kbd> (16rem) can also be made responsive.", "description": "Tailwind uses a mobile-first responsive design approach with breakpoint prefixes. The base utilities apply to all screen sizes, then you add prefixes for larger screens: <kbd>sm:</kbd> (640px+), <kbd>md:</kbd> (768px+), <kbd>lg:</kbd> (1024px+), <kbd>xl:</kbd> (1280px+), and <kbd>2xl:</kbd> (1536px+).<br><br>For example, <kbd>text-base md:text-lg lg:text-xl</kbd> makes text normal size on mobile, larger on tablets (md), and even larger on desktop (lg). Each breakpoint overrides the previous one, so <kbd>p-4 md:p-6 lg:p-8</kbd> means 1rem padding on mobile, 1.5rem on tablets, and 2rem on desktop.<br><br>Width utilities like <kbd>w-full</kbd> (100% width), <kbd>w-1/2</kbd> (50% width), or fixed sizes like <kbd>w-64</kbd> (16rem) can also be made responsive.",
"task": "Make the box responsive: <kbd>w-full</kbd> on mobile, <kbd>md:w-1/2</kbd> on tablets, and <kbd>lg:w-1/3</kbd> on desktop. Also add responsive text sizing with <kbd>text-lg</kbd>, <kbd>md:text-xl</kbd>, and <kbd>lg:text-2xl</kbd>.", "task": "Make the box responsive: <kbd>w-full</kbd> on mobile, <kbd>md:w-1/2</kbd> on tablets, and <kbd>lg:w-1/3</kbd> on desktop. Also add responsive text sizing with <kbd>text-lg</kbd>, <kbd>md:text-xl</kbd>, and <kbd>lg:text-2xl</kbd>.",
"previewHTML": "<div class=\"p-6 bg-gray-100\">\n <div class=\"{{USER_CLASSES}} bg-purple-500 text-white p-6 rounded text-center\">\n <span>Responsive Box</span><br>\n <small class=\"opacity-75\">Resize your browser to see the effect!</small>\n </div>\n</div>", "previewHTML": "<div class=\"p-6 bg-gray-100\">\n <div class=\"{{USER_CLASSES}} bg-purple-500 text-white p-6 rounded text-center\">\n <span>Responsive Box</span><br>\n <small class=\"opacity-75\">Resize your browser to see the effect!</small>\n </div>\n</div>",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "html-elements", "id": "html-elements",
"title": "HTML Elements: Block vs Inline", "title": "HTML Elements",
"description": "Understanding the fundamental difference between container (block) and inline elements", "description": "Understanding the fundamental difference between container (block) and inline elements",
"mode": "html", "mode": "html",
"difficulty": "beginner", "difficulty": "beginner",
@@ -32,7 +32,7 @@
}, },
{ {
"id": "semantic-containers", "id": "semantic-containers",
"title": "Semantic Container Elements", "title": "Semantic Tags",
"description": "Modern HTML uses semantic containers that describe their content:<br><br><kbd>&lt;header&gt;</kbd> - Page or section header<br><kbd>&lt;nav&gt;</kbd> - Navigation links<br><kbd>&lt;main&gt;</kbd> - Main content area<br><kbd>&lt;section&gt;</kbd> - Thematic grouping<br><kbd>&lt;article&gt;</kbd> - Self-contained content<br><kbd>&lt;footer&gt;</kbd> - Page or section footer", "description": "Modern HTML uses semantic containers that describe their content:<br><br><kbd>&lt;header&gt;</kbd> - Page or section header<br><kbd>&lt;nav&gt;</kbd> - Navigation links<br><kbd>&lt;main&gt;</kbd> - Main content area<br><kbd>&lt;section&gt;</kbd> - Thematic grouping<br><kbd>&lt;article&gt;</kbd> - Self-contained content<br><kbd>&lt;footer&gt;</kbd> - Page or section footer",
"task": "Create a basic page structure:<br>1. Add a <kbd>&lt;header&gt;</kbd> with an <kbd>&lt;h1&gt;</kbd> containing the text 'My Website'<br>2. Add a <kbd>&lt;main&gt;</kbd> element with a paragraph saying 'Welcome to my site!'<br>3. Add a <kbd>&lt;footer&gt;</kbd> with a paragraph saying 'Copyright 2025'", "task": "Create a basic page structure:<br>1. Add a <kbd>&lt;header&gt;</kbd> with an <kbd>&lt;h1&gt;</kbd> containing the text 'My Website'<br>2. Add a <kbd>&lt;main&gt;</kbd> element with a paragraph saying 'Welcome to my site!'<br>3. Add a <kbd>&lt;footer&gt;</kbd> with a paragraph saying 'Copyright 2025'",
"previewHTML": "", "previewHTML": "",
@@ -66,7 +66,7 @@
}, },
{ {
"id": "div-vs-span", "id": "div-vs-span",
"title": "Generic Containers: div and span", "title": "div & span",
"description": "When you need a container without semantic meaning:<br><br><kbd>&lt;div&gt;</kbd> - Generic block container (for layout/grouping)<br><kbd>&lt;span&gt;</kbd> - Generic inline container (for styling text portions)<br><br>Use semantic elements when possible, div/span when no semantic element fits.", "description": "When you need a container without semantic meaning:<br><br><kbd>&lt;div&gt;</kbd> - Generic block container (for layout/grouping)<br><kbd>&lt;span&gt;</kbd> - Generic inline container (for styling text portions)<br><br>Use semantic elements when possible, div/span when no semantic element fits.",
"task": "Wrap the word 'highlighted' in a <kbd>&lt;span&gt;</kbd> to style it differently. Wrap the whole quote in a <kbd>&lt;div&gt;</kbd>.", "task": "Wrap the word 'highlighted' in a <kbd>&lt;span&gt;</kbd> to style it differently. Wrap the whole quote in a <kbd>&lt;div&gt;</kbd>.",
"previewHTML": "", "previewHTML": "",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "html-forms-basic", "id": "html-forms-basic",
"title": "HTML Forms: Basic Inputs", "title": "Form Inputs",
"description": "Learn to create forms with various input types", "description": "Learn to create forms with various input types",
"mode": "html", "mode": "html",
"difficulty": "beginner", "difficulty": "beginner",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "html-forms-validation", "id": "html-forms-validation",
"title": "HTML Forms: Validation", "title": "Validation",
"description": "Learn HTML5 built-in form validation attributes", "description": "Learn HTML5 built-in form validation attributes",
"mode": "html", "mode": "html",
"difficulty": "intermediate", "difficulty": "intermediate",
@@ -32,7 +32,7 @@
}, },
{ {
"id": "input-constraints", "id": "input-constraints",
"title": "Input Constraints", "title": "Constraints",
"description": "Control what users can enter:<br><br><kbd>minlength</kbd> / <kbd>maxlength</kbd> - Text length limits<br><kbd>min</kbd> / <kbd>max</kbd> - Number range<br><kbd>pattern</kbd> - Regex pattern matching<br><kbd>placeholder</kbd> - Hint text (not a label!)", "description": "Control what users can enter:<br><br><kbd>minlength</kbd> / <kbd>maxlength</kbd> - Text length limits<br><kbd>min</kbd> / <kbd>max</kbd> - Number range<br><kbd>pattern</kbd> - Regex pattern matching<br><kbd>placeholder</kbd> - Hint text (not a label!)",
"task": "Add validation to the password input:<br>1. Add <kbd>minlength=\"8\"</kbd> for minimum length<br>2. Add <kbd>maxlength=\"20\"</kbd> for maximum length<br>3. Add <kbd>placeholder=\"Enter password\"</kbd> as a hint", "task": "Add validation to the password input:<br>1. Add <kbd>minlength=\"8\"</kbd> for minimum length<br>2. Add <kbd>maxlength=\"20\"</kbd> for maximum length<br>3. Add <kbd>placeholder=\"Enter password\"</kbd> as a hint",
"previewHTML": "", "previewHTML": "",
@@ -61,7 +61,7 @@
}, },
{ {
"id": "complete-registration", "id": "complete-registration",
"title": "Complete Registration Form", "title": "Full Form",
"description": "Build a complete registration form with all validation concepts:<br><br>- Required fields marked with *<br>- Email validation (use type=\"email\")<br>- Password with length constraints<br>- Terms checkbox (required)<br>- Submit button", "description": "Build a complete registration form with all validation concepts:<br><br>- Required fields marked with *<br>- Email validation (use type=\"email\")<br>- Password with length constraints<br>- Terms checkbox (required)<br>- Submit button",
"task": "Complete the registration form. Add required attributes, proper input types, and validation constraints.", "task": "Complete the registration form. Add required attributes, proper input types, and validation constraints.",
"previewHTML": "", "previewHTML": "",

View File

@@ -1,14 +1,14 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "html-details-summary", "id": "html-details-summary",
"title": "Details & Summary: Disclosure Widgets", "title": "Disclosure",
"description": "Create expandable content sections without JavaScript", "description": "Create expandable content sections without JavaScript",
"mode": "html", "mode": "html",
"difficulty": "beginner", "difficulty": "beginner",
"lessons": [ "lessons": [
{ {
"id": "details-summary-basic", "id": "details-summary-basic",
"title": "Your First Disclosure Widget", "title": "First Widget",
"description": "The <kbd>&lt;details&gt;</kbd> element creates a collapsible section. The <kbd>&lt;summary&gt;</kbd> provides the clickable label.<br><br>Click the summary to toggle the hidden content - no JavaScript needed!", "description": "The <kbd>&lt;details&gt;</kbd> element creates a collapsible section. The <kbd>&lt;summary&gt;</kbd> provides the clickable label.<br><br>Click the summary to toggle the hidden content - no JavaScript needed!",
"task": "Create a <kbd>&lt;details&gt;</kbd> element with:<br>1. A <kbd>&lt;summary&gt;</kbd> saying 'Click to reveal'<br>2. A <kbd>&lt;p&gt;</kbd> with the text 'This content was hidden!'", "task": "Create a <kbd>&lt;details&gt;</kbd> element with:<br>1. A <kbd>&lt;summary&gt;</kbd> saying 'Click to reveal'<br>2. A <kbd>&lt;p&gt;</kbd> with the text 'This content was hidden!'",
"previewHTML": "", "previewHTML": "",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "html-progress-meter", "id": "html-progress-meter",
"title": "Progress & Meter Elements", "title": "Progress/Meter",
"description": "Display completion status and scalar measurements natively", "description": "Display completion status and scalar measurements natively",
"mode": "html", "mode": "html",
"difficulty": "beginner", "difficulty": "beginner",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "html-datalist", "id": "html-datalist",
"title": "Datalist: Autocomplete Inputs", "title": "Datalist",
"description": "Provide suggestions for text inputs without JavaScript", "description": "Provide suggestions for text inputs without JavaScript",
"mode": "html", "mode": "html",
"difficulty": "beginner", "difficulty": "beginner",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "html-data-attributes", "id": "html-data-attributes",
"title": "Custom Data Attributes", "title": "Data Attrs",
"description": "Store custom data on HTML elements with data-* attributes", "description": "Store custom data on HTML elements with data-* attributes",
"mode": "html", "mode": "html",
"difficulty": "beginner", "difficulty": "beginner",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "html-dialog", "id": "html-dialog",
"title": "Native Dialog Element", "title": "Dialogs",
"description": "Create modal dialogs without JavaScript libraries", "description": "Create modal dialogs without JavaScript libraries",
"mode": "html", "mode": "html",
"difficulty": "beginner", "difficulty": "beginner",
@@ -47,7 +47,7 @@
}, },
{ {
"id": "dialog-form", "id": "dialog-form",
"title": "Dialog with Form", "title": "Dialog + Form",
"description": "Dialogs can contain full forms. The <kbd>method=\"dialog\"</kbd> makes the form close the dialog on submit instead of sending data.<br><br>This pattern is perfect for confirmation dialogs, quick inputs, or settings panels.", "description": "Dialogs can contain full forms. The <kbd>method=\"dialog\"</kbd> makes the form close the dialog on submit instead of sending data.<br><br>This pattern is perfect for confirmation dialogs, quick inputs, or settings panels.",
"task": "Create a confirmation dialog:<br>1. Add <kbd>open</kbd> to show it<br>2. An <kbd>&lt;h2&gt;</kbd> saying 'Confirm Delete'<br>3. A <kbd>&lt;p&gt;</kbd> asking 'Are you sure?'<br>4. A <kbd>&lt;form method=\"dialog\"&gt;</kbd> with Cancel and Delete buttons", "task": "Create a confirmation dialog:<br>1. Add <kbd>open</kbd> to show it<br>2. An <kbd>&lt;h2&gt;</kbd> saying 'Confirm Delete'<br>3. A <kbd>&lt;p&gt;</kbd> asking 'Are you sure?'<br>4. A <kbd>&lt;form method=\"dialog\"&gt;</kbd> with Cancel and Delete buttons",
"previewHTML": "", "previewHTML": "",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "html-forms-fieldset", "id": "html-forms-fieldset",
"title": "Forms with Fieldsets", "title": "Fieldsets",
"description": "Group form controls with fieldset and legend elements", "description": "Group form controls with fieldset and legend elements",
"mode": "html", "mode": "html",
"difficulty": "beginner", "difficulty": "beginner",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "html-figure", "id": "html-figure",
"title": "Figure & Figcaption", "title": "Figure",
"description": "Create self-contained content with captions", "description": "Create self-contained content with captions",
"mode": "html", "mode": "html",
"difficulty": "beginner", "difficulty": "beginner",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "html-tables", "id": "html-tables",
"title": "HTML Tables", "title": "Tables",
"description": "Create structured data tables with headers and captions", "description": "Create structured data tables with headers and captions",
"mode": "html", "mode": "html",
"difficulty": "beginner", "difficulty": "beginner",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "html-marquee", "id": "html-marquee",
"title": "The Marquee Element", "title": "Marquee",
"description": "Create scrolling text with the classic (deprecated but fun!) marquee element", "description": "Create scrolling text with the classic (deprecated but fun!) marquee element",
"mode": "html", "mode": "html",
"difficulty": "beginner", "difficulty": "beginner",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "html-svg", "id": "html-svg",
"title": "SVG Basics", "title": "SVG",
"description": "Draw scalable vector graphics directly in HTML", "description": "Draw scalable vector graphics directly in HTML",
"mode": "html", "mode": "html",
"difficulty": "beginner", "difficulty": "beginner",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "../schemas/code-crispies-module-schema.json", "$schema": "../schemas/code-crispies-module-schema.json",
"id": "tailwindcss-basics", "id": "tailwindcss-basics",
"title": "Tailwind CSS Basics", "title": "TW Basics",
"description": "Learn how to use Tailwind CSS utility classes to quickly style your HTML elements", "description": "Learn how to use Tailwind CSS utility classes to quickly style your HTML elements",
"difficulty": "beginner", "difficulty": "beginner",
"lessons": [ "lessons": [