Parallax Layers

3D & Depth · Static · pure CSS

Two shaded copies trail the cursor at increasing rates behind the face, so deeper layers slide further — stacked 3D depth that follows the pointer.

Parallax Layers

How it works

Parallax Layers is a static 3d & depth text effect rendered entirely in CSS. A data-text attribute mirrors the word into ::before/::after layers, so copy that attribute together with the CSS. It reacts to the pointer through CSS custom properties updated by a tiny inline script.

Controls

Parallax Layers exposes 2 dedicated controls — Hue and Depth — on top of the shared type controls (font, weight, letter-spacing and case). Open it in the generator to tune every value live, then copy the updated CSS.

CSS

/* Parallax Layers — generated with TEXT-FX
 * HTML: the element needs a data-text attribute equal to its text; needs the small pointer-move JS snippet.
 * Font: 'Anton', sans-serif (load from Google Fonts).
 */

.text-effect {
  font-family: 'Anton', sans-serif;
  font-weight: 900;
  letter-spacing: 4px;
  text-transform: none;
}

.text-effect {
  --mx: 30%;
  --my: 26%;
  position: relative;
  isolation: isolate;
  color: hsl(61 80% 78%);
}
.text-effect::before {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  color: hsl(61 60% 50%);
  z-index: -1;
  transform: translate(calc((var(--mx) - 50%) * -0.29), calc((var(--my) - 50%) * -0.29));
  transition: transform 0.12s ease-out;
  pointer-events: none;
}
.text-effect::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  color: hsl(61 45% 32%);
  z-index: -2;
  transform: translate(calc((var(--mx) - 50%) * -0.58), calc((var(--my) - 50%) * -0.58));
  transition: transform 0.12s ease-out;
  pointer-events: none;
}

HTML

This effect needs the markup below (per-letter spans, SVG defs, or a data-text attribute).

<style>
.text-effect {
  font-family: 'Anton', sans-serif;
  font-weight: 900;
  letter-spacing: 4px;
  text-transform: none;
}

.text-effect {
  --mx: 30%;
  --my: 26%;
  position: relative;
  isolation: isolate;
  color: hsl(61 80% 78%);
}
.text-effect::before {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  color: hsl(61 60% 50%);
  z-index: -1;
  transform: translate(calc((var(--mx) - 50%) * -0.29), calc((var(--my) - 50%) * -0.29));
  transition: transform 0.12s ease-out;
  pointer-events: none;
}
.text-effect::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  color: hsl(61 45% 32%);
  z-index: -2;
  transform: translate(calc((var(--mx) - 50%) * -0.58), calc((var(--my) - 50%) * -0.58));
  transition: transform 0.12s ease-out;
  pointer-events: none;
}
</style>

<div data-text="Your text" class="text-effect">Your text</div>

<script>
const fx = document.querySelector('.text-effect');
if (fx) {
  fx.addEventListener('pointermove', (e) => {
    const r = fx.getBoundingClientRect();
    if (!r.width || !r.height) return;
    fx.style.setProperty('--mx', ((e.clientX - r.left) / r.width) * 100 + '%');
    fx.style.setProperty('--my', ((e.clientY - r.top) / r.height) * 100 + '%');
  });
  fx.addEventListener('pointerleave', () => {
    fx.style.removeProperty('--mx');
    fx.style.removeProperty('--my');
  });
}
</script>
Category
3D & Depth
Type
Static
Browser support
Stacked data-text copies translating at different pointer-driven rates.
Capabilities
dataText, pointer

Related 3D & Depth effects