Balken groeien op scroll (CSS animation-timeline) Nieuw
Een besparingsoverzicht waarin elke balk groeit terwijl de regel in beeld scrolt, volledig in CSS met animation-timeline: view() en animation-range; de kop krijgt een schaduw via scroll(nearest). Browsers zonder ondersteuning krijgen hetzelfde via een kleine IntersectionObserver, bij minder beweging staan de balken direct vol. Voor rekenvoorbeelden, vergelijkingen en jaarverslagen.
Wat levert verduurzamen op?
Tussenwoning uit 1965 in Breda, besparing per jaar
- Spouwmuurisolatie€ 480
- Zonnepanelen, 8 stuks€ 620
- Dakisolatie€ 390
- HR++ glas€ 260
- Vloerisolatie€ 210
- Kierdichting€ 95
Samen € 2.055 per jaar. Bedragen bij de energieprijs van oktober 2026.
Zo gebruik je het
- Plak de HTML op de plek waar het onderdeel moet komen.
- Zet de CSS in je stylesheet. Alle klassen hebben een eigen voorvoegsel, dus niets botst met je eigen opmaak.
- Voeg de JavaScript toe en roep init() aan met het element waar de HTML in staat.
<!-- Balken groeien op scroll (CSS animation-timeline) · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="stb">
<div class="stb__vp" tabindex="0" aria-label="Besparing per maatregel, scroll voor meer">
<div class="stb__kop"><h3 class="stb__t">Wat levert verduurzamen op?</h3><p class="stb__w">Tussenwoning uit 1965 in Breda, besparing per jaar</p></div>
<ul class="stb__lijst">
<li class="stb__r" style="--v:.77"><span class="stb__naam">Spouwmuurisolatie</span><span class="stb__bedrag">€ 480</span><span class="stb__balk"><i></i></span></li>
<li class="stb__r" style="--v:1"><span class="stb__naam">Zonnepanelen, 8 stuks</span><span class="stb__bedrag">€ 620</span><span class="stb__balk"><i></i></span></li>
<li class="stb__r" style="--v:.63"><span class="stb__naam">Dakisolatie</span><span class="stb__bedrag">€ 390</span><span class="stb__balk"><i></i></span></li>
<li class="stb__r" style="--v:.42"><span class="stb__naam">HR++ glas</span><span class="stb__bedrag">€ 260</span><span class="stb__balk"><i></i></span></li>
<li class="stb__r" style="--v:.34"><span class="stb__naam">Vloerisolatie</span><span class="stb__bedrag">€ 210</span><span class="stb__balk"><i></i></span></li>
<li class="stb__r" style="--v:.15"><span class="stb__naam">Kierdichting</span><span class="stb__bedrag">€ 95</span><span class="stb__balk"><i></i></span></li>
</ul>
<p class="stb__voet">Samen € 2.055 per jaar. Bedragen bij de energieprijs van oktober 2026.</p>
</div>
</div>
</div>/* Balken groeien op scroll (CSS animation-timeline) · NedDev · eigen werk. */
.stb{position:absolute;inset:0;padding:8px;font-family:'Switzer',system-ui,sans-serif;color:#0a0a0a;background:#f4f3f1;text-align:left}
.stb *{box-sizing:border-box}
.stb__vp{width:100%;height:100%;overflow-y:auto;overscroll-behavior:contain;background:#fff;border:1px solid rgba(10,10,10,.14);border-radius:8px;scrollbar-width:thin;scrollbar-color:#0a0a0a transparent}
.stb__vp:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.stb__kop{position:sticky;top:0;z-index:1;padding:10px 14px 8px;background:#fff;border-bottom:1px solid transparent}
.stb__t{margin:0;font-size:15px;font-weight:700;letter-spacing:-.01em}
.stb__w{margin:2px 0 0;font-size:12px;color:#4a4a4a}
.stb__lijst{list-style:none;margin:0;padding:4px 14px 0}
.stb__r{display:grid;grid-template-columns:1fr auto;gap:3px 10px;padding:9px 0}
.stb__naam{font-size:13px;font-weight:500}
.stb__bedrag{font-size:13px;font-weight:700;font-variant-numeric:tabular-nums}
.stb__balk{grid-column:1/-1;height:8px;background:#efedea;border-radius:4px;overflow:hidden}
.stb__balk i{display:block;height:100%;width:calc(var(--v) * 100%);background:#F5480F;border-radius:4px;transform-origin:0 50%}
.stb__voet{margin:6px 14px 14px;font-size:12px;line-height:1.4;color:#4a4a4a}
@supports (animation-timeline:view()){
.stb__balk i{animation:stbGroei linear both;animation-timeline:view();animation-range:entry 10% cover 42%}
.stb__bedrag{animation:stbToon linear both;animation-timeline:view();animation-range:entry 10% cover 42%}
.stb__kop{animation:stbSchaduw linear both;animation-timeline:scroll(nearest);animation-range:0 40px}
}
@keyframes stbGroei{from{transform:scaleX(0)}}
@keyframes stbToon{from{opacity:.25}}
@keyframes stbSchaduw{to{border-bottom-color:rgba(10,10,10,.14);box-shadow:0 8px 12px -10px rgba(10,10,10,.4)}}
.stb.is-terugval .stb__balk i{transform:scaleX(0);transition:transform .8s cubic-bezier(.2,.7,.2,1)}
.stb.is-terugval .stb__r.is-in .stb__balk i{transform:none}
.stb.is-terugval .stb__kop.is-schaduw{border-bottom-color:rgba(10,10,10,.14);box-shadow:0 8px 12px -10px rgba(10,10,10,.4)}
@media (prefers-reduced-motion:reduce){.stb__balk i,.stb__bedrag,.stb.is-terugval .stb__balk i{animation:none!important;transform:none!important;opacity:1;transition:none}}// Balken groeien op scroll (CSS animation-timeline) · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w = root.querySelector('.stb');
if (window.CSS && CSS.supports && CSS.supports('animation-timeline', 'view()')) return;
if (matchMedia('(prefers-reduced-motion: reduce)').matches || !('IntersectionObserver' in window)) return;
var vp = w.querySelector('.stb__vp'), kop = w.querySelector('.stb__kop');
w.classList.add('is-terugval');
var io = new IntersectionObserver(function (es) { es.forEach(function (e) { if (e.isIntersecting) { e.target.classList.add('is-in'); io.unobserve(e.target); } }); }, { root: vp, threshold: .6 });
[].forEach.call(w.querySelectorAll('.stb__r'), function (r) { io.observe(r); });
vp.addEventListener('scroll', function () { kop.classList.toggle('is-schaduw', vp.scrollTop > 4); }, { passive: true });
}
init(document.querySelector('.jouw-container'));
Meer uit scroll-effecten
Iets gezien dat je mooi vindt?
Zet het in je selectie en stuur hem op. Dan bouwen we je site eromheen, in jouw huisstijl.
Neem contact op →