{ "$schema": "../schemas/code-crispies-module-schema.json", "id": "html-data-attributes", "title": "Data Attrs", "description": "Store custom data on HTML elements with data-* attributes", "mode": "html", "difficulty": "beginner", "lessons": [ { "id": "data-attributes-intro", "title": "Adding Data Attributes", "description": "Custom data-* attributes let you store extra information on any HTML element. The attribute name starts with data- followed by your custom name.

Examples: data-id, data-category, data-price", "task": "Create two product cards using <article> elements. Each should have:
1. A data-category attribute (e.g., 'electronics' or 'clothing')
2. A data-price attribute with a number
3. An <h2> with the product name", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; display: grid; gap: 15px; } article { padding: 20px; border-radius: 10px; background: #f5f5f5; border-left: 4px solid #ccc; } article[data-category='electronics'] { border-left-color: #2196f3; background: #e3f2fd; } article[data-category='clothing'] { border-left-color: #e91e63; background: #fce4ec; } h2 { margin: 0 0 10px 0; } article::after { content: '€' attr(data-price); display: block; font-weight: bold; color: #4caf50; margin-top: 10px; }", "sandboxCSS": "", "initialCode": "", "solution": "
\n

Laptop

\n

A powerful laptop for work and play.

\n
\n\n
\n

T-Shirt

\n

A comfortable cotton t-shirt.

\n
", "previewContainer": "preview-area", "validations": [ { "type": "element_count", "value": { "selector": "article[data-category]", "min": 2 }, "message": "Create at least 2 articles with data-category attributes" }, { "type": "element_count", "value": { "selector": "article[data-price]", "min": 2 }, "message": "Add data-price attribute to your articles" }, { "type": "element_count", "value": { "selector": "article h2", "min": 2 }, "message": "Add an <h2> inside each article" } ] }, { "id": "data-attributes-css", "title": "Styling with Data Attributes", "description": "CSS can select elements by their data attributes using [data-*] selectors. You can even match specific values!

The preview CSS uses [data-status='active'] to style active items differently.", "task": "Create a task list with 3 <li> items. Give each a data-status attribute:
1. One with data-status=\"completed\"
2. One with data-status=\"active\"
3. One with data-status=\"pending\"", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } ul { list-style: none; padding: 0; } li { padding: 15px; margin: 8px 0; border-radius: 8px; background: #f5f5f5; } li[data-status='completed'] { background: #c8e6c9; text-decoration: line-through; color: #388e3c; } li[data-status='active'] { background: #fff3e0; border-left: 4px solid #ff9800; font-weight: 600; } li[data-status='pending'] { background: #e3f2fd; color: #1976d2; }", "sandboxCSS": "", "initialCode": "", "solution": "", "previewContainer": "preview-area", "validations": [ { "type": "element_exists", "value": "li[data-status='completed']", "message": "Add an item with data-status=\"completed\"" }, { "type": "element_exists", "value": "li[data-status='active']", "message": "Add an item with data-status=\"active\"" }, { "type": "element_exists", "value": "li[data-status='pending']", "message": "Add an item with data-status=\"pending\"" } ] } ] }