I help bloggers, podcasters, makers, coaches grow their audience
How to make your words rotate ✨
- Type your headline with all your rotating words in a row, separated by commas. Like this: I help bloggers, podcasters, makers grow their audience
- Highlight just the word list (bloggers, podcasters, makers) and click the Highlight button in the toolbar.
- That’s it! Style the highlight however you like (color, italic, background) and your words will take turns stealing the spotlight.
Quick tips:
- Keep punctuation like periods outside the highlight.
- Two words minimum, but go wild with as many as you want.
- The magic happens on the live page, so preview it to see your words spin.
Place the below code in your header script area this delete this block.
<script>/* Rotating words headline */
(function () {
var HOLD = 2200; // ms each word stays on screen
var SPEED = 600; // ms the roll takes (keep in sync with the 0.6s in the CSS)
var rotators = [];
var timer = null;
var reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
function setup(mark) {
if (mark.dataset.ccRotate) return null;
mark.dataset.ccRotate = '1';
var words = mark.textContent.split(',').map(function (w) {
return w.trim();
}).filter(Boolean);
if (words.length < 2) {
mark.classList.add('cc-rotate-ready');
return null;
}
mark.textContent = '';
var sr = document.createElement('span');
sr.className = 'cc-rotate-sr';
sr.textContent = words.join(', ');
mark.appendChild(sr);
var stack = document.createElement('span');
stack.className = 'cc-rotate-stack';
stack.setAttribute('aria-hidden', 'true');
// add the first word again at the end so the loop wraps around seamlessly
words.concat(words[0]).forEach(function (w) {
var item = document.createElement('span');
item.className = 'cc-rotate-word';
item.textContent = w;
stack.appendChild(item);
});
mark.appendChild(stack);
mark.classList.add('cc-rotate-ready');
stack.style.willChange = 'transform';
return { mark: mark, stack: stack, items: stack.children, n: words.length, i: 0, lineH: 0, widths: [] };
}
// Measure word heights and widths (re-run once custom fonts finish loading)
function measure(r) {
r.lineH = r.items[0].offsetHeight;
r.mark.style.height = r.lineH + 'px';
r.widths = Array.prototype.map.call(r.items, function (el) {
return el.offsetWidth;
});
r.mark.style.width = r.widths[r.i] + 'px';
r.stack.style.transform = 'translateY(' + -r.i * r.lineH + 'px)';
}
function step(r) {
r.i++;
r.stack.style.transition = '';
r.stack.style.transform = 'translateY(' + -r.i * r.lineH + 'px)';
r.mark.style.width = r.widths[r.i] + 'px';
// on the copy of the first word, quietly jump back to the real first word
if (r.i === r.n) {
setTimeout(function () {
r.stack.style.transition = 'none';
r.i = 0;
r.stack.style.transform = 'translateY(0px)';
void r.stack.offsetHeight; // lock in the jump before turning the transition back on
r.stack.style.transition = '';
}, SPEED + 30);
}
}
function measureAll() {
rotators.forEach(measure);
}
function start() {
if (reduce || timer) return; // reduced motion: keep the first word, no rotating
timer = setInterval(function () {
rotators.forEach(step);
}, HOLD + SPEED);
}
function stop() {
clearInterval(timer);
timer = null;
}
function init() {
document.querySelectorAll('.cc-rotate .kt-highlight').forEach(function (mark) {
var r = setup(mark);
if (r) rotators.push(r);
});
if (!rotators.length) return;
measureAll();
if (document.fonts && document.fonts.ready) document.fonts.ready.then(measureAll);
window.addEventListener('load', measureAll);
window.addEventListener('resize', measureAll);
// pause while the browser tab is hidden so it doesn't jump when you come back
document.addEventListener('visibilitychange', function () {
document.hidden ? stop() : start();
});
start();
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();</script>