{ "$schema": "../../schemas/code-crispies-module-schema.json", "id": "units-variables", "title": "Unidades y Variables CSS", "description": "Comprende la variedad de unidades de medida CSS y cómo definir y usar propiedades personalizadas para estilos mantenibles.", "difficulty": "beginner", "lessons": [ { "id": "units-1", "title": "Relative Units", "description": "CSS ofrece dos tipos de unidades: absolutas (como px) y relativas (como % y rem). Las unidades relativas se adaptan a su contexto, haciendo los layouts flexibles y accesibles.

Unidades relativas comunes:
% – Relativo al elemento padre
rem – Relativo al tamaño de fuente raíz (típicamente 16px)
em – Relativo al tamaño de fuente del elemento

Un patrón común para contenido legible: establece width: 100% para llenar el espacio disponible, luego max-width: 40rem para limitar la longitud de línea para legibilidad.", "task": "Este texto de artículo es demasiado ancho en pantallas grandes. Añade max-width: 40rem para un ancho de lectura óptimo.", "previewHTML": "

The Art of Typography

Good typography is invisible. When text is set well, readers absorb information without noticing the design decisions that make it comfortable to read. Line length is crucial—too wide and eyes get lost, too narrow and reading becomes choppy.

The ideal line length is 45-75 characters per line. At typical font sizes, this works out to roughly 40rem maximum width.

", "previewBaseCSS": "body { font-family: Georgia, serif; padding: 1rem; background: #f9f9f9; } .article { background: white; padding: 2rem; box-shadow: 0 1px 3px rgba(0,0,0,0.1); } .article h2 { margin: 0 0 1rem; color: #333; } .article p { margin: 0 0 1rem; line-height: 1.6; color: #444; } .article p:last-child { margin-bottom: 0; }", "sandboxCSS": "", "codePrefix": ".article {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "max-width: 40rem;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "max-width", "expected": "40rem" }, "message": "Establece max-width: 40rem" } ] }, { "id": "units-2", "title": "CSS Variables", "description": "Las propiedades personalizadas CSS (variables) te permiten definir valores reutilizables. Defínelas con --nombre y úsalas con var(--nombre). Las variables definidas en :root están disponibles en todas partes.", "task": "Define --brand: steelblue en :root, luego úsala como color de background para .btn.", "previewHTML": "
", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .actions { display: flex; gap: 1rem; } .btn { color: white; border: none; padding: 12px 24px; border-radius: 6px; font-size: 1rem; cursor: pointer; background: #ccc; }", "sandboxCSS": "", "codePrefix": ":root {\n ", "initialCode": "", "codeSuffix": "\n}\n\n.btn {\n background: var(--brand);\n}", "solution": "--brand: steelblue;", "previewContainer": "preview-area", "validations": [ { "type": "contains", "value": "--brand", "message": "Define la variable --brand", "options": { "caseSensitive": false } }, { "type": "contains", "value": "steelblue", "message": "Establece el valor a steelblue", "options": { "caseSensitive": false } } ] }, { "id": "units-3", "title": "calc() Function", "description": "La función calc() te permite mezclar diferentes unidades en cálculos. Esto es esencial para layouts que combinan tamaños fijos y flexibles, como un layout con barra lateral.", "task": "El contenido principal debe llenar el espacio restante después de la barra lateral de 200px. Establece width: calc(100% - 200px) en .main.", "previewHTML": "

Main Content

This area should fill the remaining width after accounting for the fixed-width sidebar.

", "previewBaseCSS": "body { font-family: system-ui, sans-serif; padding: 1rem; } .layout { display: flex; gap: 1rem; } .sidebar { width: 200px; background: #1a1a2e; color: white; padding: 1rem; border-radius: 8px; flex-shrink: 0; } .main { background: white; padding: 1rem; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .main h2 { margin: 0 0 8px; } .main p { margin: 0; color: #666; }", "sandboxCSS": "", "codePrefix": ".main {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "width: calc(100% - 200px);", "previewContainer": "preview-area", "validations": [ { "type": "regex", "value": "width:\\s*calc\\(\\s*100%\\s*-\\s*200px\\s*\\)", "message": "Establece width: calc(100% - 200px)", "options": { "caseSensitive": false } } ] }, { "id": "units-4", "title": "Viewport Units", "description": "Las unidades de viewport dimensionan elementos relativos a la ventana del navegador:
vw – 1% del ancho del viewport
vh – 1% de la altura del viewport

Son perfectas para secciones de pantalla completa como banners hero.", "task": "Haz que esta sección hero llene la altura del viewport estableciendo min-height: 100vh.", "previewHTML": "

Welcome

Scroll down to explore

", "previewBaseCSS": "body { font-family: system-ui, sans-serif; margin: 0; } .hero { background: linear-gradient(135deg, #1a1a2e 0%, steelblue 100%); color: white; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 2rem; } .hero h1 { margin: 0 0 1rem; font-size: 2.5rem; } .hero p { margin: 0; opacity: 0.8; }", "sandboxCSS": "", "codePrefix": ".hero {\n ", "initialCode": "", "codeSuffix": "\n}", "solution": "min-height: 100vh;", "previewContainer": "preview-area", "validations": [ { "type": "property_value", "value": { "property": "min-height", "expected": "100vh" }, "message": "Establece min-height: 100vh" } ] } ] }