Loader: Bar + Percentage
An accessible, themable progress bar that eases from 0→100% (Flash vibes, modern stack).
0%
Use this on your site (self-host)
- Copy these to
/assets/preloaders/
on your site:loader-bar.css
andloader-bar.js
. - Add the HTML snippet where you want the loader to appear.
- Optional: tweak size/speed/colors with CSS variables on
.rc-bar
.
HTML snippet
HTML
<link rel="stylesheet" href="/assets/preloaders/loader-bar.css">
<div class="rc-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-live="polite"
style="--bar-w:320px;--bar-h:14px;--speed:2200ms;--accent:#ff6bd6;--accent2:#5ef1ff;--accent3:#ffe66b">
<div class="rc-fill"></div>
</div>
<div class="rc-pct">0%</div>
<script src="/assets/preloaders/loader-bar.js" defer></script>
/assets/preloaders/loader-bar.css
CSS
/* RetroCrave Loader — Bar */
:root{ --accent:#ff6bd6; --accent2:#5ef1ff; --accent3:#ffe66b }
.rc-bar{ width:var(--bar-w,320px); height:var(--bar-h,14px); border-radius:999px; position:relative;
background:rgba(255,255,255,.10); border:1px solid rgba(255,255,255,.18); overflow:hidden }
.rc-fill{ position:absolute; inset:0 auto 0 0; width:0%;
background:linear-gradient(90deg, var(--accent), var(--accent2) 60%, var(--accent3));
box-shadow:0 0 18px rgba(255,107,214,.35); border-right:1px solid rgba(0,0,0,.25) }
.rc-pct{ font-variant-numeric:tabular-nums; color:#b7b9d4; font-weight:700; margin-top:.6rem }
@media (prefers-reduced-motion: reduce){ .rc-fill{ transition:none !important } }
/assets/preloaders/loader-bar.js
JS
(function(){
var bars = document.querySelectorAll('.rc-bar');
if(!bars.length) return;
var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
bars.forEach(function(root){
var fill = root.querySelector('.rc-fill');
var pctEl = root.nextElementSibling && root.nextElementSibling.classList.contains('rc-pct') ? root.nextElementSibling : null;
var speed = parseInt(getComputedStyle(root).getPropertyValue('--speed')) || 2000;
if(reduce){ if(fill) fill.style.width='100%'; if(pctEl) pctEl.textContent='100%'; root.setAttribute('aria-valuenow','100'); return; }
var start = performance.now();
function tick(now){
var t = Math.min(1, (now - start) / speed);
t = 1 - Math.pow(1 - t, 3); // easeOutCubic
var percent = Math.round(t * 100);
if(fill) fill.style.width = percent + '%';
if(pctEl) pctEl.textContent = percent + '%';
root.setAttribute('aria-valuenow', String(percent));
if (percent < 100) requestAnimationFrame(tick);
}
requestAnimationFrame(tick);
});
})();