https://jsfiddle.net/jessuni/bjer0fn1/2/#

by jessuni

HTML

<div class="parallax">
  parallax
  <div class="parallax-group">
    <h2>hello world</h2>
    <span value="-15"></span>
    <span value="5"></span>
    <span value="30"></span>
    <span value="-5"></span>
    <span value="15"></span>
  </div>
</div>

CSS

body {
  padding: 0;
  margin: 0;
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.parallax {
  margin: 0;
  height: 100vh;
  background-color: #bd1060;
  overflow: hidden;
}
.parallax-group {
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
}
.parallax-group h2 {
  position: relative;
  font-size: 100px;
  color: white;
  z-index: 2;
  text-align: center;
}
.parallax-group span {
  position: absolute;
  height: 20px;
  width: 20px;
  border-radius: 100%;
}
.parallax-group span:nth-child(1) {
  top: 70%;
  left: 70%;
  background: blue;
  z-index: 3;
}
.parallax-group span:nth-child(2) {
  top: 60%;
  left: 80%;
  background: yellow;
  content: '5';
  z-index: 3;
}
.parallax-group span:nth-child(3) {
  top: 40%;
  left: 60%;
  background: green;
  z-index: 3;
}
.parallax-group span:nth-child(4) {
  top: 70%;
  left: 40%;
  background: red;
  z-index: 3;
}
.parallax-group span:nth-child(5) {
  top: 40%;
  left: 30%;
  background: purple;
  z-index: 3;
}

JavaScript

document.addEventListener("mousemove", parallax);
function parallax(event) {
  this.querySelectorAll(".parallax-group span").forEach((shift) => {
    const position = shift.getAttribute("value");
    const x = (window.innerWidth - event.pageX * position) / 90;
    const y = (window.innerHeight - event.pageY * position) / 90;

    shift.style.transform = `translateX(${x}px) translateY(${y}px)`;
  });
}