Interfaz de usuario CSS
Optional Advanced acaba de poner una plantilla sobre una foto. Esta sesión es otra caja de herramientas: interfaz de usuario. Cambias el puntero, el caret y el cromo nativo del widget. No perforas el hero ni partes el artículo en columnas de periódico.
Respuesta directa
Las propiedades de interfaz CSS insinúan la interacción. cursor elige la forma del ratón (pointer, wait, help, not-allowed…). resize deja arrastrar una esquina — casi siempre en un textarea. outline con outline-offset dibuja un anillo de foco que no ocupa espacio de layout (el outline del modelo de caja ya lo viste; aquí es el hábito de teclado). user-select limita el resaltado accidental. caret-color tiñe la barra de inserción. appearance (y -webkit-appearance) puede quitar la piel nativa para restilizar el control. Mantén el foco visible. No conviertas toda la página en un póster inseleccionable.
Por qué no es máscara ni columna
Una máscara decide qué píxeles de una caja siguen visibles. Varias columnas fragmentan un flujo de texto. Las propiedades de UI no hacen ninguna de las dos. El ancho y el alto se quedan salvo que entre resize. Filtros y mask-image siguen siendo arte. Aquí la pregunta es: «¿Parece clicable? ¿Puedo escribir? ¿Puedo agrandar la caja? ¿El teclado ve dónde está?»
Cursor — di la verdad
cursor es una promesa. pointer significa «esto se puede hacer clic». Úsalo en botones y enlaces reales. No pongas una mano sobre un título que no hace nada.
a.nav-link,
button.save {
cursor: pointer;
}
button[disabled] {
cursor: not-allowed;
}
.help-hint {
cursor: help;
}
.busy-panel {
cursor: wait;
}
default es la flecha. text es la I sobre texto seleccionable. grab / grabbing van con asas de arrastre. Hay cursores url(...) personalizados; mantenlos pequeños y pon siempre una palabra de reserva. Un cursor mentiroso es peor que ninguno: la gente pulsa un eslogan y no pasa nada.
Resize — agranda una caja, no el layout
resize funciona en cajas con overflow. El uso diario es un campo de notas:
textarea.notes {
min-height: 6rem;
min-width: 16rem;
max-width: 100%;
resize: vertical;
overflow: auto;
}
Valores: none, both, horizontal, vertical. Acompáñalo de overflow distinto de visible o el asa puede no aparecer. No riegues resize: both en cada tarjeta. min-height / max-width evitan que el campo se hunda o explote.
Outline como anillo de foco
En el modelo de caja el outline queda fuera del borde y no ocupa espacio. En la caja de UI conservas ese anillo para el foco de teclado — a menudo con :focus-visible para que el ratón no encaje un recuadro en cada clic:
button.save:focus-visible {
outline: 3px solid #2563eb;
outline-offset: 3px;
}
button.save:focus:not(:focus-visible) {
outline: none;
}
Nunca envíes *:focus { outline: none; } global sin un recambio igual de visible. outline-offset aleja el anillo sin mover vecinos. Esto no es border (cambia el tamaño) ni un fundido de máscara en la etiqueta del botón.
user-select — menos resaltado accidental
Seleccionar es una función. Bájala solo donde un doble clic no debe pintar azul — etiqueta de barra, chip arrastrable — no el artículo.
.toolbar-label {
user-select: none;
}
article.body {
user-select: text;
}
none bloquea el resaltado. text es el valor legible habitual. all selecciona el elemento entero de un clic. Aún hay prefijos (-webkit-user-select) en WebKit viejo. No desactives la copia en texto legal, precios o errores.
caret-color — tiñe la marca de inserción
El caret es la barra que parpadea en el campo. Ajusta el color de marca sin ocultarlo:
input.email,
textarea.notes {
caret-color: #0f766e;
color: #0f172a;
}
caret-color: auto sigue el color del texto. caret-color: transparent «para que se vea limpio» es una trampa. No es color de toda la página ni mask-image sobre el glifo.
appearance — vuelve a vestir el widget nativo
El navegador pinta checkboxes y campos de búsqueda con cromo nativo. appearance: none (y -webkit-appearance: none si hace falta) quita esa piel:
input.search {
appearance: none;
-webkit-appearance: none;
border: 1px solid #94a3b8;
border-radius: 0.5rem;
padding: 0.5rem 0.75rem;
}
input[type="checkbox"].tick {
appearance: none;
-webkit-appearance: none;
width: 1.15rem;
height: 1.15rem;
border: 2px solid #334155;
border-radius: 0.25rem;
}
Tras none tú debes un borde, un estado marcado y un anillo de foco. Un checkbox invisible no es un checkbox a medida. El soporte varía; prueba el widget real. appearance no arregla una máscara ni sustituye columnas.
UI frente a máscara, columnas y outline de caja
📊 UI vs mask vs columns vs outline
| Tool | Job | Poor fit |
|---|---|---|
cursor / resize / caret-color / appearance |
Interaction chrome on controls | Stenciling a photo; newspaper columns |
user-select |
Limit highlight on chrome, not articles | Hiding copy people must paste |
outline + :focus-visible |
Keyboard focus ring (no layout space) | Replacing border math; fading labels with a mask |
mask-image |
Soft holes on one element’s pixels | Pointer shape; growing a textarea |
Multi-column (column-*) |
Fragment flowing text | Cursors, carets, native widget skin |
Optional Advanced usó columnas para prosa y máscaras para fotos. La interfaz es la capa de control. column-count en un formulario de ajustes o mask-image en el botón enviar no lo hace «más UI».
Qué no debes borrar
No quites todas las pistas nativas. Barras de desplazamiento, carets y anillos de foco existen porque hacen falta. Si el control está desactivado, cursor: not-allowed más el atributo real disabled es más calmo que una máscara que esconde la etiqueta.
.ok-ui {
cursor: pointer;
outline-offset: 2px;
}
.not-a-stencil {
/* don't: mask-image on the submit label to “soften” the click */
}
.not-a-newspaper {
/* don't: column-count on a login form to look advanced */
}
Si el problema es el borde de una foto, vuelve a la máscara. Si es un artículo largo, a las columnas o al flujo de bloque. Si «no se siente clicable», empieza por cursor y un control de verdad, no un filtro decorativo.
Pruébalo tú
cursor: pointeren un<button>real ynot-alloweden[disabled].- A un
textarea,resize: vertical,min-heightyoverflow: auto. - Outline con
:focus-visibleyoutline-offset— llega con Tab. user-select: nonesolo en un chip de barra; el artículo sigue seleccionable.- Tiñe
caret-coloren un input. No enmascares el campo ni pongascolumn-count.
Errores habituales
cursor: pointeren texto que no es enlace ni botónresize: bothen tarjetas de layout y barras de navegaciónoutline: noneglobal sin recambio:focus-visibleuser-select: noneen páginas enteras, precios o errorescaret-color: transparent«para un look limpio»appearance: nonesin borde, estado marcado ni anillo de foco- Tratar una máscara o varias columnas como pulido de interfaz
Resumen
- El CSS de interfaz insinúa interacción: puntero, resize, caret, cromo nativo
cursordebe decir la verdad;resizees para campos, no para la cáscara de la página- Conserva un anillo de foco visible;
user-selectycaret-colorcon mano ligera appearance: nonesolo cuando restilizas el widget por completo- Ni plantilla de máscara ni columnas de periódico
- Optional Advanced sigue con transforms 3D (
transforms-3d)
🧠 Pon a Prueba tu Conocimiento
Pon a Prueba tu Conocimiento
Ponte a prueba con este cuestionario interactivo y descubre qué tan bien entiendes el tema
📝 Instrucciones
- Lee cada pregunta cuidadosamente
- Selecciona la mejor respuesta para cada pregunta
- Puedes repetir el quiz tantas veces como quieras
- Tu progreso se mostrará en la parte superior