<div class="text-container">
<svg class="svg-clip">
<defs>
<clipPath id="text-clip"></clipPath>
</defs>
</svg>
<h1 class="text-header">
<div class="text-header__content text-header__content--orig">TEXT</div>
<div class="text-header__content text-header__content--copy" aria-hidden="true">TEXT</div>
</h1>
</div>
<section class="bg">
</section>
<section class="no-bg">
</section>
<section class="bg">
</section>
<section class="no-bg">
</section>
body,
html {
margin: 0;
padding: 0;
}
section {
width: 100vw;
height: 100vh;
background: #fff;
}
.bg {
background: #000 url("https://source.unsplash.com/featured?milkyway")
no-repeat;
background-size: cover;
}
.text-container {
position: fixed;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.svg-clip {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
}
.text-header {
position: relative;
font-size: 150px;
z-index: 0;
}
.text-header__content {
&--orig {
background: linear-gradient(90deg, #8500ff, #ff8100);
background-clip: text;
text-fill-color: transparent;
clip-path: url('#text-clip');
}
&--copy {
position: absolute;
top: 0;
left: 0;
color: #fff;
z-index: -1;
}
}
View Compiled
const clipedText = document.querySelector(".text-header__content--orig");
const clipPath = document.querySelector("#text-clip");
const sections = document.querySelectorAll(".no-bg");
let textRect = null;
function getPageBoundRect(el, sx = 0, sy = 0) {
const r = el.getBoundingClientRect();
return {
x: r.x + sx,
y: r.y + sy,
w: r.width,
h: r.height,
};
}
const xmlns = "http://www.w3.org/2000/svg";
const clipRects = Array.from(sections, (sect) => ({
clipRectEl: document.createElementNS(xmlns, "rect"),
sectionRect: null,
section: sect
}));
clipRects.forEach((r) => clipPath.appendChild(r.clipRectEl));
function resizeClips() {
textRect = clipedText.getBoundingClientRect();
const dx = -textRect.x - window.scrollX;
const dy = -textRect.y - window.scrollY;
clipRects.forEach((r) => {
r.sectionRect = getPageBoundRect(r.section, window.scrollX, window.scrollY);
r.clipRectEl.setAttribute("x", r.sectionRect.x + dx);
r.clipRectEl.setAttribute("y", r.sectionRect.y + dy);
r.clipRectEl.setAttribute("width", r.sectionRect.w);
r.clipRectEl.setAttribute("height", r.sectionRect.h);
});
}
resizeClips();
window.addEventListener("resize", resizeClips);
window.addEventListener("scroll", e => {
const dx = -textRect.x - window.scrollX;
const dy = -textRect.y - window.scrollY;
clipRects.forEach(r => {
r.clipRectEl.setAttribute("x", r.sectionRect.x + dx);
r.clipRectEl.setAttribute("y", r.sectionRect.y + dy);
})
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.