Tablas de datos
Una tabla muestra datos en filas y columnas.
<table>
<tr>
<th>Alumno</th>
<th>Nota</th>
</tr>
<tr>
<td>Ana</td>
<td>6,5</td>
</tr>
</table>| Etiqueta | Qué es |
|---|---|
<table> | Envuelve toda la tabla |
<tr> | Table row: una fila |
<th> | Table header: una celda de encabezado. Se ve en negrita y centrada |
<td> | Table data: una celda normal de datos |
Celdas que ocupan varias columnas o filas
<table>
<caption>Notas del primer semestre</caption>
<tr>
<th>Alumno</th>
<th colspan="2">Notas</th>
</tr>
<tr>
<td>Ana</td>
<td>6,5</td>
<td>5,9</td>
</tr>
</table>| Atributo | Qué hace |
|---|---|
<caption> | El título de la tabla. Va justo después de <table> y se lee antes que nada en un lector de pantalla |
colspan="2" | Esa celda ocupa 2 columnas |
rowspan="2" | Esa celda ocupa 2 filas |
Cuenta las celdas cuando uses colspan
Si una fila declara
colspan="2"y las demás tienen tres celdas sueltas, la tabla queda descuadrada y el navegador no avisa. La suma de columnas de cada fila, contando loscolspan, tiene que dar siempre el mismo número.
Las tablas son para datos, no para maquetar
Un horario, una lista de notas, un catálogo de precios: eso es una tabla. La disposición de la página (columnas, barras laterales, cuadrículas) se hace con CSS.
Maquetar con tablas fue normal hace veinte años y hoy es un error: rompe la lectura en lectores de pantalla y se desarma en pantallas chicas.
¿Por qué los formularios?
La tabla muestra datos que ya existen. El formulario es el que los captura.
| Quién | Qué hace |
|---|---|
| El usuario | Escribe datos: nombre, correo, una búsqueda, un pedido |
| El formulario | La puerta de entrada: recoge lo escrito y lo envía |
| El servidor | Recibe y procesa. Lo veremos con PHP, más adelante |
Todo sistema necesita recibir datos: un registro, un login, un pedido, una búsqueda. Hoy construimos la puerta con HTML; procesar lo que entra por ella viene después.
Anatomía de un formulario
<form action="" method="GET">
<label for="correo">Correo</label>
<input id="correo" name="correo" type="email"
placeholder="tu@correo.cl" required>
<button type="submit">Enviar</button>
</form>| Elemento / atributo | Qué hace |
|---|---|
<form> | Envuelve los campos |
action | A dónde se envían: el archivo del servidor que los recibirá. Ese archivo lo escribiremos con PHP; por ahora va vacío |
method | Cómo se envían: GET los pone en la URL; POST los manda dentro de la solicitud, sin mostrarlos |
<label> | Describe el campo; se asocia con for / id |
<input> | El campo donde se escribe. Su type define qué acepta |
name | El nombre con el que llega el dato al servidor |
required | El navegador no deja enviar si el campo está vacío |
placeholder | Texto gris de ejemplo dentro del campo |
Sin name el dato se pierde
Un campo sin
namesimplemente no se envía, y nadie te avisa: el formulario se manda, el navegador no protesta, y ese dato nunca llega. Es el error más común de todos.
id frente a name
Se confunden todo el tiempo porque suelen valer lo mismo:
idenlaza el<label>con el campo, dentro del HTML. Hace que al hacer clic en la etiqueta se enfoque el campo, y es lo que anuncia el lector de pantalla.namees el nombre con el que el dato viaja hacia el servidor.Lo normal es poner el mismo valor en los dos.
El placeholder no reemplaza al label
El texto gris desaparece en cuanto el usuario empieza a escribir. Si era la única indicación de qué iba ahí, el usuario se queda sin referencia a mitad de camino. El
labelse queda siempre.
Al enviar, mira la barra de direcciones
Solo con HTML nadie procesa los datos: la página se vuelve a cargar y el formulario queda vacío. Pero con
method="GET"los datos viajan en la URL, y ahí los puedes ver:contacto.html?correo=ana%40correo.cl. Son los mismos parámetros de la anatomía de una URL.En esta unidad usamos
GETjustamente para verlos. En la Unidad 2, cuando PHP reciba el envío, pasaremos aPOST, que es lo correcto para datos como una contraseña: conGETquedaría escrita en la URL y en el historial.
Con Live Server, method="POST" muestra «Cannot POST»
Live Server solo sabe entregar archivos, no recibir envíos. Un formulario con
POSTle pide algo que no sabe hacer y responde con esa página de error. No es un problema de tu HTML: cámbialo aGETpor ahora.
Agrupar campos relacionados
<form action="" method="GET">
<fieldset>
<legend>Datos personales</legend>
<label for="nombre">Nombre</label>
<input id="nombre" name="nombre" type="text" required>
</fieldset>
<fieldset>
<legend>Tu consulta</legend>
…
</fieldset>
</form>| Elemento | Qué hace |
|---|---|
<fieldset> | Agrupa campos que van juntos y dibuja un marco alrededor |
<legend> | El título de ese grupo. Va como primer hijo del fieldset |
Úsalo cuando el formulario tenga más de cinco campos
Un formulario largo sin agrupar se lee como una lista interminable. Con dos o tres
fieldsetel usuario ve de entrada cuánto le falta, y el lector de pantalla anuncia ellegendal entrar en cada grupo.
Tipos de campo
El type del <input> define qué acepta el campo, y de paso da validación
gratis: el navegador se encarga.
1 · Texto, correo y contraseña
type | Qué acepta | Detalle |
|---|---|---|
text | Texto libre de una línea | El más común |
email | Formato de correo | Exige arroba y dominio. En el celular aparece el teclado con arroba |
password | Texto oculto | Lo escrito se ve como puntos |
password no cifra nada
Solo tapa la pantalla para que nadie lea por encima del hombro. El dato viaja tal cual. Lo que protege el envío es HTTPS, que viste en cómo funciona la web.
2 · Números, fechas y texto largo
| Elemento | Qué acepta | Detalle |
|---|---|---|
type="number" | Solo números | Admite min y max. Trae flechas para subir y bajar |
type="date" | Una fecha | Abre el calendario del navegador, así la fecha llega siempre con el mismo formato |
<textarea> | Texto largo, de varias líneas | No es un input: es un elemento aparte y sí se cierra |
3 · Elegir entre opciones
Cuando el dato no se escribe, se elige.
| Elemento | Cuántas se eligen | Detalle |
|---|---|---|
type="checkbox" | Ninguna, una o varias | Cada casilla es independiente |
type="radio" | Solo una del grupo | Lo que las agrupa es compartir el mismo name |
<select> | Una de la lista | Lista desplegable, con un <option> por alternativa. Se cierra |
El value es lo que realmente se envía
En los campos donde se escribe, el dato que viaja es lo que el usuario escribió.
En los que se eligen, viaja el value (y el texto que se ve al lado es solo la
etiqueta).
<input type="radio" id="diurna" name="jornada" value="diurna" checked>
<label for="diurna">Diurna</label>
<select name="asunto">
<option value="consulta" selected>Consulta</option>
<option value="reclamo">Reclamo</option>
</select>| Atributo | En qué campo | Qué hace |
|---|---|---|
value | radio, checkbox, option | El dato que se envía al servidor |
checked | radio, checkbox | Deja la opción marcada de entrada |
selected | option | Deja esa opción elegida de entrada |
Un option sin value envía su texto visible
<option>Consulta</option>manda literalmenteConsulta, con mayúscula y tildes. Si mañana cambias el texto a “Hacer una consulta”, cambia también el dato que llega al servidor y lo que ya estaba guardado deja de coincidir. Pon siempre unvaluecorto y estable.
Poner límites al dato
| Atributo | En qué campo | Qué hace |
|---|---|---|
maxlength | text, textarea | Máximo de caracteres que deja escribir |
min / max | number, date | Valor mínimo y máximo aceptado |
step | number | De cuánto en cuánto sube: step="0.1" permite decimales |
pattern | text | Una expresión regular que el valor debe cumplir |
<input type="number" name="edad" min="18" max="120" required>
<input type="text" name="rut" pattern="[0-9]{7,8}-[0-9kK]" placeholder="12345678-9">
<textarea name="mensaje" maxlength="500"></textarea>La validación del navegador no reemplaza a la del servidor
Todo esto se puede saltar: basta con abrir el inspector (
F12), borrar elrequireddel campo y enviar, o mandar la petición por fuera del formulario. Sirve para ayudar al usuario a no equivocarse, no para proteger el sistema.El dato se valida otra vez en el servidor, siempre. Eso lo veremos con PHP.
Los radio se agrupan por el name
Si dos botones de radio tienen
namedistinto, el navegador los trata como grupos separados y se pueden marcar los dos a la vez. Compartennamey se distinguen porvalue.
Un formulario con todos los tipos
<form action="" method="GET">
<input type="text" name="nombre" required>
<input type="email" name="correo">
<input type="password" name="clave">
<input type="number" name="edad" min="18">
<input type="date" name="nacimiento">
<textarea name="mensaje"></textarea>
<input type="checkbox" name="foto">
<input type="radio" name="jornada" value="diurna">
<input type="radio" name="jornada" value="vespertina">
<select name="asunto">
<option value="consulta">Consulta</option>
<option value="reclamo">Reclamo</option>
</select>
<button type="submit">Enviar</button>
</form>Tres cosas que revisar en ese bloque:
- Todos los campos llevan
name. - Los dos
radiocomparten el mismoname(son el mismo grupo) y se distinguen porvalue. textareayselectse cierran;inputno.
Falta un
<label>por campoEl ejemplo está comprimido para que quepan todos los tipos juntos. En tu código, cada campo lleva su
<label for="…">delante.
La tabla donde irán los datos
El formulario decide las columnas: una por cada name. Las filas, por ahora,
las escribimos a mano con datos de ejemplo.
<table>
<thead>
<tr>
<th>Nombre</th>
<th>Correo</th>
<th>Asunto</th>
</tr>
</thead>
<tbody>
<tr>
<td>Ana Soto</td>
<td>ana@correo.cl</td>
<td>Consulta</td>
</tr>
<tr>
<td>Beto Díaz</td>
<td>beto@correo.cl</td>
<td>Reclamo</td>
</tr>
</tbody>
</table>| Etiqueta | Qué agrupa |
|---|---|
<thead> | La fila de títulos, una sola vez |
<tbody> | Las filas de datos |
El orden de los
<th>y el de los<td>debe coincidirSi mueves una columna en el encabezado, mueve también sus celdas. Nada te avisa si quedan cruzadas: la tabla se dibuja igual, con los datos en la columna equivocada.
Con HTML solo no se pueden mostrar los datos enviados
Al apretar enviar, los datos aparecen en la URL pero no en la tabla. HTML no recuerda nada y no hay quién procese el envío.
Leerlos y mostrarlos lo hará PHP con la base de datos, en las unidades 2 y 3. Lo que hacemos hoy es dejar preparada la tabla donde después irán esos datos.
Incrustar contenido de otro sitio
Un <iframe> mete otra página completa dentro de un hueco de la tuya. Es lo que
usan los mapas de Google y los videos de YouTube.
<!-- Un video de YouTube -->
<iframe width="560" height="315"
src="https://www.youtube.com/embed/CODIGO_DEL_VIDEO"
title="Descripción del video"
allowfullscreen></iframe>
<!-- Un mapa de Google -->
<iframe src="https://www.google.com/maps/embed?pb=..."
width="600" height="450"
title="Ubicación de la UMAG"
loading="lazy"></iframe>| Atributo | Para qué |
|---|---|
src | La dirección de la página que se incrusta |
width / height | El tamaño del hueco |
title | Describe qué hay dentro. Es el alt de los iframes: obligatorio por accesibilidad |
loading="lazy" | No lo carga hasta que el usuario se acerca a él. Acelera la página |
Copia el código que te da el propio sitio
En YouTube: Compartir → Insertar. En Google Maps: Compartir → Incorporar un mapa. Ambos entregan el
<iframe>completo y ya armado.
La URL de la barra de direcciones no sirve
youtube.com/watch?v=abc123no funciona dentro de uniframe: YouTube lo bloquea. La que sirve es la de incrustar,youtube.com/embed/abc123, que es la que da el botón Insertar.
No todos los sitios se dejan incrustar
Un sitio puede prohibir que lo metan en un
iframeajeno, y entonces el hueco aparece en blanco o con un mensaje de error. Es una medida de seguridad del sitio incrustado, no un fallo de tu código.
Checkpoint
Intenta responder antes de desplegar cada pregunta.
¿Qué hacen
table,tr,th,td,theadytbody?
tableenvuelve toda la tabla.tr(table row) es una fila.th(table header) es una celda de encabezado: se ve en negrita.td(table data) es una celda normal de datos.theadagrupa la fila de títulos, que va una sola vez, ytbodylas filas de datos.
¿Por qué no se maquetan las páginas con tablas?
Porque una tabla significa “estos son datos en filas y columnas”. Usarla para colocar cosas en la pantalla rompe la lectura en lectores de pantalla, se desarma en pantallas chicas y es imposible de mantener. La disposición de la página se hace con CSS.
¿Para qué sirven
actionymethoden un formulario?
actiondice a dónde se envían los datos: el archivo del servidor que los recibirá.methoddice cómo:GETlos pone a la vista en la URL yPOSTlos manda dentro de la solicitud. En esta unidad usamosGET.Por ahora el
actionva vacío, porque todavía no existe el archivo PHP que reciba el envío.
¿Qué atributo hace que un campo llegue al servidor?
name. Sin él el campo no se envía y nadie avisa: el formulario se manda igual y ese dato simplemente no llega. Es el error más común.No confundirlo con
id, que enlaza el<label>dentro del HTML. Lo normal es poner el mismo valor en ambos.
¿Qué son checkbox, select, textarea y date, y qué envía cada uno?
checkbox(casillas independientes: ninguna, una o varias marcadas).select(lista desplegable, con un<option>por alternativa).textarea(texto largo, de varias líneas). No es uninputy sí se cierra.date(abre el calendario del navegador, así la fecha llega siempre con el mismo formato).En los que se eligen, lo que viaja es el
value, no el texto visible. Por eso un<option>debe llevar siempre unvaluecorto y estable.
¿Por qué
requiredypatternno reemplazan la validación del servidor?Porque son validación del navegador, y el navegador está en el computador del usuario: basta con borrar el atributo desde el inspector (
F12) o enviar la petición por fuera del formulario.Sirven para ayudar al usuario a no equivocarse, no para proteger el sistema. El dato se vuelve a validar en el servidor, siempre.