Custom Web Cursors

Share
Custom Web Cursors with Elementor

This guide will show you how to integrate a custom web cursor on your sites, customize it, and apply it to different page elements.

Prepare Code Integration

  1. Go to your WordPress dashboard.
  2. Navigate to Elementor > Custom Code.
  3. Click on Add New Code.
  4. Name the code, for example: Custom Cursor.
  5. Choose the location </body> – End .
  6. Paste the following code (HTML, CSS, and JS included):
<script>
document.addEventListener('DOMContentLoaded', function () {
    let defaultSetting = {
        size: '1',
        textColor: '#FFFFFF',
        backgroundColor: '#FFFFFF',
        mixBlendMode: 'difference',
        transitionDuration: '0.3s',
        cursor: 'inherit',
    }

    let selectorsSettings = [
        {
            selector: '.link-hover',
            size: '4',
            textColor: '#FFFFFF',
            backgroundColor: '#FFFFFF',
            mixBlendMode: 'difference',
            transitionDuration: '0.3s',
            cursor: 'pointer',
        },
        {
            selector: '.article',
            message: 'Voir',
            textColor: '#000',
            backgroundColor: '#FFFFFF',
            mixBlendMode: 'difference',
            size: '8',
            fontSize: '2px',
            fontFamily: 'sora',
            transitionDuration: '0.3s',
            cursor: 'pointer',
        },
    ];

    document.body.insertAdjacentHTML('beforeEnd', "<div class='ehow_mouse'><div class='ehow_mouse_content'></div></div>");

    let mouse = document.querySelector('.ehow_mouse');
    let mouseContent = document.querySelector('.ehow_mouse_content');

    document.addEventListener('mousemove', function(e){
        mouse.style.transform = `translate3d(${e.clientX}px, ${e.clientY}px, 0)`;
    });

    if(typeof defaultSetting === 'object'){
        document.addEventListener('mousemove', setDefault);
        if(defaultSetting.cursor){
            document.body.style.cursor = defaultSetting.cursor;
        }
    }

    let enteredAreas = [];

    function init(isPopup){
        selectorsSettings.forEach((setting, i, allSettings) => {
            let showMouseHoverElems;
            if(isPopup){
                showMouseHoverElems = document.querySelectorAll('.dialog-lightbox-widget ' + setting.selector);
            } else {
                showMouseHoverElems = document.querySelectorAll(setting.selector + ':not(.mouse-init)');
            }

            showMouseHoverElems.forEach(e => {
                e.classList.add('mouse-init');
                e.addEventListener('mouseenter', function() {
                    enteredAreas.push(i);
                    updateMouse(setting);
                });
                e.addEventListener('mouseleave', function() {
                    enteredAreas.pop();
                    if(enteredAreas.length > 0){
                        updateMouse(allSettings[enteredAreas[enteredAreas.length-1]])
                    } else if(typeof defaultSetting === 'object'){
                        updateMouse(defaultSetting)
                    } else {
                        mouse.style.setProperty('--mouse-size', 0)
                    }
                });
                if(setting.cursor){
                    e.style.cursor = setting.cursor;
                }
            });
        });
    };

    init();

    if(typeof jQuery === 'function'){
        jQuery(document).on('elementor/popup/show', () => {
            init(true);
        });
    }

    function updateMouse(setting){
        mouseContent.innerHTML = setting.message || '';
        mouse.style.setProperty('--mouse-size', setting.size || 1);
        mouse.style.setProperty('--mouse-text-color', setting.textColor || '#999999');
        mouse.style.setProperty('--mouse-background-color', setting.backgroundColor || 'transparent');
        if(setting.image) mouse.style.setProperty('--mouse-background-image', setting.image);
        if(setting.imageSize) mouse.style.setProperty('--mouse-background-image-size', setting.imageSize);
        if(setting.border) mouse.style.setProperty('--mouse-border', setting.border);
        if(setting.borderRadius) mouse.style.setProperty('--mouse-border-radius', setting.borderRadius);
        if(setting.mixBlendMode) mouse.style.setProperty('--mouse-mix-blend-mode', setting.mixBlendMode);
        if(setting.filter) mouse.style.setProperty('--mouse-filter', setting.filter);
        if(setting.fontSize) mouse.style.setProperty('--mouse-font-size', setting.fontSize);
        if(setting.fontFamily) mouse.style.setProperty('--mouse-font-family', setting.fontFamily);
        if(setting.transitionDuration) mouse.style.setProperty('--mouse-transition-duration', setting.transitionDuration);
        if(setting.backDropFilter) mouse.style.setProperty('--mouse-backdrop', setting.backDropFilter);
    }
});
</script>

<style>
@media (hover: hover) {
    .ehow_mouse {
        position: fixed;
        top: 0; left: 0;
        z-index: 999999;
        pointer-events: none;
        will-change: transform;
        mix-blend-mode: var(--mouse-mix-blend-mode, none);
    }
    .ehow_mouse .ehow_mouse_content {
        position: absolute;
        top: -24px; left: -24px;
        width: 48px; height: 48px;
        transform: scale(var(--mouse-size, 1));
        background-image: var(--mouse-background-image, none);
        background-color: var(--mouse-background-color, transparent);
        background-repeat: no-repeat;
        background-position: center center;
        background-size: var(--mouse-background-image-size, 50%);
        border: var(--mouse-border, none);
        border-radius: var(--mouse-border-radius, 50%);
        filter: var(--mouse-filter, none);
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: var(--mouse-font-size, 12px);
        font-family: var(--mouse-font-family, inherit);
        color: var(--mouse-text-color, transparent);
        text-align: center;
        transition: transform var(--mouse-transition-duration, 0.3s) ease-in-out, background-color var(--mouse-transition-duration, 0.3s);
        backdrop-filter: var(--mouse-backdrop);
        -webkit-backdrop-filter: var(--mouse-backdrop);
    }
}
</style>

Customize the Cursor

Configuration Objects

  • defaultSetting : defines the default cursor across the entire page.
  • selectorsSettings : defines the cursor on specific elements via CSS selectors.

Available Properties

PropertyDescriptionExample
messageText in the center of the cursor'Lire'
sizeCursor size (scale)'2'
textColorText color'#FFF'
backgroundColorCursor background color'rgba(0,0,0,0.5)'
imageImage or gradient'url(image.svg)' or 'linear-gradient(...)'
imageSizeImage size'50%'
borderCursor border'3px solid #000'
borderRadiusCorner radius'50%'
filterCSS effects (e.g., drop-shadow)'drop-shadow(0 0 5px #000)'
fontSizeText size'12px'
fontFamilyText font'Roboto'
transitionDurationTransition duration'0.3s'
cursorNative cursor'pointer' or 'none'
mixBlendModeBlend mode'difference'
backDropFilterFrosted glass effect'blur(25px)'

Target Specific Elements

Add a CSS Class to an Elementor Widget

  1. Open the page with Elementor.
  2. Select the widget you want to target (button, image, section, etc.).
  3. In the left panel, go to Advanced > CSS Classes.
  4. Add a unique class name, for example: curseur-personnalise

⚠️ Do not add the dot (.) here, just the name.

Modify the Code to Target this Class

In the selectorsSettings array of your script, add an object for this CSS class:

{
    selector: '.curseur-personnalise',  // le point est obligatoire ici
    message: 'Voir plus',
    size: '3',
    textColor: '#FFF',
    backgroundColor: '#333',
    cursor: 'pointer',
    borderRadius: '50%',
    transitionDuration: '0.3s'
}
  • selector : the CSS class you just created (with a dot in front).
  • message : text in the center of the cursor.
  • size : cursor size (scale).
  • textColor and backgroundColor: colors.
  • cursor : native cursor type (“pointer”, “none”, etc.).
  • borderRadius : to round the cursor if needed.
  • transitionDuration : animation duration.

Debugging

  • If the cursor does not appear, open the browser console (F12).
  • Check for syntax errors in defaultSetting or selectorsSettings.
  • Ensure correct commas and single quotes.
Category
Compatible
WordPress, Elementor
Updated
17 Sep 2025

Built with Elementor

Host, create, and grow your dream website with the leading platform for WordPress.

Inspire your Elementor projects with 1 animation per week.

Thank you for subscribing!