¿Te has fijado alguna vez en esas webs que tienen pequeños iconos siguiendo al cursor del ratón? Es un efecto que puede dar mucha personalidad a tu sitio web y hacer que la experiencia de usuario sea más memorable.
Aunque pueda parecer algo complejo, la verdad es que con un poco de CSS y JavaScript, si me apuras incluso con plugins, puedes conseguir efectos realmente chulos.
¿Por qué añadir iconos al cursor?
En un mundo donde la atención del usuario es oro puro, cualquier detalle que haga tu web más única puede marcar la diferencia. Los iconos que siguen al cursor no son solo un capricho estético, sino una herramienta más para reforzar tu marca y crear una experiencia diferencial.
Imagínate una tienda online de productos artesanales donde aparece una pequeña estrella dorada siguiendo el cursor, o un blog de cocina donde una mini cuchara acompaña cada movimiento del ratón. Son detalles de personalización, de identidad, que la gente recuerda y que pueden hacer que vuelvan a tu web.
Además, técnicamente hablando, es un ejercicio perfecto para entender cómo interactúan CSS y JavaScript en tiempo real, cómo funciona el sistema de coordenadas del navegador y cómo optimizar efectos visuales sin que afecten al rendimiento.
Importante – Dispositivos móviles: Todos los códigos de este artículo incluyen detección automática para desactivarse completamente en dispositivos táctiles (móviles y tablets). Esto es fundamental porque en pantallas táctiles no hay cursor, por lo que el efecto no tiene sentido y solo consumiría recursos innecesarios. La detección se hace en tres capas (PHP, CSS y JavaScript) para asegurar que nunca aparezca en móviles.
Casos de uso más interesantes
- Webs corporativas y portfolios: Un icono relacionado con tu logo o actividad profesional puede reforzar tu identidad de marca de forma sutil pero efectiva.
- E-commerce y tiendas online: Iconos temáticos (carrito, corazón, estrella) que aparezcan al pasar por productos o secciones específicas pueden guiar sutilmente la atención del usuario.
- Eventos y campañas temporales: Perfecto para Black Friday, Navidad, lanzamientos de productos o celebraciones especiales. Un corazón para San Valentín o copos de nieve en invierno.
- Blogs y medios: Iconos que cambien según la sección (lupa en búsquedas, pluma en artículos, chat en comentarios) ayudan a contextualizar el contenido.
- Webs educativas o infantiles: Efectos más llamativos como estelas de partículas pueden hacer el aprendizaje más divertido y visual.
- Presentaciones y landing pages: Para captar atención en momentos clave, como al pasar sobre botones de llamada a la acción importantes.
Ventajas y desventajas de añadir iconos al cursor
| Aspecto | Ventajas | Inconvenientes |
|---|---|---|
| Atractivo visual | Efecto sorpresa que diferencia tu web de la competencia, añade dinamismo y modernidad | Puede resultar molesto si se abusa, distrae del contenido principal |
| Identidad de marca | Refuerza el branding de forma sutil, distinta y coherente con la estética general | Si no encaja con la marca puede parecer amateur o fuera de lugar |
| Experiencia de usuario | Hace la navegación más divertida e interactiva, guía la atención de forma intuitiva | Puede interferir con la experiencia de uso en algunos dispositivos o situaciones |
| Rendimiento | Con código optimizado el impacto es mínimo, funciona bien en navegadores modernos | Puede consumir recursos innecesarios, especialmente en dispositivos de gama baja |
| Compatibilidad | Funciona en la mayoría de navegadores de escritorio, fácil de implementar | No funciona en dispositivos táctiles, puede causar problemas con lectores de pantalla |
| Mantenimiento | Una vez implementado requiere poco mantenimiento, fácil de activar/desactivar | Hay que probar con actualizaciones del tema, puede entrar en conflicto con otros plugins |
| Personalización | Totalmente personalizable, se puede adaptar a cualquier diseño o temporada | Requiere conocimientos técnicos para modificaciones avanzadas |
Ejemplos de código para añadir iconos al cursor
Todos los códigos que vas a encontrar a continuación están pensados para funcionar como códigos independientes en tu functions.php o en un plugin de snippets. Puedes activar uno solo o combinar varios según tus necesidades, siempre teniendo en cuenta que más efectos no siempre significa mejor experiencia.
Icono básico que sigue al cursor
Este es el ejemplo más sencillo. Un icono que acompaña al cursor con un pequeño desplazamiento para que no tape lo que estás señalando.
/* Icono básico que sigue al cursor */
function ayudawp_cursor_icon() {
// Solo en la web, no en el admin
if ( is_admin() ) return;
// No cargar en dispositivos móviles
if ( wp_is_mobile() ) return;
?>
<style>
.ayudawp-cursor-icon {
position: fixed;
top: 0;
left: 0;
width: 32px;
height: 32px;
transform: translate(-50%, -50%);
pointer-events: none;
z-index: 99999;
user-select: none;
background: url("https://tudominio.com/tu-icono.png") no-repeat center/contain;
transition: left 0.1s ease, top 0.1s ease;
visibility: hidden;
}
/* Ocultar en dispositivos táctiles */
@media (hover: none), (pointer: coarse), (max-width: 768px) {
.ayudawp-cursor-icon {
display: none !important;
visibility: hidden !important;
}
}
</style>
<div class="ayudawp-cursor-icon"></div>
<script>
(function(){
'use strict';
// Detección de dispositivos táctiles
if ('ontouchstart' in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0 ||
window.innerWidth <= 768) {
const el = document.querySelector('.ayudawp-cursor-icon');
if (el && el.parentNode) {
el.parentNode.removeChild(el);
}
return;
}
const icon = document.querySelector('.ayudawp-cursor-icon');
if (!icon) return;
// Hacer visible solo en desktop
icon.style.visibility = 'visible';
// Capturar movimiento del ratón
document.addEventListener('mousemove', function(e){
const offsetX = 30; // Píxeles a la derecha
const offsetY = 20; // Píxeles hacia abajo
icon.style.left = (e.clientX + offsetX) + 'px';
icon.style.top = (e.clientY + offsetY) + 'px';
});
})();
</script>
<?php
}
add_action( 'wp_footer', 'ayudawp_cursor_icon' );
![]()
Icono con estela suave
Un efecto más elaborado donde el icono deja una estela que se desvanece gradualmente, creando una sensación de movimiento fluido.
/* Icono con estela suave */
function ayudawp_cursor_trail() {
// Solo en la web, no en el admin
if ( is_admin() ) return;
// No cargar en dispositivos móviles
if ( wp_is_mobile() ) return;
?>
<style>
.ayudawp-trail-dot {
position: fixed;
width: 28px;
height: 28px;
background: url("https://tudominio.com/tu-icono.png") no-repeat center/contain;
pointer-events: none;
z-index: 99999;
user-select: none;
transform: translate(-50%, -50%);
transition: opacity 0.6s ease-out, transform 0.3s ease-out;
will-change: transform, opacity;
visibility: hidden;
}
/* Ocultar en dispositivos táctiles */
@media (hover: none), (pointer: coarse), (max-width: 768px) {
.ayudawp-trail-dot {
display: none !important;
visibility: hidden !important;
}
}
</style>
<script>
(function(){
'use strict';
// Detección de dispositivos táctiles
if ('ontouchstart' in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0 ||
window.innerWidth <= 768) {
return;
}
const trailLength = 5;
const dots = [];
let mouseX = 0, mouseY = 0;
// Crear puntos de la estela
for (let i = 0; i < trailLength; i++) {
const dot = document.createElement('div');
dot.className = 'ayudawp-trail-dot';
dot.style.opacity = '0';
dot.style.visibility = 'visible';
document.body.appendChild(dot);
dots.push({
element: dot,
x: 0,
y: 0
});
}
// Capturar movimiento del ratón
document.addEventListener('mousemove', function(e){
mouseX = e.clientX;
mouseY = e.clientY;
});
// Animar estela
function animate() {
dots.forEach((dot, i) => {
const targetX = mouseX + 30;
const targetY = mouseY + 20;
dot.x += (targetX - dot.x) * (0.15 - i * 0.02);
dot.y += (targetY - dot.y) * (0.15 - i * 0.02);
dot.element.style.left = dot.x + 'px';
dot.element.style.top = dot.y + 'px';
dot.element.style.opacity = (1 - i * 0.15);
dot.element.style.transform = `translate(-50%, -50%) scale(${1 - i * 0.1})`;
});
requestAnimationFrame(animate);
}
animate();
})();
</script>
<?php
}
add_action( 'wp_footer', 'ayudawp_cursor_trail' );
![]()
Icono con estela de partículas que se dispersan
Un efecto más espectacular donde el icono se descompone en pequeñas partículas que se dispersan y desvanecen, como polvo estelar.
/* Estela de partículas dispersas */
function ayudawp_cursor_particles() {
// Solo en la web, no en el admin
if ( is_admin() ) return;
// No cargar en dispositivos móviles
if ( wp_is_mobile() ) return;
?>
<style>
.ayudawp-particle {
position: fixed;
width: 6px;
height: 6px;
background: #ff6b6b;
border-radius: 50%;
pointer-events: none;
z-index: 99999;
user-select: none;
transform: translate(-50%, -50%);
will-change: transform, opacity;
}
/* Ocultar en dispositivos táctiles */
@media (hover: none), (pointer: coarse), (max-width: 768px) {
.ayudawp-particle {
display: none !important;
}
}
</style>
<script>
(function(){
'use strict';
// Detección de dispositivos táctiles
if ('ontouchstart' in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0 ||
window.innerWidth <= 768) {
return;
}
const particles = [];
let mouseX = 0, mouseY = 0;
// Capturar movimiento del ratón
document.addEventListener('mousemove', function(e){
mouseX = e.clientX;
mouseY = e.clientY;
// Crear nuevas partículas ocasionalmente
if (Math.random() < 0.3) {
createParticle();
}
});
function createParticle() {
const particle = document.createElement('div');
particle.className = 'ayudawp-particle';
document.body.appendChild(particle);
const particleData = {
element: particle,
x: mouseX,
y: mouseY,
vx: (Math.random() - 0.5) * 6,
vy: (Math.random() - 0.5) * 6,
life: 1.0,
decay: 0.02 + Math.random() * 0.02
};
particles.push(particleData);
// Limitar número de partículas
if (particles.length > 50) {
const old = particles.shift();
if (old.element.parentNode) {
old.element.parentNode.removeChild(old.element);
}
}
}
function animate() {
for (let i = particles.length - 1; i >= 0; i--) {
const p = particles[i];
p.x += p.vx;
p.y += p.vy;
p.life -= p.decay;
p.vx *= 0.98;
p.vy *= 0.98;
p.element.style.left = p.x + 'px';
p.element.style.top = p.y + 'px';
p.element.style.opacity = p.life;
p.element.style.transform = `translate(-50%, -50%) scale(${p.life})`;
if (p.life <= 0) {
if (p.element.parentNode) {
p.element.parentNode.removeChild(p.element);
}
particles.splice(i, 1);
}
}
requestAnimationFrame(animate);
}
animate();
})();
</script>
<?php
}
add_action( 'wp_footer', 'ayudawp_cursor_particles' );

Cursor con icono que se muestra solo en elementos interactivos
Este código hace que el icono aparezca únicamente cuando pasas el cursor sobre elementos específicos como botones, enlaces o áreas destacadas.
/* Icono solo en elementos interactivos */
function ayudawp_cursor_interactive() {
// Solo en la web, no en el admin
if ( is_admin() ) return;
// No cargar en dispositivos móviles
if ( wp_is_mobile() ) return;
?>
<style>
.ayudawp-interactive-cursor {
position: fixed;
top: 0;
left: 0;
width: 32px;
height: 32px;
transform: translate(-50%, -50%) scale(0);
pointer-events: none;
z-index: 99999;
user-select: none;
background: url("https://tudominio.com/tu-icono.png") no-repeat center/contain;
transition: transform 0.3s ease, opacity 0.3s ease;
opacity: 0;
will-change: transform, opacity;
visibility: hidden;
}
.ayudawp-interactive-cursor.active {
transform: translate(-50%, -50%) scale(1);
opacity: 1;
}
/* Ocultar en dispositivos táctiles */
@media (hover: none), (pointer: coarse), (max-width: 768px) {
.ayudawp-interactive-cursor {
display: none !important;
visibility: hidden !important;
}
}
</style>
<div class="ayudawp-interactive-cursor"></div>
<script>
(function(){
'use strict';
// Detección de dispositivos táctiles
if ('ontouchstart' in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0 ||
window.innerWidth <= 768) {
const el = document.querySelector('.ayudawp-interactive-cursor');
if (el && el.parentNode) {
el.parentNode.removeChild(el);
}
return;
}
const cursor = document.querySelector('.ayudawp-interactive-cursor');
if (!cursor) return;
cursor.style.visibility = 'visible';
let mouseX = 0, mouseY = 0;
const interactiveSelectors = [
'a',
'button',
'.button',
'.btn',
'input[type="button"]',
'input[type="submit"]',
'.woocommerce-button',
'.wp-block-button',
'[role="button"]'
].join(', ');
// Capturar movimiento del ratón
document.addEventListener('mousemove', function(e){
mouseX = e.clientX;
mouseY = e.clientY;
cursor.style.left = (mouseX + 25) + 'px';
cursor.style.top = (mouseY + 15) + 'px';
});
// Detectar hover en elementos interactivos
document.addEventListener('mouseover', function(e){
if (e.target.matches(interactiveSelectors)) {
cursor.classList.add('active');
}
});
document.addEventListener('mouseout', function(e){
if (e.target.matches(interactiveSelectors)) {
cursor.classList.remove('active');
}
});
})();
</script>
<?php
}
add_action( 'wp_footer', 'ayudawp_cursor_interactive' );
![]()
Cursor contextual que cambia según la sección o elemento
Un sistema inteligente que muestra diferentes iconos dependiendo de dónde esté el cursor: lupa en búsquedas, cadena en enlaces, carrito en productos, lápiz en artículos, etc.
/* Cursor contextual adaptativo */
function ayudawp_cursor_contextual() {
// Solo en la web, no en el admin
if ( is_admin() ) return;
// No cargar en dispositivos móviles
if ( wp_is_mobile() ) return;
?>
<style>
.ayudawp-contextual-cursor {
position: fixed;
top: 0;
left: 0;
width: 28px;
height: 28px;
transform: translate(-50%, -50%);
pointer-events: none;
z-index: 99999;
user-select: none;
transition: background-image 0.3s ease, transform 0.2s ease;
will-change: transform, background-image;
visibility: hidden;
}
.ayudawp-contextual-cursor.search {
background: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='%23666' viewBox='0 0 24 24'><path d='M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z'/></svg>") no-repeat center/contain;
}
.ayudawp-contextual-cursor.cart {
background: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='%23666' viewBox='0 0 24 24'><path d='M7 18c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zM1 2v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.14 0-.25-.11-.25-.25l.03-.12L8.1 13h7.45c.75 0 1.41-.41 1.75-1.03L21.7 4H5.21l-.94-2H1zm16 16c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z'/></svg>") no-repeat center/contain;
}
.ayudawp-contextual-cursor.edit {
background: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='%23666' viewBox='0 0 24 24'><path d='M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34a.996.996 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z'/></svg>") no-repeat center/contain;
}
.ayudawp-contextual-cursor.link {
background: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='%23666' viewBox='0 0 24 24'><path d='M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z'/></svg>") no-repeat center/contain;
}
/* Ocultar en dispositivos táctiles */
@media (hover: none), (pointer: coarse), (max-width: 768px) {
.ayudawp-contextual-cursor {
display: none !important;
visibility: hidden !important;
}
}
</style>
<div class="ayudawp-contextual-cursor"></div>
<script>
(function(){
'use strict';
// Detección de dispositivos táctiles
if ('ontouchstart' in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0 ||
window.innerWidth <= 768) {
const el = document.querySelector('.ayudawp-contextual-cursor');
if (el && el.parentNode) {
el.parentNode.removeChild(el);
}
return;
}
const cursor = document.querySelector('.ayudawp-contextual-cursor');
if (!cursor) return;
cursor.style.visibility = 'visible';
let mouseX = 0, mouseY = 0;
const contextMap = [
{ selectors: ['[type="search"]', '.search-field', '.search-form'], class: 'search' },
{ selectors: ['.woocommerce .products .product', '.add-to-cart', '.cart'], class: 'cart' },
{ selectors: ['article', '.post', '.entry-content', 'p'], class: 'edit' },
{ selectors: ['a'], class: 'link' }
];
// Capturar movimiento del ratón
document.addEventListener('mousemove', function(e){
mouseX = e.clientX;
mouseY = e.clientY;
cursor.style.left = (mouseX + 30) + 'px';
cursor.style.top = (mouseY + 20) + 'px';
});
// Detectar cambios de contexto
document.addEventListener('mouseover', function(e){
cursor.className = 'ayudawp-contextual-cursor';
for (const context of contextMap) {
for (const selector of context.selectors) {
if (e.target.matches(selector) || e.target.closest(selector)) {
cursor.classList.add(context.class);
return;
}
}
}
});
})();
</script>
<?php
}
add_action( 'wp_footer', 'ayudawp_cursor_contextual' );
Cursor con icono con estela y efecto de clic explosivo
Combina un icono personalizado con estela, y además un efecto especial cuando haces clic: aparece una pequeña explosión de partículas.
/* Estela con efecto de clic explosivo */
function ayudawp_cursor_click_explosion() {
// Solo en la web, no en el admin
if ( is_admin() ) return;
// No cargar en dispositivos móviles
if ( wp_is_mobile() ) return;
?>
<style>
.ayudawp-trail-icon {
position: fixed;
width: 24px;
height: 24px;
background: url("https://tudominio.com/tu-icono.png") no-repeat center/contain;
pointer-events: none;
z-index: 99999;
user-select: none;
transform: translate(-50%, -50%);
transition: opacity 0.5s ease-out;
will-change: transform, opacity;
}
.ayudawp-explosion-particle {
position: fixed;
width: 8px;
height: 8px;
background: linear-gradient(45deg, #ff6b6b, #ffa500);
border-radius: 50%;
pointer-events: none;
z-index: 99998;
user-select: none;
transform: translate(-50%, -50%);
will-change: transform, opacity;
}
/* Ocultar en dispositivos táctiles */
@media (hover: none), (pointer: coarse), (max-width: 768px) {
.ayudawp-trail-icon,
.ayudawp-explosion-particle {
display: none !important;
}
}
</style>
<script>
(function(){
'use strict';
// Detección de dispositivos táctiles
if ('ontouchstart' in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0 ||
window.innerWidth <= 768) {
return;
}
const trailIcons = [];
const explosionParticles = [];
let mouseX = 0, mouseY = 0;
// Crear iconos de estela
for (let i = 0; i < 4; i++) {
const icon = document.createElement('div');
icon.className = 'ayudawp-trail-icon';
icon.style.opacity = '0';
document.body.appendChild(icon);
trailIcons.push({
element: icon,
x: 0,
y: 0
});
}
// Capturar movimiento del ratón
document.addEventListener('mousemove', function(e){
mouseX = e.clientX;
mouseY = e.clientY;
});
// Efecto de explosión al hacer clic
document.addEventListener('click', function(e){
createExplosion(e.clientX, e.clientY);
});
function createExplosion(x, y) {
const particleCount = 8;
for (let i = 0; i < particleCount; i++) {
const particle = document.createElement('div');
particle.className = 'ayudawp-explosion-particle';
document.body.appendChild(particle);
const angle = (i / particleCount) * Math.PI * 2;
const velocity = 3 + Math.random() * 4;
const particleData = {
element: particle,
x: x,
y: y,
vx: Math.cos(angle) * velocity,
vy: Math.sin(angle) * velocity,
life: 1.0,
decay: 0.04 + Math.random() * 0.02
};
explosionParticles.push(particleData);
}
}
function animate() {
// Animar estela
trailIcons.forEach((icon, i) => {
const delay = i * 0.1;
const targetX = mouseX + 25;
const targetY = mouseY + 15;
icon.x += (targetX - icon.x) * (0.2 - delay);
icon.y += (targetY - icon.y) * (0.2 - delay);
icon.element.style.left = icon.x + 'px';
icon.element.style.top = icon.y + 'px';
icon.element.style.opacity = (1 - i * 0.2);
icon.element.style.transform = `translate(-50%, -50%) scale(${1 - i * 0.15})`;
});
// Animar partículas de explosión
for (let i = explosionParticles.length - 1; i >= 0; i--) {
const p = explosionParticles[i];
p.x += p.vx;
p.y += p.vy;
p.life -= p.decay;
p.vx *= 0.95;
p.vy *= 0.95;
p.element.style.left = p.x + 'px';
p.element.style.top = p.y + 'px';
p.element.style.opacity = p.life;
p.element.style.transform = `translate(-50%, -50%) scale(${p.life})`;
if (p.life <= 0) {
if (p.element.parentNode) {
p.element.parentNode.removeChild(p.element);
}
explosionParticles.splice(i, 1);
}
}
requestAnimationFrame(animate);
}
animate();
})();
</script>
<?php
}
add_action( 'wp_footer', 'ayudawp_cursor_click_explosion' );
![]()
Cursor con iconos personalizados configurable para eventos temporales
Este código te permite activar efectos especiales solo en fechas específicas que tú configures. Perfecto para Navidad, Black Friday, San Valentín o eventos especiales de tu negocio.
/* Cursor para eventos temporales */
function ayudawp_cursor_temporal_event() {
// Solo en la web, no en el admin
if ( is_admin() ) return;
// No cargar en dispositivos móviles
if ( wp_is_mobile() ) return;
// CONFIGURACIÓN DE EVENTOS - Personaliza aquí tus fechas
$events = array(
'christmas' => array(
'start' => '12-20',
'end' => '12-31',
'icon' => 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" fill="%23ff0000" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></svg>',
'color' => '#ff0000'
),
'halloween' => array(
'start' => '10-25',
'end' => '11-02',
'icon' => 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" fill="%23ff6600" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></svg>',
'color' => '#ff6600'
),
'valentine' => array(
'start' => '02-10',
'end' => '02-16',
'icon' => 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" fill="%23ff1493" viewBox="0 0 24 24"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>',
'color' => '#ff1493'
),
'custom_event' => array(
'start' => '06-15',
'end' => '06-20',
'icon' => 'https://tudominio.com/evento-especial.png',
'color' => '#00ff00'
)
);
// Verificar si estamos en algún evento activo
$current_date = date('m-d');
$active_event = null;
foreach ($events as $event_name => $event_data) {
if ($current_date >= $event_data['start'] && $current_date <= $event_data['end']) {
$active_event = $event_data;
break;
}
}
// Si no hay evento activo, no mostrar nada
if (!$active_event) return;
?>
<style>
.ayudawp-event-cursor {
position: fixed;
top: 0;
left: 0;
width: 32px;
height: 32px;
transform: translate(-50%, -50%);
pointer-events: none;
z-index: 99999;
user-select: none;
background: url("<?php echo esc_attr($active_event['icon']); ?>") no-repeat center/contain;
filter: drop-shadow(0 0 8px <?php echo esc_attr($active_event['color']); ?>);
animation: ayudawp-event-pulse 2s ease-in-out infinite;
visibility: hidden;
}
@keyframes ayudawp-event-pulse {
0%, 100% { transform: translate(-50%, -50%) scale(1); }
50% { transform: translate(-50%, -50%) scale(1.1); }
}
.ayudawp-event-trail {
position: fixed;
width: 12px;
height: 12px;
background: <?php echo esc_attr($active_event['color']); ?>;
border-radius: 50%;
pointer-events: none;
z-index: 99998;
user-select: none;
transform: translate(-50%, -50%);
box-shadow: 0 0 6px <?php echo esc_attr($active_event['color']); ?>;
will-change: transform, opacity;
}
/* Ocultar en dispositivos táctiles */
@media (hover: none), (pointer: coarse), (max-width: 768px) {
.ayudawp-event-cursor,
.ayudawp-event-trail {
display: none !important;
visibility: hidden !important;
}
}
</style>
<div class="ayudawp-event-cursor"></div>
<script>
(function(){
'use strict';
// Detección de dispositivos táctiles
if ('ontouchstart' in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0 ||
window.innerWidth <= 768) {
const el = document.querySelector('.ayudawp-event-cursor');
if (el && el.parentNode) {
el.parentNode.removeChild(el);
}
return;
}
const cursor = document.querySelector('.ayudawp-event-cursor');
if (!cursor) return;
cursor.style.visibility = 'visible';
const trails = [];
let mouseX = 0, mouseY = 0;
// Crear puntos de estela
for (let i = 0; i < 8; i++) {
const trail = document.createElement('div');
trail.className = 'ayudawp-event-trail';
trail.style.opacity = '0';
document.body.appendChild(trail);
trails.push({
element: trail,
x: 0,
y: 0
});
}
// Capturar movimiento del ratón
document.addEventListener('mousemove', function(e){
mouseX = e.clientX;
mouseY = e.clientY;
});
function animate() {
// Posicionar cursor principal
cursor.style.left = (mouseX + 25) + 'px';
cursor.style.top = (mouseY + 15) + 'px';
// Animar estela
trails.forEach((trail, i) => {
const delay = i * 0.08;
const targetX = mouseX + 25;
const targetY = mouseY + 15;
trail.x += (targetX - trail.x) * (0.15 - delay);
trail.y += (targetY - trail.y) * (0.15 - delay);
trail.element.style.left = trail.x + 'px';
trail.element.style.top = trail.y + 'px';
trail.element.style.opacity = (0.8 - i * 0.1);
trail.element.style.transform = `translate(-50%, -50%) scale(${1 - i * 0.08})`;
});
requestAnimationFrame(animate);
}
animate();
})();
</script>
<?php
}
add_action( 'wp_footer', 'ayudawp_cursor_temporal_event' );
![]()
Tablas de referencia para personalización
Propiedades CSS más relevantes
| Propiedad | Función | Ejemplos de valores | Notas importantes |
|---|---|---|---|
position |
Posicionamiento del elemento | fixed, absolute |
Siempre usar fixed para seguir el viewport |
transform |
Centrado y efectos visuales | translate(-50%, -50%), scale(1.2) |
Valores negativos centran, positivos desplazan |
z-index |
Orden de apilamiento | 99999, 9999 |
Números altos para estar encima de todo |
pointer-events |
Interacción con el cursor | none, auto |
none evita que el icono interfiera con clics |
user-select |
Selección de texto | none, auto |
none evita que el icono se pueda seleccionar |
will-change |
Optimización de rendimiento | transform, opacity |
Mejora rendimiento en animaciones |
transition |
Animaciones suaves | opacity 0.3s ease, transform 0.2s |
Duración en segundos, ease para suavidad |
opacity |
Transparencia | 0 (invisible), 1 (opaco), 0.5 (semitransparente) |
De 0 a 1, decimales permitidos |
background |
Imagen del icono | url("ruta.png") no-repeat center/contain |
contain mantiene proporciones |
filter |
Efectos visuales | drop-shadow(0 0 8px #ff0000), blur(2px) |
Para sombras, desenfoques, etc. |
visibility |
Visibilidad del elemento | visible, hidden |
Mejor que display para animaciones |
Métodos JavaScript esenciales
| Método/Propiedad | Función | Ejemplos de uso | Valores importantes |
|---|---|---|---|
addEventListener |
Capturar eventos | mousemove, click, mouseover |
mousemove es el más usado para seguir cursor |
clientX/clientY |
Coordenadas del ratón | e.clientX, e.clientY |
Posición relativa al viewport |
requestAnimationFrame |
Animaciones fluidas | requestAnimationFrame(animate) |
60 FPS, mejor que setInterval |
querySelector |
Seleccionar elemento | .querySelector('.mi-clase') |
Devuelve el primer elemento encontrado |
createElement |
Crear elementos | document.createElement('div') |
Para generar partículas dinámicamente |
appendChild |
Añadir al DOM | document.body.appendChild(elemento) |
Insertar elementos creados |
removeChild |
Eliminar del DOM | parent.removeChild(elemento) |
Para limpiar partículas muertas |
style.left/top |
Posicionar elemento | elemento.style.left = '100px' |
Valores en píxeles con ‘px’ |
classList |
Gestionar clases CSS | .add('activo'), .remove('inactivo') |
Para cambiar estados |
matches |
Verificar selectores | elemento.matches('a') |
Comprobar si elemento coincide |
Math.random() |
Números aleatorios | Math.random() * 10 |
De 0 a 1, multiplicar para rangos |
setTimeout |
Retrasos | setTimeout(función, 1000) |
Tiempo en milisegundos |
Plugins para añadir iconos al cursor
Si lo prefieres (tú verás) hay algunos plugins que ofrecen algo parecido – ni de lejos, ya te lo anticipo – a lo que hemos visto.
Cursor Trail
- Es un plugin simple que añade un efecto de estela al cursor.
- En sus ajustes permite elegir la imagen que sigue al cursor, ajustar la velocidad de desvanecimiento y la tasa de aparición del rastro.
- También permite decidir cuándo activar o desactivar el efecto (por ejemplo, solo en determinadas fechas).
- Ha sido actualizado recientemente.
- Tiene pocas instalaciones activas (≈ 100).
¿Lo recomiendo?
Puede valer la pena como opción de plugin para usuarios que no quieren tocar código. Las opciones de personalización son escasas, pero suficientes para casos básicos. No esperes que tenga efectos complejos de partículas, rutas avanzadas o condicionantes sofisticados. NO lo recomiendo, demasiado limitado.
Animated Mouse Cursor Trail
- En su versión gratuita ofrece solo 1 estilo de efecto.
- En la versión de pago (o pro) se anuncian 60 estilos distintos.
- El plugin no requiere editar configuraciones necesariamente (aunque para cambiar estilo sí).
- Ha sido actualizado recientemente.
- Tiene pocas instalaciones activas (≈ 100).
¿Lo recomiendo?
Este plugin tiene más posibilidades visuales (pero solo si adquieres la versión pro). Para alguien que quiera muchas variantes sin tocar código, puede ser atractivo, pero en la versión gratuita está bastante limitado. Pero NO, no lo recomiendo.
Recapitulando…
Añadir iconos al cursor en WordPress es una técnica que puede transformar completamente la percepción de tu web. Desde efectos simples hasta complejas animaciones con partículas, las posibilidades son prácticamente infinitas.
Lo más importante que debes recordar:
- Rendimiento ante todo: Siempre optimiza para dispositivos móviles y de gama baja. Los efectos visuales nunca deben comprometer la velocidad de carga o la experiencia de usuario.
- Menos es más: Un efecto sutil y bien ejecutado tiene mucho más impacto que múltiples efectos que compiten entre sí por la atención.
- Compatibilidad universal: Incluye siempre detección de dispositivos táctiles y media queries apropiadas. Tu web debe funcionar perfectamente tanto con efectos como sin ellos.
- Coherencia con tu marca: El icono debe reforzar tu identidad visual, no distraer de ella. Piensa en el cursor como una extensión más de tu diseño.
- Facilidad de mantenimiento: Estructura tu código de forma modular y comentada. Tu yo del futuro te lo agradecerá cuando necesites hacer cambios.
La clave está en encontrar el equilibrio perfecto entre impacto visual y usabilidad práctica. Cuando lo consigas, habrás añadido esa chispa especial que hace que tu web sea reconocible, única.
¿Te gustó este artículo? ¡Ni te imaginas lo que te estás perdiendo en YouTube!










Saludos Fernando, muy bueno, bien explicado, . . Lo usaremos, con tus créditos . .
Gracias, y no hacen falta créditos, con que te sirva me llega 🙂