Woord dat overvloeit New
The last word of a heading melts into the next one through blur and an SVG threshold filter, so the letters seem to flow into each other. For a hero with several services; screen readers hear the full list in one sentence, with a pause button and no motion under reduced motion.
Wij bouwen uw nieuwe dakkapel, badkamer, keuken of uitbouw
Bouwbedrijf Visser, Zwolle. Vaste prijs vooraf, oplevering binnen zes weken.
How to use it
- Paste the HTML where the text animations should appear.
- Add the CSS to your stylesheet. All classes are prefixed, so nothing clashes with your own styles.
- Add the JavaScript and call init() with the element that contains the HTML.
<!-- Woord dat overvloeit · Bron: Magic UI (morphing-text) · licentie MIT. Laat deze vermelding staan bij hergebruik. -->
<div class="jouw-container">
<div class="wmo">
<svg class="wmo__defs" aria-hidden="true" focusable="false" width="0" height="0"><defs><filter id="wmo-drempel"><feColorMatrix in="SourceGraphic" type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 255 -140"/></filter></defs></svg>
<h3 class="wmo__h">Wij bouwen uw nieuwe <span class="wmo__sr">dakkapel, badkamer, keuken of uitbouw</span><span class="wmo__slot" aria-hidden="true"><span class="wmo__w wmo__w--a"></span><span class="wmo__w wmo__w--b">dakkapel</span></span></h3>
<div class="wmo__voet">
<p class="wmo__t">Bouwbedrijf Visser, Zwolle. Vaste prijs vooraf, oplevering binnen zes weken.</p>
<button class="wmo__knop" type="button" aria-pressed="false">Pauzeer</button>
</div>
</div>
</div>/* Woord dat overvloeit · Bron: Magic UI (morphing-text) · licentie MIT. Laat deze vermelding staan bij hergebruik. */
.wmo{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;gap:14px;padding:18px 22px;font-family:'Switzer',system-ui,sans-serif;color:#0a0a0a;background:#f4f3f1;text-align:left}
.wmo__defs{position:absolute;width:0;height:0;overflow:hidden}
.wmo__h{margin:0;font-weight:600;font-size:clamp(17px,4.6cqw,21px);line-height:1.2;letter-spacing:-.01em}
.wmo{container-type:inline-size}
.wmo__sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.wmo__slot{position:relative;display:block;height:1.05em;margin-top:4px;font-size:clamp(40px,13cqw,56px);font-weight:800;letter-spacing:-.035em;line-height:1;color:#F5480F;filter:url(#wmo-drempel)}
.wmo__w{position:absolute;left:0;top:0;white-space:nowrap;user-select:none}
.wmo__w--a{opacity:0}
.wmo__voet{display:flex;align-items:center;justify-content:space-between;gap:12px;border-top:1px solid rgba(10,10,10,.14);padding-top:10px}
.wmo__t{margin:0;font-size:12.5px;line-height:1.4;color:#4a4a4a;max-width:30ch}
.wmo__knop{flex:none;min-height:30px;padding:6px 10px;border:1px solid #0a0a0a;border-radius:4px;background:#fff;color:#0a0a0a;font:500 12.5px/1 'Switzer',system-ui,sans-serif;cursor:pointer}
.wmo__knop:hover{background:#0a0a0a;color:#fff}
.wmo__knop:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
@media (prefers-reduced-motion:reduce){.wmo__slot{filter:none}.wmo__knop{display:none}}// Woord dat overvloeit · Bron: Magic UI (morphing-text) · licentie MIT. Laat deze vermelding staan bij hergebruik.
// root = het element waarin de HTML staat
function init(root){
const w = root.querySelector('.wmo'); if (!w) return;
const a = w.querySelector('.wmo__w--a'), b = w.querySelector('.wmo__w--b'), knop = w.querySelector('.wmo__knop');
const woorden = ['dakkapel', 'badkamer', 'keuken', 'uitbouw'];
if (matchMedia('(prefers-reduced-motion: reduce)').matches) return;
const MORPH = 1.1, RUST = 2.4;
let i = 0, morph = 0, rust = RUST, vorige = performance.now(), gepauzeerd = false, zichtbaar = true, raf = 0;
const zet = f => {
b.style.filter = 'blur(' + Math.min(8 / f - 8, 100) + 'px)'; b.style.opacity = Math.pow(f, .4) * 100 + '%';
const r = 1 - f;
a.style.filter = 'blur(' + Math.min(8 / r - 8, 100) + 'px)'; a.style.opacity = Math.pow(r, .4) * 100 + '%';
a.textContent = woorden[i % woorden.length]; b.textContent = woorden[(i + 1) % woorden.length];
};
const stil = () => { morph = 0; b.style.filter = ''; b.style.opacity = '100%'; a.style.filter = ''; a.style.opacity = '0%'; };
const stap = nu => {
const dt = Math.min((nu - vorige) / 1000, .1); vorige = nu;
if (!gepauzeerd && zichtbaar) {
rust -= dt;
if (rust <= 0) {
morph -= rust; rust = 0; let f = morph / MORPH;
if (f >= 1) { rust = RUST; f = 1; }
zet(f); if (f === 1) i++;
} else stil();
}
raf = requestAnimationFrame(stap);
};
raf = requestAnimationFrame(stap);
if ('IntersectionObserver' in window) new IntersectionObserver(e => { zichtbaar = e[0].isIntersecting; }).observe(w);
knop.addEventListener('click', () => {
gepauzeerd = !gepauzeerd;
knop.setAttribute('aria-pressed', String(gepauzeerd));
knop.textContent = gepauzeerd ? 'Afspelen' : 'Pauzeer';
if (gepauzeerd) { const f = morph / MORPH; if (f > 0 && f < 1) { i++; } rust = RUST; stil(); }
});
}
init(document.querySelector('.jouw-container'));
More text animations
Seen something you like?
Add it to your selection and send it over. We build your site around it, in your brand.
Get in touch →