Cambiar el cursor con CSS es una de esas cosas pequeñas que, cuando las descubres, te preguntas cómo no las estabas usando antes.
A mí me pasó exactamente así: quería mejorar la experiencia en una interfaz bastante minimalista y empecé a probar cursores distintos. Ahí aprendí dos lecciones importantes:
- No todos los navegadores cargan los mismos cursores,
- Un cursor mal elegido puede arruinar la experiencia del usuario.
En esta guía te voy a enseñar todo lo que he aprendido sobre el uso de cursores con CSS: cómo funcionan, cuáles existen, cómo crear los tuyos propios, qué errores evitar y cómo aplicarlos sin comprometer la usabilidad de tu interfaz.
Qué es la propiedad cursor y para qué sirve
La propiedad cursor de CSS define la apariencia del puntero del ratón cuando el usuario pasa sobre un elemento. Es conceptualmente simple: cambias el valor y el cursor cambia su aspecto visualmente.
Cuando sitúas el ratón sobre un input de tipo text, aparece la famosa I de edición. Sobre un enlace <a>, aparece la manito. Todo eso lo decide el navegador según el tipo de elemento… pero tú puedes sobreescribirlo a voluntad con esta propiedad.
Cómo funciona y cuándo se aplica
El navegador asigna un cursor por defecto a cada elemento según su rol semántico, pero tú puedes cambiarlo en cualquier selector CSS:
button {
cursor: pointer;
}Mucho cuidado aquí: cambiar el cursor solo por estética puede confundir al usuario. Yo lo hice al principio y terminé dando marcha atrás porque los usuarios no distinguían qué elementos eran clicables y cuáles no. El cursor es un indicador de affordance —es decir, le dice al usuario qué puede hacer— y nunca debería mentirle.
Errores comunes al usar cursores (y cómo evitarlos)
- Usar cursores que no representan acciones reales (por ejemplo, poner
cursor: pointeren texto que no es clicable) - Poner cursores personalizados demasiado grandes (queda lento y torpe al mover el ratón)
- No incluir un fallback cuando el navegador no soporta la imagen del cursor
- Aplicar estilos de cursor en pantallas táctiles (donde el cursor simplemente no existe)
Con la propiedad
cursorde CSS podemos cambiar el aspecto del puntero sobre ciertos elementos de nuestra web. Normalmente, cuando visitamos un sitio, el cursor toma la forma de una flecha; pero esta cambia al situarse sobre ciertos elementos —por ejemplo, uninputde tipotext— donde pasa a mostrar el cursor de edición de texto. Nosotros podemos controlar ese comportamiento.
Cursores en la web con CSS
El uso de cursores personalizados en una aplicación web puede mejorar notablemente la experiencia del usuario final. En este artículo veremos cómo usar tanto los cursores predefinidos por CSS como los cursores personalizados creados con imágenes propias.
Para utilizar los cursores ya predefinidos basta con asignar el valor correspondiente a la propiedad cursor del selector que quieras. Para un cursor personalizado, en cambio, debes proporcionar la URL de una imagen que representará visualmente el puntero.
Sintaxis básica de la propiedad cursor en CSS
Con CSS puedes establecer el tipo de cursor usando la siguiente sintaxis:
/* donde 'cursor' es la propiedad y 'valor' es el tipo de cursor */
cursor: valor;Ejemplo básico de uso
Como todo en CSS, hay una propiedad y un valor. El siguiente ejemplo convierte el cursor sobre un elemento .texto-editable en el cursor de tipo I-beam, que indica al usuario que puede escribir ahí:
.texto-editable {
cursor: text;
}Aplicación del cursor en elementos específicos
Puedes cambiar el cursor en elementos HTML específicos sin afectar de forma global a toda la página. Por ejemplo, aquí definimos un cursor pointer para tarjetas clicables y un cursor ew-resize para un borde redimensionable:
.card {
cursor: pointer;
}
.borde {
cursor: ew-resize;
}A mí me gusta probar cada cursor en varios navegadores porque algunos, sorprendentemente, no renderizan ciertos valores. Me ha pasado especialmente con context-menu, que en algunos entornos simplemente se ignora y cae al cursor por defecto.
Lista completa de cursores en CSS (con descripción y utilidad)
A continuación tienes los cursores predefinidos por el sistema operativo o el navegador. Algunos de ellos pueden no cargarse en todos los entornos, dependiendo del sistema operativo o del navegador que utilice tu visitante; ten eso en cuenta al elegir uno para tu interfaz:
default— Flecha estándar del sistemapointer— Mano indicando que el elemento es clicabletext— I-beam para selección o edición de textowait— Indica que el sistema está procesando y el usuario debe esperarprogress— Cargando en segundo plano (el usuario puede seguir interactuando)help— Signo de interrogación o ayuda disponiblecrosshair— Cruz de precisión, útil en herramientas gráficas o mapasmove— Movimiento libre en todas las direcciones
Cursores para redimensionar elementos
Este grupo de cursores es especialmente útil cuando construyes interfaces con paneles redimensionables, divisores o grids ajustables:
e-resize— Redimensionar hacia la derecha (este)w-resize— Redimensionar hacia la izquierda (oeste)n-resize— Redimensionar hacia arriba (norte)s-resize— Redimensionar hacia abajo (sur)ne-resize— Diagonal arriba-derechanw-resize— Diagonal arriba-izquierdase-resize— Diagonal abajo-derechasw-resize— Diagonal abajo-izquierdans-resize— Redimensionado vertical (norte-sur)ew-resize— Redimensionado horizontal (este-oeste)col-resize— Ajuste de columnasrow-resize— Ajuste de filas
Cursores funcionales y de advertencia
Estos cursores comunican restricciones o acciones especiales al usuario, y son muy útiles en interfaces con elementos de arrastrar y soltar o zonas bloqueadas:
not-allowed— Indica que la acción está bloqueada o no está permitidano-drop— El elemento no se puede soltar en esta zonacopy— Indica que se va a copiar un elementoalias— Indica un alias o acceso directo alternativonone— Oculta completamente el cursor (úsalo con precaución)grab— El elemento puede arrastrarsegrabbing— El elemento está siendo arrastrado en este momento
Aquí tienes el bloque completo de cursores predefinidos, listo para copiar y usar como referencia en tu proyecto:
/* cursores predefinidos por CSS */
.alias { cursor: alias; }
.auto { cursor: auto; }
.cell { cursor: cell; }
.copy { cursor: copy; }
.context-menu { cursor: context-menu; }
.crosshair { cursor: crosshair; }
.default { cursor: default; }
.help { cursor: help; }
.move { cursor: move; }
.none { cursor: none; }
.pointer { cursor: pointer; }
.progress { cursor: progress; }
.text { cursor: text; }
.vertical-text { cursor: vertical-text; }
.wait { cursor: wait; }
.no-drop { cursor: no-drop; }
.not-allowed { cursor: not-allowed; }
.grab { cursor: grab; }
.grabbing { cursor: grabbing; }
.all-scroll { cursor: all-scroll; }
.col-resize { cursor: col-resize; }
.row-resize { cursor: row-resize; }
.e-resize { cursor: e-resize; }
.n-resize { cursor: n-resize; }
.s-resize { cursor: s-resize; }
.w-resize { cursor: w-resize; }
.ns-resize { cursor: ns-resize; }
.ew-resize { cursor: ew-resize; }
.ne-resize { cursor: ne-resize; }
.nw-resize { cursor: nw-resize; }
.se-resize { cursor: se-resize; }
.sw-resize { cursor: sw-resize; }
.nesw-resize { cursor: nesw-resize; }
.nwse-resize { cursor: nwse-resize; }Puedes verlo en la práctica aquí:
Cursores personalizados con CSS: cómo usar tus propias imágenes
Para definir un cursor completamente personalizado basta con indicar la URL de la imagen que lo representará como valor de la propiedad cursor. Puedes encadenar varias URLs seguidas: CSS intentará cargar la primera imagen; si falla —porque no existe, el formato no es compatible o el tamaño supera el límite del navegador—, pasará automáticamente a la siguiente. Al final de la cadena siempre debes incluir un cursor estándar de fallback:
/* cursor personalizado con fallback */
.pointer-custom {
cursor: url(pointer-custom.gif),
url(pointer-custom.png),
pointer;
}Usar url() para cargar tu propio cursor
- Puedes usar
.png,.gif,.curo incluso.svgen navegadores modernos. - Algunos navegadores ignoran la primera imagen si no cumple con ciertas dimensiones o si el formato no está soportado. Por eso siempre encadeno varias opciones:
.cursor-custom {
cursor: url("cursor.cur"),
url("cursor.png"),
pointer;
}Nota el pointer al final: ese es el fallback obligatorio. Sin él, si ninguna imagen carga, el navegador puede quedarse sin cursor o comportarse de forma impredecible.
Fallbacks: cómo asegurar que tu cursor siempre funcione
La estrategia de fallback para cursores personalizados sigue este orden de prioridad:
- Primera URL → formato ideal y más compatible (p. ej.
.png) - Segunda URL → alternativa para navegadores menos comunes (p. ej.
.cur) - Valor final → cursor estándar de CSS (
pointer,default, etc.)
Esta estrategia me ha salvado más de una vez, especialmente cuando un .png no cargaba correctamente en Safari o cuando un .gif animado no lo soportaba Firefox en alguna versión antigua.
Formatos recomendados: PNG, SVG y CUR
.cur: formato nativo de Windows, óptimo para compatibilidad en IE/Edge heredado.png: el mejor balance entre compatibilidad y calidad; funciona en la mayoría de navegadores modernos.svg: resolución perfecta en cualquier densidad de píxeles, pero el soporte como cursor no es universal todavía.gif: permite cursores animados, aunque con soporte variable según el navegador
Punto de anclaje del cursor (hotspot)
Hay un detalle que mucha gente pasa por alto: el hotspot o punto de anclaje. Es la coordenada exacta dentro de la imagen del cursor que representa el "pico" —el píxel que actúa como el punto de clic real. Lo defines con dos números después de la URL, en píxeles desde la esquina superior izquierda de la imagen:
/* hotspot en x=0, y=0 (esquina superior izquierda) */
.custom-svg {
cursor: url("cursor.svg") 0 0, pointer;
}
/* hotspot centrado en una imagen de 32x32 */
.crosshair-custom {
cursor: url("crosshair.png") 16 16, crosshair;
}Si no defines el hotspot correctamente, el clic puede registrarse en un punto diferente al que visualmente parece el puntero, lo que genera una experiencia frustrante para el usuario.
Tamaños, optimización y calidad del cursor
Esto lo aprendí a base de prueba y error: si la imagen es demasiado grande, el movimiento del cursor se siente torpe y lento, porque el navegador tiene que escalarla en tiempo real. Las dimensiones recomendadas son 24×24 o 32×32 píxeles. Algunos navegadores tienen un límite máximo de 128×128 px, pero en la práctica, cuanto más pequeña y ligera sea la imagen, mejor rendimiento tendrás.
Buenas prácticas de UX al elegir un cursor
- Cuándo cambiar el cursor realmente mejora la experiencia:
- Elementos que no son nativamente interactivos pero que sí lo son en tu UI (tarjetas clicables,
divs con eventos, etc.) - Interfaces de arrastrar y soltar (
cursor: grabantes de arrastrar,cursor: grabbingdurante el arrastre) - Elementos gráficos como
<canvas>, sliders personalizados o editores visuales - Interfaces altamente visuales o de juegos donde el cursor forma parte del lenguaje visual
- Elementos que no son nativamente interactivos pero que sí lo son en tu UI (tarjetas clicables,
- Casos donde NO debes cambiar el cursor:
- Si el elemento ya tiene un comportamiento estándar que el usuario reconoce: los enlaces llevan
pointer, el texto llevatexty los botones llevanpointer. Respetar esas convenciones evita confusión. - No uses
cursor: nonea menos que estés construyendo un cursor personalizado completo con JavaScript, porque ocultar el cursor sin reemplazarlo es una experiencia pésima.
- Si el elemento ya tiene un comportamiento estándar que el usuario reconoce: los enlaces llevan
- Cursores y pantallas táctiles (lo que nadie te dice):
- En dispositivos móviles y táctiles no existe el concepto de cursor, así que no dependas de él como único indicador de interactividad.
- Complementa siempre con señales visuales alternativas: sombras, bordes, cambios de color al estado
:active, iconos o animaciones de feedback.
Accesibilidad y diseño: hacer cursores útiles para todos
El cursor que defines en CSS no afecta por igual a todos los usuarios, porque no todos interactúan con tu interfaz del mismo modo. Dependiendo del dispositivo:
- Ratón: interacción precisa, se beneficia de todos los tipos de cursor
- Trackpad: precisión media, los cursores funcionan pero con menos granularidad
- Pantalla táctil: sin cursor físico; los estilos de
cursorno tienen efecto - Stylus / lápiz digital: comportamiento mixto, varía según el sistema operativo y el navegador
Media queries del puntero: pointer y any-pointer
CSS te da una herramienta poderosa para detectar el tipo de puntero del usuario y adaptar tu interfaz en consecuencia: las media queries pointer y any-pointer. Esto es especialmente útil para no aplicar lógica de cursor donde no tiene sentido:
/* El usuario usa dedo en pantalla táctil → no apliques cursores personalizados */
@media (pointer: coarse) {
.cursor-custom {
cursor: auto;
}
}
/* El usuario tiene un puntero preciso (ratón) → puedes enriquecer la experiencia */
@media (pointer: fine) {
.drag {
cursor: grab;
}
}El valor coarse identifica dispositivos táctiles o de baja precisión, mientras que fine identifica ratones y trackpads. Usar estas queries te permite construir experiencias verdaderamente adaptativas.
Diferencia entre cursor y caret-color
Mucha gente confunde estos dos conceptos, así que vale la pena aclararlo:
- La propiedad
cursorcontrola el puntero del ratón, que sigue el movimiento del dispositivo de entrada. - La propiedad
caret-colorcontrola el color del cursor de texto —esa barra vertical parpadeante que aparece dentro de uninputotextareacuando estás escribiendo.
input {
caret-color: red; /* cambia el color de la barra de escritura */
}Son propiedades independientes y complementarias: cursor define cómo se ve el puntero al acercarse al campo, y caret-color define cómo se ve el punto de inserción una vez que el usuario está escribiendo dentro de él.
Ejemplos listos para copiar: cursores CSS para tu proyecto
Botones, enlaces e inputs:
/* Cualquier botón o enlace clicable */
.boton {
cursor: pointer;
}
/* Input de texto o área editable */
.editable {
cursor: text;
}Menús, sliders y elementos arrastrables:
/* Elemento arrastrable: grab antes, grabbing durante */
.drag {
cursor: grab;
}
.drag:active {
cursor: grabbing;
}Zona bloqueada o no disponible:
/* Botón deshabilitado o acción no permitida */
.bloqueado {
cursor: not-allowed;
opacity: 0.5;
}Cursor personalizado con SVG e hotspot:
/* SVG como cursor, con hotspot definido y fallback estándar */
.custom-svg {
cursor: url("cursor.svg") 0 0, pointer;
}Preguntas frecuentes sobre cursores CSS (FAQ)
- ¿Funcionan los cursores en pantallas táctiles?
- No. En dispositivos táctiles no existe cursor físico, por lo que la propiedad
cursorno tiene ningún efecto visible.
- No. En dispositivos táctiles no existe cursor físico, por lo que la propiedad
- ¿Por qué mi cursor personalizado no aparece?
- Las causas más comunes son: la imagen supera el tamaño máximo permitido (generalmente 128 px), el formato no es compatible con ese navegador, o falta el valor de fallback al final de la declaración
cursor.
- Las causas más comunes son: la imagen supera el tamaño máximo permitido (generalmente 128 px), el formato no es compatible con ese navegador, o falta el valor de fallback al final de la declaración
- ¿Qué formatos de imagen acepta CSS para cursores personalizados?
- Los formatos más ampliamente soportados son
.png,.gify.cur. El formato.svgtambién funciona en navegadores modernos, pero con soporte parcial.
- Los formatos más ampliamente soportados son
- ¿Puedo poner un cursor diferente en un
div?- Sí, la propiedad
cursorse aplica por selector CSS y funciona en cualquier elemento HTML, no solo en los elementos interactivos nativos.
- Sí, la propiedad
- ¿Qué tamaño debe tener un cursor personalizado?
- El tamaño ideal es 24×24 o 32×32 píxeles. Tamaños mayores pueden provocar que el movimiento del cursor se sienta lento o que el navegador lo rechace directamente.
- ¿Qué es el hotspot y por qué importa?
- El hotspot es la coordenada dentro de la imagen del cursor que corresponde al punto de clic real. Se define con dos valores en píxeles después de la URL:
url("cursor.png") 0 0, pointer. Si no lo defines correctamente, el clic puede registrarse en el lugar equivocado.
- El hotspot es la coordenada dentro de la imagen del cursor que corresponde al punto de clic real. Se define con dos valores en píxeles después de la URL:
Conclusiones
Los cursores con CSS son una herramienta pequeña pero con un impacto real en la experiencia de usuario cuando se usan con criterio. No se trata de decorar por decorar: un cursor bien elegido comunica affordance, guía la interacción y hace que tu interfaz se sienta más intuitiva y profesional.
Como aprendí cuando empecé a experimentar con ellos, los detalles marcan la diferencia: buenos fallbacks, formatos compatibles, tamaños correctos, hotspot bien definido, y siempre pensando en si el dispositivo del usuario tiene cursor en primer lugar. Si aplicas estas prácticas, notarás que tu interfaz gana en claridad sin esfuerzo aparente.
Y recuerda: el mejor cursor es el que el usuario no necesita pensar. Si está haciendo su trabajo, es invisible.