{ "$schema": "../../schemas/code-crispies-module-schema.json", "id": "html-progress-meter", "title": "HTML Progress & Meter", "description": "Muestra el estado de completado y mediciones escalares nativamente", "mode": "html", "difficulty": "beginner", "lessons": [ { "id": "progress-basic", "title": "Barras de progreso", "description": "El elemento <progress> muestra el progreso de una tarea. Usa value para el progreso actual y max para el total.

Nota: ¡Esto no es una etiqueta de cierre automático! Escribe <progress>...</progress> con texto alternativo dentro para navegadores antiguos.", "task": "Crea una barra de progreso mostrando 70% de completado:
1. Añade un <label> que diga Download:
2. Añade un <progress> con value=\"70\" y max=\"100\"", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } label { display: block; margin-bottom: 8px; font-weight: 500; } progress { width: 100%; height: 20px; border-radius: 10px; } progress::-webkit-progress-bar { background: #e0e0e0; border-radius: 10px; } progress::-webkit-progress-value { background: linear-gradient(90deg, #4caf50, #8bc34a); border-radius: 10px; } progress::-moz-progress-bar { background: linear-gradient(90deg, #4caf50, #8bc34a); border-radius: 10px; }", "sandboxCSS": "", "initialCode": "", "solution": "\n70%", "previewContainer": "preview-area", "validations": [ { "type": "element_exists", "value": "progress", "message": "Añade un elemento <progress>" }, { "type": "attribute_value", "value": { "selector": "progress", "attr": "value", "value": "70" }, "message": "Establece value=\"70\" en el elemento progress" }, { "type": "attribute_value", "value": { "selector": "progress", "attr": "max", "value": "100" }, "message": "Establece max=\"100\" en el elemento progress" }, { "type": "element_exists", "value": "label", "message": "Añade un <label> para la barra de progreso" } ] }, { "id": "progress-indeterminate", "title": "Progreso indeterminado", "description": "Cuando el progreso es desconocido (como al cargar), omite el atributo value. Esto crea un estado animado indeterminado.

Útil para solicitudes de red o procesos con duración desconocida.", "task": "Crea un indicador de carga:
1. Añade un <p> que diga Loading...
2. Añade un <progress> sin atributo value", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } p { margin-bottom: 10px; color: #666; } progress { width: 100%; height: 8px; border-radius: 4px; } progress::-webkit-progress-bar { background: #e0e0e0; border-radius: 4px; }", "sandboxCSS": "", "initialCode": "", "solution": "

Loading...

\n", "previewContainer": "preview-area", "validations": [ { "type": "element_exists", "value": "progress", "message": "Añade un elemento <progress>" }, { "type": "element_exists", "value": "p", "message": "Añade un <p> con texto de carga" } ] }, { "id": "meter-gauge", "title": "Indicadores meter", "description": "El elemento <meter> muestra un valor escalar dentro de un rango. Úsalo para mediciones como espacio en disco, batería o calificaciones.

Establece low, high y optimum para definir rangos buenos/malos - ¡el navegador lo colorea correspondientemente!", "task": "Crea un indicador de nivel de batería:
1. Añade un <label> que diga Battery:
2. Añade un <meter> con:
- value=\"0.8\"
- min=\"0\" y max=\"1\"
- low=\"0.2\" y high=\"0.8\"
- optimum=\"1\"", "previewHTML": "", "previewBaseCSS": "body { font-family: system-ui; padding: 20px; } label { display: block; margin-bottom: 8px; font-weight: 500; } meter { width: 100%; height: 25px; }", "sandboxCSS": "", "initialCode": "", "solution": "\n80%", "previewContainer": "preview-area", "validations": [ { "type": "element_exists", "value": "meter", "message": "Añade un elemento <meter>" }, { "type": "attribute_value", "value": { "selector": "meter", "attr": "value", "value": "0.8" }, "message": "Establece value=\"0.8\" en el meter" }, { "type": "attribute_value", "value": { "selector": "meter", "attr": "min", "value": "0" }, "message": "Establece min=\"0\" en el meter" }, { "type": "attribute_value", "value": { "selector": "meter", "attr": "max", "value": "1" }, "message": "Establece max=\"1\" en el meter" }, { "type": "attribute_value", "value": { "selector": "meter", "attr": "low", "value": "0.2" }, "message": "Establece low=\"0.2\" para definir el umbral bajo" }, { "type": "attribute_value", "value": { "selector": "meter", "attr": "high", "value": "0.8" }, "message": "Establece high=\"0.8\" para definir el umbral alto" }, { "type": "attribute_value", "value": { "selector": "meter", "attr": "optimum", "value": "1" }, "message": "Establece optimum=\"1\" para indicar el valor óptimo" }, { "type": "element_exists", "value": "label", "message": "Añade un <label> para el meter" } ] } ] }