Open In App

How to Map Mouse Position in CSS ?

Last Updated : 22 Dec, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

This article will describe how to map the position of the mouse on the web page using CSS. You can do this in CSS using:hover pseudo-class and custom properties that contain the relative position of the mouse and change accordingly with:hover.

Approach: To map the position of the mouse, we will maintain two custom properties –posX, –posY and update them along with the mouse movement. In CSS, we cannot get the position of the mouse like in javascript so we need to add a grid of cells(squares) with relative numbering on the entire web page and refer those cells to decide a relative value for the mouse position ( Note: we cannot get the absolute position of the mouse in CSS ). The number of rows and columns in the grid can be decided by you. In this case, we will create a grid of 10X10.

Example: In this example, we will create an absolute container of 10 * 10 = 100 <div> tags in the <body> tag that spans the entire body, and using display: grid property, we will make the grid. 

HTML




<!DOCTYPE html>
<html>
  
<head>
    <title>Create a Grid for Mouse Position</title>
  
    <style>
        .container {
            position: absolute;
            width: 100%;
            height: 100vh;
            display: grid;
            grid-template: repeat(10, 1fr) / repeat(10, 1fr);
            overflow: hidden;
        }
  
        .cell {
            width: 100%;
            height: 100%;
            border: 1px solid gray;
            z-index: 2;
        }
    </style>
</head>
  
<body>
    <h1 style="color:green;">
        GeeksforGeeks
    </h1>
      
    <h3>How to Map Mouse Position in CSS ?</h3>
  
    <div class="container">
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
    </div>
</body>
  
</html>


Output: 

 

In the above example, the cells have a common class name (.cell) and hence they can be selected using .cell:nth-child( n ) where n = Cell number in the grid. You have to assume the cell number starting from 1 and ending with 100.

---------------------------
|    1   |    2   |   3   |   .... so on till 10
|        |        |       |
---------------------------
|   11   |
|        |
----------
     .
     :
     91 .......................... so on till 100

Finding the values for –posX and –posY: The value of –posX (X-coordinate) and –posY(Y-coordinate) is relative and can start from any value. In this case, the value of –posX starts from 1 and increases when the mouse moves horizontally. For example, when we hover over the first column the –posX becomes 1 and for column 2 the value of –posX becomes 2, and so on. Similarly, for y-coordinate. Remember that, we should update them using the:hover pseudo-class.

.cell:nth-child(1):hover {
    --posX: 1;
    --posY: 1;
}

In the above code, when we hover over the first cell in the grid the –posX and –posY become (1,1).

The same code snippet must be included in each and every cell in the grid. To do this, we will analyze the grid, The grid contains 10 rows with numbers from 1 – 10 which means the –posY gets reflected with the change in the position of the mouse from one row to another. For example, the value of –posY = 3 when the mouse is at the third row. But to find the position of the row, we need to find the range of the row (starting and ending cell number). For example, in a 10X10 grid the range of the first row is 1 – 10, the second row is 11-20, and so on.

So in CSS, let’s say if you want to select the first row we do this:

.cell:nth-child(n + 1):nth-child(-n + 10):hover {
    --posY : 1
}

where,

  • n selects all the multiples of 1 and n+1 = first row.
  • -n + 10 is the last cell in the row.

For the second it becomes (n + 2) to (-n + 20) and so on.

Similarly, –posX changes when the mouse position changes from column to column. For –posX  when the mouse is in first column :

.cell:nth-child(10n+1):hover {
    --posX: 1 ;
}

where,

  • 10n selects every multiple of 10
  • 10n + 1 selects the first column

For the second it is 10n+2 and so on.

Now, you need to add the above code snippets to every cell in the grid-like shown in the below examples

Example 1: In this example, we will track the position of a mouse using the above approach and update the –posX and –posY using:hover pseudo-class and change the size of the central black circle of the page shown in the output. 

HTML




<!DOCTYPE html>
<html>
  
<head>
    <title>
        How to Map Mouse Position in CSS ?
    </title>
  
    <style>
        .container {
            height: 100vh;
            display: grid;
            grid-template: repeat(10, 1fr) / repeat(10, 1fr);
            position: absolute;
            width: 100%;
            height: 100vh;
            top: 0;
            left: 0;
        }
  
        .cell {
            width: 100%;
            height: 100%;
            border: 1px solid gray;
            z-index: 2;
        }
  
        .cell:nth-child(10n+2):hover~.parent {
            --posX: 1;
        }
  
        .cell:nth-child(n+11):nth-child(-n+20):hover~.parent {
            --posY: 1;
        }
  
        .cell:nth-child(10n+3):hover~.parent {
            --posX: 2;
        }
  
        .cell:nth-child(n+21):nth-child(-n+30):hover~.parent {
            --posY: 2;
        }
  
        .cell:nth-child(10n+4):hover~.parent {
            --posX: 3;
        }
  
        .cell:nth-child(n+31):nth-child(-n+40):hover~.parent {
            --posY: 3;
        }
  
        .cell:nth-child(10n+5):hover~.parent {
            --posX: 4;
        }
  
        .cell:nth-child(n+41):nth-child(-n+50):hover~.parent {
            --posY: 4;
        }
  
        .cell:nth-child(10n+6):hover~.parent {
            --posX: 5;
        }
  
        .cell:nth-child(n+51):nth-child(-n+60):hover~.parent {
            --posY: 5;
        }
  
        .cell:nth-child(10n+7):hover~.parent {
            --posX: 6;
        }
  
        .cell:nth-child(n+61):nth-child(-n+70):hover~.parent {
            --posY: 6;
        }
  
        .cell:nth-child(10n+8):hover~.parent {
            --posX: 7;
        }
  
        .cell:nth-child(n+71):nth-child(-n+80):hover~.parent {
            --posY: 7;
        }
  
        .cell:nth-child(10n+9):hover~.parent {
            --posX: 8;
        }
  
        .cell:nth-child(n+81):nth-child(-n+90):hover~.parent {
            --posY: 8;
        }
  
        .cell:nth-child(10n+10):hover~.parent {
            --posX: 9;
        }
  
        .cell:nth-child(n+91):nth-child(-n+100):hover~.parent {
            --posY: 9;
        }
  
        .cell:nth-child(10n+11):hover~.parent {
            --posX: 10;
        }
  
        .cell:nth-child(n+101):nth-child(-n+110):hover~.parent {
            --posY: 10;
        }
  
        .parent {
            --posX: 0;
            --posY: 0;
  
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            display: flex;
            justify-content: center;
            align-items: center;
        }
  
        .circle {
            width: calc(100px + var(--posX) * 100px);
            height: calc(100px + var(--posY) * 100px);
            background: black;
            transition: all 0.4s;
            border-radius: 100%;
        }
    </style>
</head>
  
<body>
    <h1 style="color:green">GeeksforGeeks</h1>
    <h3>How to Map Mouse Position in CSS ?</h3>
  
    <div class="container">
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="parent">
            <div class="circle"></div>
        </div>
    </div>
</body>
  
</html>


Output :

 

Example 2: In this example, we will create a circle that changes its color with a change in mouse position using the above approach by referring to the –posX only. –posX contains color names that change with hover.

HTML




<!DOCTYPE html>
<html>
  
<head>
    <title>
        How to Map Mouse Position in CSS ?
    </title>
  
    <style>
        .container {
            height: 100vh;
            display: grid;
            grid-template: repeat(10, 1fr) / repeat(10, 1fr);
            position: absolute;
            width: 100%;
            height: 100vh;
            top: 0;
            left: 0;
        }
  
        .cell {
            width: 100%;
            height: 100%;
            border: 1px solid #9f9b9b5c;
            z-index: 2;
        }
  
        .cell:nth-child(10n+2):hover~.parent {
            --posX: red;
        }
  
        .cell:nth-child(10n+3):hover~.parent {
            --posX: blue;
        }
  
        .cell:nth-child(10n+4):hover~.parent {
            --posX: green;
        }
  
        .cell:nth-child(10n+5):hover~.parent {
            --posX: yellow;
        }
  
        .cell:nth-child(10n+6):hover~.parent {
            --posX: black;
        }
  
        .cell:nth-child(10n+7):hover~.parent {
            --posX: orange;
        }
  
        .cell:nth-child(10n+8):hover~.parent {
            --posX: pink;
        }
  
        .cell:nth-child(10n+9):hover~.parent {
            --posX: purple;
        }
  
        /*# sourceMappingURL=output.scss.map */
  
        .parent {
            --posX: black;
  
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            display: flex;
            justify-content: center;
            align-items: center;
        }
  
        .circle {
            width: 200px;
            height: 200px;
            background: var(--posX);
            transition: all 0.4s;
            border-radius: 100%;
        }
    </style>
  
<body>
    <h1 style="color:green">GeeksforGeeks</h1>
    <h3>How to Map Mouse Position in CSS ?</h3>
  
    <div class="container">
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
        <div class="cell"></div>
  
        <div class="parent">
            <div class="circle"></div>
        </div>
    </div>
</body>
  
</html>


Output :

 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads