Refactoring UI
El diseño visual no es talento. Es un conjunto pequeño de decisiones sistémicas tomadas una vez, más un puñado de técnicas para crear jerarquía. Este skill son esos sistemas y esas técnicas.
La mayor causa única de una UI con aspecto amateur es elegir valores ad hoc — 17px aquí, #3B82F6 allá, lighten(5%) para un estado hover. Diseña a partir de una escala, siempre.
Los sistemas — úsalos, no los redescubras
Elige de estas listas. Nunca inventes un valor que no esté en una de ellas.
Espaciado y tamaño
Base 16px, construida a partir de factores y múltiplos:
4 8 12 16 24 32 48 64 96 128 192 256 384 512 640 768
Apretado en el extremo pequeño, expandiéndose en el extremo grande. No puede haber dos valores adyacentes separados por menos de ~25% — eso es lo que hace obvia la elección. Una escala lineal de "múltiplos de 4" falla: no te ayuda a decidir entre 120px y 124px.
Úsalo para márgenes, padding, ancho, alto, tamaños de iconos, ancho de borde — todo lo espacial.
Fija también un conjunto pequeño de valores de opacidad (p.ej. .05 .1 .2 .4 .6 .8) para estados deshabilitados, superposiciones y tintes hover, en lugar de ajustar un deslizador cada vez. Misma lógica que las otras escalas: decide una vez, reutiliza en todas partes.
Escala tipográfica
12 14 16 18 20 24 30 36 48 60 72
No es una escala modular construida a partir de una proporción (4:5, 2:3, proporción áurea). Esas producen valores fraccionarios de píxel que se redondean de manera inconsistente entre navegadores y son demasiado dispersos para la densidad de una interfaz — ganan los valores elegidos a mano, seleccionados por cómo se sienten.
Unidades: solo px o rem. Nunca em. em es relativo al tamaño de fuente actual, por lo que un .875em dentro de un padre de 1.25em se calcula como 17.5px — un valor que no está en tu escala. La escala deja de existir silenciosamente.
Peso de fuente
Dos pesos son suficientes:
- 400 o 500 — cuerpo y la mayoría del texto UI
- 600 o 700 — cualquier cosa enfatizada
Nada por debajo de 400 en UI. Para desenfatizar, usa un color más claro o un tamaño más pequeño — nunca un peso más claro.
Color
Necesitas muchos más colores de los que te da un generador de paletas de cinco muestras.
- Grises: 8–10 tonos. Casi toda una UI es gris — texto, fondos, paneles, bordes, controles de formulario. Tres o cuatro tonos siempre se quedan cortos. Empieza con un gris muy oscuro, no negro verdadero (el negro verdadero se ve antinatural).
- Primario: 5–10 tonos, uno o quizás dos primarios.
- Acentos: 5–10 tonos cada uno — rojo destructivo, amarillo de advertencia, verde positivo, más cualquier otro que el producto necesite distinguir (series de gráficos, eventos de calendario, etiquetas). Diez colores × 5–10 tonos es normal para una UI compleja.
Nómbralos 100 (el más claro) → 900 (el más oscuro), base 500.
Construye la escala en este orden: elige 500 primero (para un primario/acento, debe ser un tono que funcione como fondo de botón). Luego encuentra los extremos — 900 suele ser tu color de texto, 100 un tinte de fondo; un componente de alerta usa ambos, así que diseña uno y lee los dos valores de él. Luego llena 700 y 300 como el compromiso perfecto entre sus vecinos, luego 800 600 400 200 de la misma manera.
Escribe los colores como HSL, no hex. hsl(220, 95%, 34%) y hsl(220, 65%, 61%) están visiblemente relacionados; #03369E y #507DD7 no.
Nunca generes tonos en tiempo de ejecución con lighten() / darken(). Así es como terminas con 35 azules ligeramente diferentes.
Sombras — cinco elevaciones
0 1px 3px hsla(0,0%,0%,.2) /* apenas elevado — botones */
0 4px 6px hsla(0,0%,0%,.2) /* desplegables */
0 5px 15px hsla(0,0%,0%,.2)
0 10px 24px hsla(0,0%,0%,.2)
0 15px 35px hsla(0,0%,0%,.2) /* modales */
Elige preguntando ¿dónde se sitúa esto en el eje Z?, no ¿qué sombra se ve bien?. Más cerca del usuario = más atención. Reducir la sombra de un botón en :active hace que se sienta presionado; aumentar la sombra de un elemento de lista cuando se levanta para arrastrar y reordenar hace lo contrario — se lee como "ahora por encima de sus hermanos" y funciona como la propia indicación de arrastre.
Estas cinco son el valor predeterminado y están bien en todas partes. references/techniques.md proporciona una versión de dos partes refinada de la misma escala — paralela, pero no valores idénticos (su paso superior es más pesado). Úsala cuando las sombras sean prominentes en el diseño; usa estas cuando no lo sean. No mezcles las dos en un mismo proyecto.
Altura de línea y longitud de línea
La altura de línea es inversamente proporcional al tamaño de fuente, y proporcional al ancho de línea:
- texto pequeño / columnas anchas →
1.5a2 - titulares grandes →
1está bien
Longitud de línea: 45–75 caracteres, es decir, max-width: 20em–35em. Esto se aplica al párrafo incluso cuando el contenedor que lo rodea es más ancho — los anchos mixtos en una misma área de contenido se ven más pulidos, no menos.
(em es correcto aquí — la medida debe escalar con el texto que envuelve. La regla de "nunca em" está limitada a la escala tipográfica, donde em se combina por anidamiento. No "arregles" esto.)
Radio de borde
Elige uno y mantente consistente. Radio pequeño = neutro. Radio grande = divertido. Ninguno = serio/formal. Mezclar esquinas cuadradas y redondeadas en una misma interfaz siempre se ve peor.
El procedimiento
1. Empieza con una funcionalidad, no con un layout. No diseñes "la aplicación" — no puedes decidir entre navegación superior y barra lateral antes de saber qué contiene el producto. Diseña una pieza real de funcionalidad (el formulario de búsqueda, el compositor de mensajes), y deja que la estructura emerja.
2. Los detalles vienen después. Ignora tipografías, sombras e iconos al principio. Trabaja primero en escala de grises — esto fuerza a que la jerarquía provenga del espaciado, el contraste y el tamaño en lugar del color. Añade color una vez que el layout funcione.
3. No sobreinviertas en baja fidelidad. Los bocetos, wireframes y mockups son desechables — nadie puede usar una imagen estática de una aplicación. Existen para explorar ideas; abandónalos una vez que se tome la decisión y ve a construir lo real.
4. Diseña la versión más pequeña y útil, luego constrúyela. Trabaja en ciclos cortos de diseño→código. No impliques funcionalidad que no estés listo para construir — un cuadro de comentarios con una zona de archivos adjuntos que no puedes enviar bloquea toda la funcionalidad. Las cosas "bonitas de tener" se diseñan después.
5. Elige por eliminación. Al elegir un valor de una escala: adivina el que crees que es correcto, luego compáralo con el vecino de cada lado. Dos serán obviamente incorrectos. Si una opción externa gana, repite la comparación con esa como nuevo centro.
6. Empieza con demasiado espacio en blanco y elimínalo. Añadir espacio hasta que algo deje de verse mal te da el mínimo. Empezar generoso y recortar te da la cantidad correcta. Las UIs densas (dashboards) son legítimas, pero como una decisión deliberada, no un valor predeterminado.
7. Reduce el lienzo. Un componente pequeño diseñado en una mesa de trabajo de 1400px tiende a expandirse, porque el espacio está ahí para llenarlo. Empieza en ~400px y diseña primero el layout móvil, donde las restricciones son reales — luego llévalo a una pantalla grande y relaja solo lo que genuinamente se sintió apretado. Cambiarás menos de lo que esperas.
Jerarquía — la técnica que hace el mayor trabajo
Todo en la pantalla se sitúa en una pirámide: primario, secundario, terciario. Cuando todo compite, la UI se lee como ruido. Esto es lo que hace que un diseño se vea "diseñado" — no el estilo.
El tamaño no lo es todo. Apoyarse solo en el tamaño de fuente te da contenido primario demasiado grande y contenido secundario demasiado pequeño. Usa peso y color para llevar el énfasis en su lugar, y mantén los tamaños razonables.
Tres colores de texto, como máximo:
- oscuro — contenido primario
- gris — contenido secundario
- gris más claro — contenido terciario (notas al pie, copyright)
Los tres llevan texto de tamaño corporal real, por lo que los tres necesitan 4.5:1. "Gris más claro" significa el tono más claro que aún lo supera — aproximadamente la mitad de una rampa de 9 pasos, no el extremo pálido. Los tonos pálidos son solo para estados deshabilitados y texto grande.
Enfatiza desenfatizando. Cuando el elemento importante no destaque y no quede nada que añadirle, suaviza lo que compite con él. Atenúa los elementos de navegación inactivos; baja el color de fondo de la barra lateral para que el contenido principal se sitúe al frente.
Acciones: estiliza por jerarquía, no por semántica.
- Primaria → sólida, alto contraste. Generalmente exactamente una por página.
- Secundaria → contorno, o un fondo de bajo contraste.
- Terciaria → estilizada como un enlace.
Destructivo ≠ botón rojo grande. Si "Eliminar" no es la acción principal de la página, dale tratamiento terciario — luego hazlo un botón primario rojo grande dentro del diálogo de confirmación, donde genuinamente es la acción principal.
Las etiquetas son un último recurso. etiqueta: valor da a cada dato el mismo peso. La mayoría de los datos se identifican por su formato ($19.99, una dirección de correo) o por contexto. Cuando una etiqueta es genuinamente necesaria, intégrala en el valor ("Quedan 12 en stock", no "En stock: 12"), o añádela como contenido visiblemente secundario. Excepción: en páginas tipo ficha técnica donde los usuarios escanean en busca de la etiqueta, enfatiza la etiqueta.
Equilibra el peso contra el contraste. Los iconos sólidos son visualmente pesados y acallarán el texto que los acompaña — suaviza su color para compensar. También funciona al revés: cuando un borde de 1px es demasiado sutil en un color suave pero demasiado duro una vez que lo oscureces, mantén el color suave y pasa a 2px. Añade peso para arreglar bajo contraste; reduce el contraste para arreglar exceso de peso.
Jerarquía visual ≠ jerarquía del documento. El marcado semántico y el peso visual son decisiones separadas. Los títulos de sección suelen ser etiquetas, no titulares — un h1 de 16px está bien, y a veces el título debe estar oculto visualmente porque el contenido habla por sí mismo.
Reglas duras
Desviarse de estas produce un fallo específico y reconocible.
- Nunca texto gris sobre un fondo de color. El gris sobre blanco funciona porque reduce el contraste; el gris sobre color simplemente se ve sucio. El blanco con opacidad reducida se ve lavado y deshabilitado, y deja ver patrones a través de los glifos. Elige a mano un color con el tono del fondo, ajustando saturación y luminosidad.
- Nunca
empara la escala tipográfica.pxorem. - Nunca generes tonos en tiempo de ejecución. Defínelos de antemano.
- Nunca uses un ancho porcentual para algo que no deba escalar. Las barras laterales reciben anchos fijos; el área principal se flexiona. Los elementos obtienen un
max-widthy solo se reducen cuando la pantalla es realmente más pequeña — una tarjeta de inicio de sesión no debería ser más ancha en pantallas medianas que en grandes. - Nunca escales cosas proporcionalmente entre puntos de ruptura. Los elementos grandes deben reducirse más rápido que los pequeños. Un titular de 2.5em sobre un cuerpo móvil de 14px se calcula en 35px — demasiado grande; debería ser de 20–24px allí. Del mismo modo, el padding de un botón debe volverse proporcionalmente más ajustado a medida que el botón se reduce, no escalar con su tamaño de fuente.
- Siempre más espacio alrededor de un grupo que dentro de él. Esta es la solución para "¿qué etiqueta pertenece a qué campo?", listas con viñetas apretadas, y encabezados que parecen unidos al párrafo equivocado. El espaciado ambiguo es un error funcional, no solo uno estético.
- Nunca uses el color como única señal. Añade un icono, una forma o una pista de texto. Para gráficos, distingue series por contraste (tonos claros→oscuros de un solo color) en lugar de por matiz — los usuarios daltónicos leen la luminosidad de forma fiable, el matiz no tanto.
- Mínimos de contraste: 4,5:1 para texto normal. La tolerancia de 3:1 se aplica solo a texto grande, que WCAG define como 24px regular o 18,66px negrita — no 18px. Asume 4,5:1 a menos que el texto sea genuinamente tan grande. Cuando el blanco sobre color falla, inviértelo: texto de color oscuro sobre un tinte de color claro (ver
references/systems.md). Por separado, 3:1 se aplica también a elementos no textuales (WCAG 1.4.11): si un borde es lo único que identifica un control — un contorno de entrada, un borde de casilla de verificación — necesita 3:1 contra su fondo. Una línea fina que solo divide contenido no lo necesita. Son dos tokens diferentes, no uno solo. - Nunca escales un icono lejos de su tamaño previsto. Un icono de 16–24px a 48px se ve tosco y falto de detalle. En su lugar, colócalo dentro de un círculo de color.
Referencias
assets/tokens.css — un conjunto de inicio completo y verificado por contraste de todo lo anterior como propiedades personalizadas CSS: espaciado, tipografía, pesos, ancho de borde, una escala de opacidad fija, una rampa de gris frío de 9 tonos, un primario de 9 tonos, tres tríos de acentos, cinco elevaciones, una capa de roles semánticos (--surface, --text-primary, --action…) y un bloque de modo oscuro que sobrescribe solo esos roles. Cópialo y reajusta los matices en lugar de redescubrir las escalas a partir de esta prosa. Referencia los roles en los componentes, no las rampas brutas — eso es lo que hace funcionar el modo oscuro. Cada par texto/superficie está verificado ≥4,5:1 en ambos modos y cada borde funcional ≥3:1; los tonos deliberadamente por debajo del umbral (deshabilitados, divisores decorativos, el paso solo para texto grande) están exentos por criterio y comentados en línea.
Cárgalos cuando el trabajo los requiera:
references/systems.md— construir una paleta desde cero: elegir el color base, mantener la saturación viva en los extremos claro y oscuro, rotación de matiz, grises cálidos/fríos, y las dos vías de escape para alcanzar relaciones de contraste sin color feo.references/diagnose.md— tabla de síntoma → solución. Cárgalo primero cada vez que la tarea sea mejorar una UI existente en lugar de construir una nueva.references/techniques.md— simulación de profundidad y luz, sombras de dos partes, alineación de línea base, espaciado entre letras, salir de las formas predeterminadas de los componentes y manejo de imágenes subidas por el usuario.