Learning path changes: - Reorder modules: CSS visual (selectors, colors, typography) first, then layout (flexbox, grid), then HTML structure last - Add intro lessons on CSS property syntax before selectors - Add Figure module (images with captions) - Remove Progress/Meter module (too niche) - Reduce Tables from 3 to 1 lesson - Reduce Form Validation from 3 to 1 lesson - Rename "CSS Selectors" module to "CSS Basics" Animation improvements: - Change success text to "Your CODE looks CRISPY!" - Increase animation duration to 3s - Fix Firefox glow: use linear-gradient pulse instead of conic rotation - Fix expected result toggle: match padding to prevent layout jump 🤖 Generated with [Claude Code](https://claude.com/claude-code)
35 lines
2.3 KiB
JSON
35 lines
2.3 KiB
JSON
{
|
|
"$schema": "../schemas/code-crispies-module-schema.json",
|
|
"id": "html-forms-validation",
|
|
"title": "Form Validation",
|
|
"description": "Use HTML5 built-in validation for better user experience",
|
|
"mode": "html",
|
|
"difficulty": "beginner",
|
|
"lessons": [
|
|
{
|
|
"id": "required-fields",
|
|
"title": "Required Fields",
|
|
"description": "The <kbd>required</kbd> attribute prevents form submission if the field is empty. The browser shows a validation message automatically - no JavaScript needed!<br><br>Add it to any input that must be filled:<br><kbd><input type=\"text\" required></kbd>",
|
|
"task": "Make both the name and email fields required by adding the <kbd>required</kbd> attribute to each input.",
|
|
"previewHTML": "",
|
|
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } form { max-width: 320px; } label { display: block; margin-top: 15px; margin-bottom: 5px; font-weight: 500; } label:first-of-type { margin-top: 0; } input { width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 6px; box-sizing: border-box; } input:focus { outline: 2px solid steelblue; border-color: transparent; } button { margin-top: 20px; padding: 10px 20px; background: steelblue; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: 500; }",
|
|
"sandboxCSS": "",
|
|
"initialCode": "<form>\n <label for=\"name\">Name *</label>\n <input type=\"text\" id=\"name\" name=\"name\">\n \n <label for=\"email\">Email *</label>\n <input type=\"email\" id=\"email\" name=\"email\">\n \n <button type=\"submit\">Submit</button>\n</form>",
|
|
"solution": "<form>\n <label for=\"name\">Name *</label>\n <input type=\"text\" id=\"name\" name=\"name\" required>\n \n <label for=\"email\">Email *</label>\n <input type=\"email\" id=\"email\" name=\"email\" required>\n \n <button type=\"submit\">Submit</button>\n</form>",
|
|
"previewContainer": "preview-area",
|
|
"validations": [
|
|
{
|
|
"type": "attribute_value",
|
|
"value": { "selector": "input[name='name']", "attr": "required", "value": true },
|
|
"message": "Add <kbd>required</kbd> to the name input"
|
|
},
|
|
{
|
|
"type": "attribute_value",
|
|
"value": { "selector": "input[name='email']", "attr": "required", "value": true },
|
|
"message": "Add <kbd>required</kbd> to the email input"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|