Formularios y tablas con CSS

En la lección Formularios y tablas viste formularios y tablas con su HTML correcto: etiquetas, fieldset, caption, th.

Campos y botones: font: inherit, width: 100%, box-sizing: border-box, relleno y borde.

Estados: :hover, :focus-visible, :disabled, :user-invalid y ::placeholder.

accent-color para casillas y opciones con el color de tu marca.

Tablas: border-collapse: collapse, relleno, cifras a la derecha con tabular-nums, filas alternas con :nth-child(even) y una caja con overflow-x: auto para el móvil.

  • En la lección Formularios y tablas viste formularios y tablas con su HTML correcto: etiquetas, fieldset, caption, th. Sin CSS funcionan, pero parecen de 1998. Aquí les das el aspecto de tu diseño sin perder nada de lo que los hace accesibles.
  • Los campos y los botones no heredan la tipografía de la página: el navegador les pone la suya. Es lo primero que hay que corregir:
  • label { display: block; /* la etiqueta encima del campo */ font-weight: 600; margin-bottom: 0.25rem; } input, select, textarea { width: 100%; box-sizing: border-box; /* el ancho incluye relleno y borde */ padding: 0.6rem 0.8rem; border: 1px solid #8a94a6; border-radius: 6px; background: white; } textarea { min-height: 8rem; resize: vertical; /* que solo se pueda estirar hacia abajo */ }
  • Para separar los campos, lo más cómodo es convertir el formulario en una columna con gap:
  • form { display: grid; gap: 1rem; max-width: 32rem; }

Introducción

En la lección Formularios y tablas viste formularios y tablas con su HTML correcto: etiquetas, fieldset, caption, th. Sin CSS funcionan, pero parecen de 1998. Aquí les das el aspecto de tu diseño sin perder nada de lo que los hace accesibles.

Que los campos usen tu tipografía

Los campos y los botones no heredan la tipografía de la página: el navegador les pone la suya. Es lo primero que hay que corregir:

Un campo con aspecto propio

label { display: block; /* la etiqueta encima del campo */ font-weight: 600; margin-bottom: 0.25rem; } input, select, textarea { width: 100%; box-sizing: border-box; /* el ancho incluye relleno y borde */ padding: 0.6rem 0.8rem; border: 1px solid #8a94a6; border-radius: 6px; background: white; } textarea { min-height: 8rem; resize: vertical; /* que solo se pueda estirar hacia abajo */ }

Para separar los campos, lo más cómodo es convertir el formulario en una columna con gap:

form { display: grid; gap: 1rem; max-width: 32rem; }

(Grid lo verás a fondo más adelante; aquí solo lo usas para apilar con separación.)

Los estados del campo

Un campo cambia de estado y el diseño tiene que enseñarlo:

PseudoclaseCuándo se aplica :hoverEl ratón está encima. :focus-visibleSe ha llegado al campo, sobre todo con el teclado. :disabledEl campo está desactivado (disabled en el HTML). :user-invalidEl dato no es válido después de que la persona lo haya tocado. ::placeholderEl texto de ejemplo dentro del campo (es un pseudoelemento).

input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 3px solid #fcbf49; outline-offset: 2px; } input:user-invalid { border-color: #b3261e; } input::placeholder { color: #5f6b7a; /* gris con contraste suficiente, no uno muy claro */ } input:disabled { background: #eef1f6; cursor: not-allowed; }

⚠️ Atención. Nunca quites el contorno de foco (outline: none) sin poner otro indicador igual de visible. Quien navega con el teclado necesita ver dónde está. Y no uses solo el color para marcar un error: acompáñalo de un texto que diga qué falta.

Casillas, opciones y botones

Las casillas y los botones de opción se adaptan a tu color de marca con una sola línea, que puedes poner en el formulario entero:

form { accent-color: #1d3557; /* casillas, opciones y deslizadores con tu color */ }

Y el grupo de opciones (fieldset) se puede presentar como una tarjeta:

fieldset { border: 1px solid #d6dce5; border-radius: 8px; padding: 1rem; } legend { font-weight: 600; padding: 0 0.4rem; } button { background: #1d3557; color: white; border: 0; border-radius: 6px; padding: 0.7rem 1.4rem; cursor: pointer; } button:hover { background: #12355b; }

Tablas legibles

table { border-collapse: collapse; /* un solo borde entre celdas, no dos */ width: 100%; } caption { text-align: left; font-weight: 600; padding-bottom: 0.5rem; } th, td { padding: 0.5rem 0.75rem; border-bottom: 1px solid #d6dce5; text-align: left; } td.cifra { text-align: right; /* los números, alineados a la derecha */ font-variant-numeric: tabular-nums; /* todas las cifras del mismo ancho */ } tbody tr:nth-child(even) { background: #f3f5f8; /* filas alternas */ }

:nth-child(even) elige las filas pares. Es una pseudoclase de posición.

En el móvil una tabla ancha no cabe. No la conviertas en otra cosa: métela en una caja que se pueda desplazar en horizontal.

<div class="tabla-desplazable"> <table>…</table> </div>

Practica

Coge un formulario tuyo y aplícale lo de esta página: tipografía heredada, campos al 100 % con relleno y borde, foco visible y botón con tu color. Navega por el formulario solo con el teclado (Tab y Mayús + Tab). ¿Se ve siempre dónde estás? A una tabla tuya dale bordes, filas alternas y las cifras a la derecha.

Errores frecuentes

Olvidar font: inherit: los campos salen con otra letra, más pequeña. outline: none sin alternativa: el formulario no se puede usar con el teclado. Un placeholder gris muy claro: no se lee y además no sustituye a la etiqueta. Pintar en rojo con :invalid: el formulario aparece lleno de errores al cargar. Tablas con width fija que se salen de la pantalla en el móvil.

CSS
80

Formularios y tablas con CSS

En la lección Formularios y tablas viste formularios y tablas con su HTML correcto: etiquetas, fieldset, caption, th.

Código del tema: :focus-visible

📘 Teoría

Introducción

En la lección Formularios y tablas viste formularios y tablas con su HTML correcto: etiquetas, fieldset, caption, th. Sin CSS funcionan, pero parecen de 1998. Aquí les das el aspecto de tu diseño sin perder nada de lo que los hace accesibles.

Que los campos usen tu tipografía

Los campos y los botones no heredan la tipografía de la página: el navegador les pone la suya. Es lo primero que hay que corregir:

Un campo con aspecto propio

label {
  display: block;            /* la etiqueta encima del campo */
  font-weight: 600;
  margin-bottom: 0.25rem;
}
input, select, textarea {
  width: 100%;
  box-sizing: border-box;    /* el ancho incluye relleno y borde */
  padding: 0.6rem 0.8rem;
  border: 1px solid #8a94a6;
  border-radius: 6px;
  background: white;
}
textarea {
  min-height: 8rem;
  resize: vertical;          /* que solo se pueda estirar hacia abajo */
}

Para separar los campos, lo más cómodo es convertir el formulario en una columna con gap:

form {
  display: grid;
  gap: 1rem;
  max-width: 32rem;
}

(Grid lo verás a fondo más adelante; aquí solo lo usas para apilar con separación.)

Los estados del campo

Un campo cambia de estado y el diseño tiene que enseñarlo:

PseudoclaseCuándo se aplica
:hoverEl ratón está encima.
:focus-visibleSe ha llegado al campo, sobre todo con el teclado.
:disabledEl campo está desactivado (disabled en el HTML).
:user-invalidEl dato no es válido después de que la persona lo haya tocado.
::placeholderEl texto de ejemplo dentro del campo (es un pseudoelemento).
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 3px solid #fcbf49;
  outline-offset: 2px;
}
input:user-invalid {
  border-color: #b3261e;
}
input::placeholder {
  color: #5f6b7a;           /* gris con contraste suficiente, no uno muy claro */
}
input:disabled {
  background: #eef1f6;
  cursor: not-allowed;
}

⚠️ Atención. Nunca quites el contorno de foco (outline: none) sin poner otro indicador igual de visible. Quien navega con el teclado necesita ver dónde está. Y no uses solo el color para marcar un error: acompáñalo de un texto que diga qué falta.

:user-invalid es mejor que :invalid: :invalid pinta en rojo un campo obligatorio vacío desde que carga la página, antes de que nadie haya escrito nada.

Casillas, opciones y botones

Las casillas y los botones de opción se adaptan a tu color de marca con una sola línea, que puedes poner en el formulario entero:

form {
  accent-color: #1d3557;    /* casillas, opciones y deslizadores con tu color */
}

Y el grupo de opciones (fieldset) se puede presentar como una tarjeta:

fieldset {
  border: 1px solid #d6dce5;
  border-radius: 8px;
  padding: 1rem;
}
legend {
  font-weight: 600;
  padding: 0 0.4rem;
}
button {
  background: #1d3557;
  color: white;
  border: 0;
  border-radius: 6px;
  padding: 0.7rem 1.4rem;
  cursor: pointer;
}
button:hover {
  background: #12355b;
}

Tablas legibles

table {
  border-collapse: collapse;     /* un solo borde entre celdas, no dos */
  width: 100%;
}
caption {
  text-align: left;
  font-weight: 600;
  padding-bottom: 0.5rem;
}
th, td {
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid #d6dce5;
  text-align: left;
}
td.cifra {
  text-align: right;                 /* los números, alineados a la derecha */
  font-variant-numeric: tabular-nums; /* todas las cifras del mismo ancho */
}
tbody tr:nth-child(even) {
  background: #f3f5f8;               /* filas alternas */
}

:nth-child(even) elige las filas pares. Es una pseudoclase de posición.

En el móvil una tabla ancha no cabe. No la conviertas en otra cosa: métela en una caja que se pueda desplazar en horizontal.

<div class="tabla-desplazable">
  <table>…</table>
</div>
.tabla-desplazable {
  overflow-x: auto;
}

Practica

  1. Coge un formulario tuyo y aplícale lo de esta página: tipografía heredada, campos al 100 % con relleno y borde, foco visible y botón con tu color.
  2. Navega por el formulario solo con el teclado (Tab y Mayús + Tab). ¿Se ve siempre dónde estás?
  3. A una tabla tuya dale bordes, filas alternas y las cifras a la derecha.

Errores frecuentes

  • Olvidar font: inherit: los campos salen con otra letra, más pequeña.
  • outline: none sin alternativa: el formulario no se puede usar con el teclado.
  • Un placeholder gris muy claro: no se lee y además no sustituye a la etiqueta.
  • Pintar en rojo con :invalid: el formulario aparece lleno de errores al cargar.
  • Tablas con width fija que se salen de la pantalla en el móvil.

🕹️ Practica

Taller guiado Estilo para el formulario de adopción Abrir en pantalla completa

¿Qué es esto?

Soy Cristian Eslava y a veces hago webs para procrastinar yo y vosotros. culTest

La hice en febrero de 2026 para facilitar el aprendizaje de mis alumnos. La idea es aprender desarrollo web practicando y que el proyecto siga creciendo con nuevos temas, tests y retos.

Está inspirada en MDN, W3Schools, CodePen, Manz y muchos otros sitios de documentación sobre desarrollo web. Quería combinar teoría útil, ejemplos ejecutables, retos y el sistema de tests que ya tenía en culTest. culTest

Si te gustó, si no te gustó o si quieres escribirme, puedes hacerlo en cristianeslava@gmail.com