{
"$schema": "../schemas/code-crispies-module-schema.json",
"id": "typography-fonts",
"title": "Typography",
"description": "Learn how to control text appearance through font selection, sizing, spacing, and decorative effects.",
"difficulty": "beginner",
"lessons": [
{
"id": "typography-1",
"title": "Font Family & Fallbacks",
"description": "Specify custom fonts and reliable fallback stacks for consistent typography across devices.",
"task": "Set the font-family of the '.text' element to 'Georgia, serif' with serif fallback.",
"previewHTML": "
This text shows the chosen font family.
", "previewBaseCSS": "body { padding: 1rem; }", "sandboxCSS": "", "codePrefix": "/* Set font family */\n.text {", "initialCode": "", "codeSuffix": "}", "previewContainer": "preview-area", "concept": { "explanation": "Font stacks are comma-separated lists that provide fallback options when fonts aren't available on a user's device. Browsers try each font from left to right until they find one installed locally. 'Georgia' is a web-safe font (pre-installed on most systems), and 'serif' is a generic family keyword that tells the browser to use any serif font if Georgia fails. This progressive fallback ensures text always displays in a readable font, even when custom fonts fail to load or aren't supported.", "diagram": "Font Stack Resolution Process\n\nfont-family: Georgia, serif;\n\n1. Try Georgia\n ┌─────────────────┐\n │ Is Georgia │ YES → Use Georgia ✓\n │ installed? │\n └─────────────────┘\n │ NO\n ↓\n2. Try serif (generic)\n ┌─────────────────┐\n │ Use browser's │ → Times, Times New Roman,\n │ default serif │ or similar serif font\n └─────────────────┘\n\nCommon web-safe fonts:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nSerif: Georgia, Times\nSans-serif: Arial, Helvetica, Verdana\nMonospace: Courier, Courier New\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nGeneric families (always available):\nserif, sans-serif, monospace,\ncursive, fantasy, system-ui" }, "validations": [ { "type": "contains", "value": "font-family", "message": "Use the font-family property", "options": { "caseSensitive": false } }, { "type": "regex", "value": "Georgia, serif", "message": "Include Georgia, serif in the font stack", "options": { "caseSensitive": false } } ] }, { "id": "typography-2", "title": "Font Size & Line Height", "description": "Control text scale and readability by adjusting size and line heights.", "task": "Set the heading '.heading' to 1.5rem font-size and 1.5 line-height.", "previewHTML": "font-style and font-weight.",
"previewHTML": "This text should stand out.
", "previewBaseCSS": "body { padding: 1rem; }", "sandboxCSS": "", "codePrefix": "/* Emphasize text */\n.emphasis {", "initialCode": "", "codeSuffix": "}", "previewContainer": "preview-area", "concept": { "explanation": "Font files contain multiple variations (weights and styles) of the same typeface. When you set font-weight: bold, the browser looks for a bold variant in the font family; if unavailable, it synthesizes boldness by artificially thickening letter strokes (called \"faux bold\"). Font-style: italic requests the true italic variant—if missing, browsers slant the regular font (\"oblique\" or \"faux italic\"). True variants look better because type designers craft them with proper letter spacing and stroke contrast, while synthesized versions simply distort the regular font mathematically.", "diagram": "Font Variations Within a Font Family\n\nFont Family: 'Georgia'\n\n┌──────────────────────────────┐\n│ Georgia-Regular.ttf │ font-weight: 400 (normal)\n│ Georgia-Italic.ttf │ font-style: italic\n│ Georgia-Bold.ttf │ font-weight: 700 (bold)\n│ Georgia-BoldItalic.ttf │ both combined\n└──────────────────────────────┘\n\nFont-weight numeric scale:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n100 Thin (rarely used)\n300 Light\n400 Normal/Regular (default)\n600 Semi-Bold\n700 Bold (keyword: bold)\n900 Black/Heavy\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nTrue vs Synthetic (Faux):\n\nTrue Italic: Custom letterforms\nFaux Italic: Slanted regular ⚠️\n\nTrue Bold: Designed thick strokes\nFaux Bold: Artificially thickened ⚠️" }, "validations": [ { "type": "contains", "value": "font-style", "message": "Use font-style property", "options": { "caseSensitive": false } }, { "type": "property_value", "value": { "property": "font-style", "expected": "italic" }, "message": "Set font-style to italic" }, { "type": "contains", "value": "font-weight", "message": "Use font-weight property", "options": { "caseSensitive": false } }, { "type": "property_value", "value": { "property": "font-weight", "expected": "bold" }, "message": "Set font-weight to bold" } ] }, { "id": "typography-4", "title": "Text Decoration & Shadow", "description": "Add decorative underlines, overlines, line-throughs and subtle shadows to text.", "task": "Apply an underline withtext-decoration and a light shadow using text-shadow on '.fancy'.",
"previewHTML": "Fancy text effect!
", "previewBaseCSS": "body { padding: 1rem; } .fancy { font-size: 1.25rem; }", "sandboxCSS": "", "codePrefix": "/* Decorate text */\n.fancy {", "initialCode": "", "codeSuffix": "}", "previewContainer": "preview-area", "concept": { "explanation": "Text-decoration draws lines relative to the text baseline using the browser's rendering engine—underlines sit below the baseline, overlines above the cap height, and line-throughs at the middle of the x-height. Text-shadow creates depth by rendering duplicate copies of text offset by X and Y coordinates, with optional blur radius and color. The browser draws shadows behind the original text using a Gaussian blur algorithm. Multiple shadows can be stacked (comma-separated) to create complex effects like glows, outlines, or 3D text, with each shadow rendered in order from bottom to top.", "diagram": "Text Decoration & Shadow Rendering\n\ntext-decoration: underline;\n\n Cap Height ─┬─ Overline position\n │\n Mean Line ──┼─ Strike-through\n │\n Baseline ───┼─ Text sits here\n │\n └─ Underline position\n\ntext-shadow: 2px 2px 4px gray;\n │ │ │ └─ Color\n │ │ └───── Blur radius\n │ └───────── Vertical offset\n └───────────── Horizontal offset\n\nShadow rendering layers:\n\n┌──────────────────────────┐\n│ Original text (on top) │ ← Layer 3\n├──────────────────────────┤\n│ ░░Blurred shadow copy░░ │ ← Layer 2\n├──────────────────────────┤\n│ Background │ ← Layer 1\n└──────────────────────────┘\n\nCommon patterns:\n━━━━━━━━━━━━━━━━━━━━━━━━━\nSubtle depth: 1px 1px 2px rgba(0,0,0,0.3)\nGlow effect: 0 0 10px gold\n3D text: 2px 2px 0 black (no blur)" }, "validations": [ { "type": "contains", "value": "text-decoration", "message": "Use text-decoration property", "options": { "caseSensitive": false } }, { "type": "contains", "value": "text-shadow", "message": "Use text-shadow property", "options": { "caseSensitive": false } } ] } ] }