Relatieve tijd in het Nederlands New
Time labels the way people say them: just now, 3 minutes ago, yesterday at 14:30, Monday at 09:15, in 35 minutes, and further back a short date. Every
Bestelling 20871
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.
<!-- Relatieve tijd in het Nederlands · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="drl">
<div class="drl__head">
<h3 class="drl__h">Bestelling 20871</h3>
<div class="drl__ctl">
<button type="button" class="drl__b" data-a="exact" aria-pressed="false">Exacte tijd</button>
<button type="button" class="drl__b" data-a="ff">Klok +10 min</button>
</div>
</div>
<ol class="drl__list"></ol>
</div>
</div>/* Relatieve tijd in het Nederlands · NedDev · eigen werk. */
.drl{--ink:#0a0a0a;--pop:#F5480F;--pd:#b83a0b;--mut:#5b5b5b;--line:rgba(10,10,10,.12);position:absolute;inset:0;overflow:auto;padding:12px 14px;font-family:'Switzer',system-ui,sans-serif;font-size:12.5px;line-height:1.35;color:var(--ink);background:#fff;scrollbar-width:thin;text-align:left}
.drl *,.drl *::before,.drl *::after{box-sizing:border-box}
.drl__head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:6px}
.drl__h{margin:0;font-size:14px;font-weight:600}
.drl__ctl{display:flex;gap:4px}
.drl__b{height:26px;padding:0 8px;border:1px solid rgba(10,10,10,.25);border-radius:4px;background:#fff;color:var(--ink);font:500 11.5px/1 'Switzer',system-ui,sans-serif;cursor:pointer;white-space:nowrap;transition:border-color .15s,background-color .15s}
.drl__b:hover{border-color:var(--ink)}
.drl__b[aria-pressed="true"]{background:var(--ink);color:#fff;border-color:var(--ink)}
.drl__b:focus-visible{outline:2px solid var(--pop);outline-offset:2px}
.drl__list{list-style:none;margin:0;padding:0}
.drl__it{display:flex;align-items:baseline;gap:10px;padding:6px 0;border-bottom:1px solid var(--line)}
.drl__it:last-child{border-bottom:0}
.drl__what{flex:1;min-width:0}
.drl__it.is-future .drl__what{color:var(--mut)}
.drl__it.is-future .drl__t{color:var(--pd);font-weight:600}
.drl__t{flex:0 1 auto;max-width:62%;font-size:12px;color:var(--mut);font-variant-numeric:tabular-nums;text-align:right;cursor:help;text-decoration:underline dotted rgba(10,10,10,.35);text-underline-offset:3px;transition:color .2s}
.drl__t.is-tick{color:var(--ink)}
@media (max-width:420px){.drl__head{flex-wrap:wrap}.drl__b{padding:0 6px}}
@media (prefers-reduced-motion:reduce){.drl *{transition:none!important}}// Relatieve tijd in het Nederlands · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
const w = root.querySelector('.drl'); if (!w) return;
const list = w.querySelector('.drl__list');
let offset = 0, exact = false;
const now = () => new Date(Date.now() + offset);
const rtf = new Intl.RelativeTimeFormat('nl', { numeric: 'auto' });
const fTime = new Intl.DateTimeFormat('nl-NL', { hour: '2-digit', minute: '2-digit' });
const fFull = new Intl.DateTimeFormat('nl-NL', { dateStyle: 'full', timeStyle: 'short' });
const fWd = new Intl.DateTimeFormat('nl-NL', { weekday: 'long' });
const fShort = new Intl.DateTimeFormat('nl-NL', { weekday: 'short', day: 'numeric', month: 'short' });
const fYear = new Intl.DateTimeFormat('nl-NL', { day: 'numeric', month: 'short', year: 'numeric' });
const startOfDay = d => { const x = new Date(d); x.setHours(0, 0, 0, 0); return x; };
// Kern: één functie, ook bruikbaar los van deze demo.
function relatief(d, ref) {
const s = Math.round((d - ref) / 1000), a = Math.abs(s);
if (a < 45) return s <= 0 ? 'zojuist' : 'zo meteen';
if (a < 3600) return rtf.format(Math.round(s / 60), 'minute');
const days = Math.round((startOfDay(d) - startOfDay(ref)) / 864e5);
if (days === 0) return a < 6 * 3600 ? rtf.format(Math.round(s / 3600), 'hour') : 'vandaag om ' + fTime.format(d);
if (days === -1 || days === 1) return rtf.format(days, 'day') + ' om ' + fTime.format(d);
if (days < 0 && days > -7) return fWd.format(d) + ' om ' + fTime.format(d);
if (d.getFullYear() === ref.getFullYear()) return fShort.format(d).replace(/\./g, '');
return fYear.format(d).replace(/\./g, '');
}
const base = Date.now();
const at = (min) => new Date(base + min * 60000);
const dayAt = (days, h, m) => { const d = new Date(base); d.setDate(d.getDate() + days); d.setHours(h, m, 0, 0); return d; };
const E = [
['Bezorger verwacht aan de deur', at(35), true],
['Bezorger is onderweg naar jou', new Date(base - 20000)],
['Pakket gescand in depot Nieuwegein', at(-3)],
['Overgedragen aan de bezorgdienst', at(-130)],
['Betaald met iDEAL', dayAt(-1, 14, 30)],
['Bestelling geplaatst', dayAt(-3, 9, 15)],
['Vorige bestelling 19422 bezorgd', dayAt(-38, 11, 0)],
['Klant sinds', new Date(2025, 0, 12, 10, 4)]
];
list.innerHTML = E.map((e, i) => '<li class="drl__it' + (e[2] ? ' is-future' : '') + '"><span class="drl__what">' + e[0] + '</span><time class="drl__t" data-i="' + i + '" datetime="' + e[1].toISOString() + '" title="' + fFull.format(e[1]) + '"></time></li>').join('');
const times = [...list.querySelectorAll('time')];
function tick(flash) {
const ref = now();
times.forEach(t => {
const d = E[+t.dataset.i][1];
const txt = exact ? fFull.format(d) : relatief(d, ref);
if (t.textContent !== txt) {
t.textContent = txt;
if (flash) { t.classList.add('is-tick'); setTimeout(() => t.classList.remove('is-tick'), 600); }
}
});
}
w.addEventListener('click', e => {
const b = e.target.closest('.drl__b'); if (!b) return;
if (b.dataset.a === 'exact') { exact = !exact; b.setAttribute('aria-pressed', String(exact)); tick(false); }
else { offset += 600000; tick(true); }
});
tick(false);
// Elke 15 seconden bijwerken; stil als het tabblad op de achtergrond staat.
let timer = setInterval(() => tick(true), 15000);
document.addEventListener('visibilitychange', () => { clearInterval(timer); if (!document.hidden) { tick(true); timer = setInterval(() => tick(true), 15000); } });
}
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 →