feat: add box model concept explanations with diagrams

- Added 'concept' objects to all 8 box model lessons
- Each lesson includes 2-4 sentence beginner-friendly explanation
- ASCII diagrams illustrate the 4-layer box model structure
- Concepts cover: box model layers, padding vs margin, border position, box-sizing, margin collapse, shorthand notation, and individual border sides
- All concepts follow schema requirements (explanation required, diagram optional)
This commit is contained in:
2026-01-11 05:13:11 +01:00
parent 39f1fb5fae
commit 435381b03e

View File

@@ -18,6 +18,10 @@
"codeSuffix": "\n}",
"solution": "padding: 1rem;",
"previewContainer": "preview-area",
"concept": {
"explanation": "Every HTML element is a rectangular box made of four concentric layers. The content sits at the center, padding creates breathing room inside the box (keeping content away from edges), border wraps around the padding, and margin pushes neighboring elements away. Think of it like a framed picture: the image is content, the matting is padding, the frame is the border, and the wall space around it is margin.",
"diagram": "CSS Box Model (4 Layers)\n\n┌─────────────────────────────┐\n│ Margin (transparent) │\n│ ┌────────────────────────┐ │\n│ │ Border │ │\n│ │ ┌──────────────────┐ │ │\n│ │ │ Padding (inside) │ │ │\n│ │ │ ┌────────────┐ │ │ │\n│ │ │ │ Content │ │ │ │\n│ │ │ │ Area │ │ │ │\n│ │ │ └────────────┘ │ │ │\n│ │ └──────────────────┘ │ │\n│ └────────────────────────┘ │\n└─────────────────────────────┘"
},
"validations": [
{
"type": "property_value",
@@ -39,6 +43,10 @@
"codeSuffix": "\n}",
"solution": "border: 2px solid darkslategray;",
"previewContainer": "preview-area",
"concept": {
"explanation": "Borders sit between padding and margin, defining the visual edge of an element. They're unique in the box model because they're visible by default (unlike transparent padding and margin). The border shorthand combines three properties—width, style, and color—into one declaration. Borders add to an element's total size unless you use box-sizing: border-box.",
"diagram": "Border Position in Box Model\n\n┌─────────────────────┐\n│ Margin │ (outside)\n│ ╔═══════════════╗ │\n│ ║ Border (2px) ║ │ ← You are here\n│ ║ ┌─────────┐ ║ │\n│ ║ │ Padding │ ║ │\n│ ║ │ Content │ ║ │\n│ ║ └─────────┘ ║ │\n│ ╚═══════════════╝ │\n└─────────────────────┘"
},
"validations": [
{
"type": "regex",
@@ -61,6 +69,10 @@
"codeSuffix": "\n}",
"solution": "margin: 1rem;",
"previewContainer": "preview-area",
"concept": {
"explanation": "Margins are the invisible space outside an element's border that pushes other elements away. Unlike padding (which is inside the border and gets the background color), margins are always transparent. They don't affect the element's own size—they control the relationship between elements. Margins can even be negative, pulling elements closer together or overlapping them.",
"diagram": "Margin vs Padding\n\n┌───────────────────────────┐\n│ ░░░░░ MARGIN ░░░░░ │ (transparent)\n│ ░ ┌─────────────────┐ ░ │\n│ ░ │ BORDER │ ░ │\n│ ░ │ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ │ ░ │\n│ ░ │ ▓ PADDING ▓ │ ░ │ (gets background)\n│ ░ │ ▓ ┌─────────┐ ▓ │ ░ │\n│ ░ │ ▓ │ CONTENT │ ▓ │ ░ │\n│ ░ │ ▓ └─────────┘ ▓ │ ░ │\n│ ░ │ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ │ ░ │\n│ ░ └─────────────────┘ ░ │\n│ ░░░░░░░░░░░░░░░░░░░░░░░ │\n└───────────────────────────┘"
},
"validations": [
{
"type": "property_value",
@@ -82,6 +94,10 @@
"codeSuffix": "\n}",
"solution": "box-sizing: border-box;",
"previewContainer": "preview-area",
"concept": {
"explanation": "By default (content-box), when you set width: 200px, the browser makes only the content 200px wide, then adds padding and border on top—making the total width larger. With border-box, the browser makes the entire box 200px including padding and border, shrinking the content area to fit. Border-box makes layout math predictable: width: 200px means the element is exactly 200px wide, period.",
"diagram": "content-box vs border-box\n\nwidth: 200px + padding: 20px + border: 4px\n\ncontent-box (default):\n┌────────────────────────────┐\n│ Border (4px) │\n│ ┌──────────────────────┐ │\n│ │ Padding (20px) │ │\n│ │ ┌────────────────┐ │ │\n│ │ │ Content 200px │ │ │ Total: 248px!\n│ │ └────────────────┘ │ │\n│ └──────────────────────┘ │\n└────────────────────────────┘\n\nborder-box:\n┌──────────────────────┐\n│ Border + Padding │\n│ ┌────────────────┐ │\n│ │ Content ~152px │ │ Total: 200px ✓\n│ └────────────────┘ │\n└──────────────────────┘"
},
"validations": [
{
"type": "property_value",
@@ -103,6 +119,10 @@
"codeSuffix": "\n}",
"solution": "margin-bottom: 2rem;",
"previewContainer": "preview-area",
"concept": {
"explanation": "When two vertical margins touch, they don't add up—they collapse into a single margin equal to the larger of the two. This prevents excessive spacing between stacked elements like paragraphs. If you have margin-bottom: 2rem and margin-top: 1rem, the total space is 2rem (not 3rem). Horizontal margins never collapse; only vertical ones do.",
"diagram": "Vertical Margin Collapse\n\nWithout collapse (expected?):\n┌─────────────┐\n│ Element 1 │\n└─────────────┘\n ↓ 2rem margin-bottom\n ↓ 1rem margin-top\n┌─────────────┐ Total: 3rem?\n│ Element 2 │\n└─────────────┘\n\nWith collapse (actual):\n┌─────────────┐\n│ Element 1 │\n└─────────────┘\n ↓\n ↓ 2rem (larger wins)\n ↓\n┌─────────────┐ Total: 2rem ✓\n│ Element 2 │\n└─────────────┘"
},
"validations": [
{
"type": "property_value",
@@ -124,6 +144,10 @@
"codeSuffix": "\n}",
"solution": "margin: 1rem 2rem;",
"previewContainer": "preview-area",
"concept": {
"explanation": "The margin shorthand uses a clockwise pattern: one value applies to all sides, two values set vertical then horizontal, three values set top, horizontal, then bottom, and four values go clockwise from top (top, right, bottom, left). The two-value pattern is most common because vertical and horizontal spacing often differ. Think 'Y-axis first, X-axis second.'",
"diagram": "Margin Shorthand Patterns\n\nOne value:\nmargin: 1rem;\n → all sides: 1rem\n\nTwo values:\nmargin: 1rem 2rem;\n ↓ ↓\n vertical horizontal\n (Y) (X)\n\nFour values (clockwise):\nmargin: 1rem 2rem 3rem 4rem;\n ↓ ↓ ↓ ↓\n top right bottom left\n T R B L"
},
"validations": [
{
"type": "regex",
@@ -146,6 +170,10 @@
"codeSuffix": "\n}",
"solution": "padding: 2rem;",
"previewContainer": "preview-area",
"concept": {
"explanation": "Padding shorthand follows the same clockwise pattern as margin: one value for all sides, two values for vertical/horizontal, four values for top/right/bottom/left. The key difference is that padding creates internal space (pushing content away from borders) while margin creates external space (pushing other elements away). Padding also inherits the element's background color.",
"diagram": "Padding Shorthand (same pattern)\n\npadding: 2rem;\n → Equal on all sides\n\n┌─────────────────────┐\n│ Border │\n│ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ │ ← 2rem padding\n│ ▓ ┌───────────┐ ▓ │ (all sides)\n│ ▓ │ Content │ ▓ │\n│ ▓ └───────────┘ ▓ │\n│ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ │\n└─────────────────────┘"
},
"validations": [
{
"type": "property_value",
@@ -167,6 +195,10 @@
"codeSuffix": "\n}",
"solution": "border-bottom: 4px solid dodgerblue;",
"previewContainer": "preview-area",
"concept": {
"explanation": "You can apply borders to individual sides using border-top, border-right, border-bottom, or border-left. This is common for creating underlines, dividers, or asymmetric designs. Each side can have different widths, styles, and colors. The shorthand border property is just a convenience—underneath, the browser sets all four sides at once.",
"diagram": "Individual Border Sides\n\nborder-bottom only:\n┌──────────────────┐\n│ │ (no border)\n│ Content │\n│ │\n└══════════════════┘ ← border-bottom\n\nMix and match:\nborder-left + border-bottom:\n ┌─────────────────┐\n ║ │\n ║ Content │\n ║ │\n ╚═════════════════╝"
},
"validations": [
{
"type": "regex",