{ "$schema": "../../schemas/code-crispies-module-schema.json", "id": "html-tables", "title": "HTML Tables", "description": "Create structured data tables with headers and captions", "mode": "html", "difficulty": "beginner", "lessons": [ { "id": "table-basic", "title": "Basic Table Structure", "description": "Tables use <table> with <tr> for rows. Inside rows, use <th> for headers and <td> for data cells.

The <caption> element provides an accessible title for the table.", "task": "Create a simple table with:
1. A <caption> saying Fruit Prices
2. A header row with Fruit and Price columns
3. At least 2 data rows", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: #f5f5f5; } table { border-collapse: collapse; width: 100%; max-width: 400px; background: white; border-radius: 10px; overflow: hidden; box-shadow: 0 4px 15px rgba(0,0,0,0.1); } caption { padding: 15px; font-weight: 600; font-size: 1.2rem; color: #333; background: #f8f9fa; } th, td { padding: 12px 20px; text-align: left; border-bottom: 1px solid #eee; } th { background: #3498db; color: white; font-weight: 500; } tr:hover { background: #f8f9fa; } tr:last-child td { border-bottom: none; }", "sandboxCSS": "", "initialCode": "", "solution": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n
Fruit Prices
FruitPrice
Apple$1.50
Banana$0.75
", "previewContainer": "preview-area", "validations": [ { "type": "element_exists", "value": "table", "message": "Add a <table> element" }, { "type": "element_exists", "value": "caption", "message": "Add a <caption> for the table title" }, { "type": "element_count", "value": { "selector": "th", "min": 2 }, "message": "Add at least 2 header cells (th)" }, { "type": "element_count", "value": { "selector": "tr", "min": 3 }, "message": "Add at least 3 rows (1 header + 2 data rows)" } ] }, { "id": "table-thead-tbody", "title": "Table Head & Body", "description": "Use <thead> to group header rows and <tbody> to group data rows. This helps browsers and assistive technology understand the table structure.

You can also use <tfoot> for footer rows like totals.", "task": "Create a structured table:
1. A <caption> with Monthly Sales
2. A <thead> with Month and Revenue headers
3. A <tbody> with at least 2 data rows", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; margin: 0; box-sizing: border-box; } table { border-collapse: collapse; width: 100%; max-width: 450px; background: white; border-radius: 12px; overflow: hidden; box-shadow: 0 10px 30px rgba(0,0,0,0.2); } caption { padding: 20px; font-weight: 700; font-size: 1.3rem; color: white; background: transparent; text-shadow: 0 2px 4px rgba(0,0,0,0.2); caption-side: top; } thead { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); } th { padding: 15px 20px; text-align: left; color: white; font-weight: 500; } tbody tr { border-bottom: 1px solid #eee; } tbody tr:hover { background: #f8f9fa; } td { padding: 15px 20px; color: #333; } tbody tr:last-child { border-bottom: none; }", "sandboxCSS": "", "initialCode": "", "solution": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
Monthly Sales
MonthRevenue
January$12,500
February$14,200
", "previewContainer": "preview-area", "validations": [ { "type": "element_exists", "value": "table", "message": "Add a <table> element" }, { "type": "element_exists", "value": "caption", "message": "Add a <caption> element" }, { "type": "element_exists", "value": "thead", "message": "Add a <thead> for the header section" }, { "type": "element_exists", "value": "tbody", "message": "Add a <tbody> for the data rows" }, { "type": "element_count", "value": { "selector": "tbody tr", "min": 2 }, "message": "Add at least 2 data rows in tbody" } ] }, { "id": "table-complete", "title": "Complete Table with Footer", "description": "Add <tfoot> to create a footer section for totals or summary data. The footer stays at the bottom even if tbody has many rows.

Combine all sections for a fully structured, accessible table.", "task": "Create a complete table:
1. A <caption> with Order Summary
2. A <thead> with Item and Price headers
3. A <tbody> with 2 items
4. A <tfoot> with a Total row", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; background: #fafafa; } table { border-collapse: collapse; width: 100%; max-width: 400px; background: white; border-radius: 10px; overflow: hidden; box-shadow: 0 4px 15px rgba(0,0,0,0.1); } caption { padding: 15px 20px; font-weight: 600; font-size: 1.1rem; color: #333; text-align: left; background: #f8f9fa; border-bottom: 2px solid #eee; } th, td { padding: 12px 20px; text-align: left; } thead th { background: #2c3e50; color: white; } tbody td { border-bottom: 1px solid #eee; } tbody tr:hover { background: #f8f9fa; } tfoot { background: #ecf0f1; font-weight: 600; } tfoot td { border-top: 2px solid #2c3e50; color: #2c3e50; }", "sandboxCSS": "", "initialCode": "", "solution": "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
Order Summary
ItemPrice
Widget$25.00
Gadget$35.00
Total$60.00
", "previewContainer": "preview-area", "validations": [ { "type": "element_exists", "value": "table", "message": "Add a <table> element" }, { "type": "element_exists", "value": "caption", "message": "Add a <caption> element" }, { "type": "element_exists", "value": "thead", "message": "Add a <thead> section" }, { "type": "element_exists", "value": "tbody", "message": "Add a <tbody> section" }, { "type": "element_exists", "value": "tfoot", "message": "Add a <tfoot> section for the total" }, { "type": "element_count", "value": { "selector": "tbody tr", "min": 2 }, "message": "Add at least 2 item rows in tbody" } ] } ] }