Skip to content

Full-Page Loader

Tailwind CSS full-page loader overlay with a spinning gradient ring, progress bar and status messages that fades out once the page has loaded.

Live preview

Open in new tab

Code

A full-page loader built with Tailwind CSS and a small vanilla JavaScript controller. A dark violet overlay with a spinning gradient ring, a progress bar and rotating status messages covers the page until it has finished loading, then fades away and hands focus to the main content. Use it for dashboards, single-page apps and any page that needs a moment before it is usable.

How it works

The root is .tpl-root. It holds the .tpl-overlay (marked data-tpl-overlay), a visually hidden live region marked data-tpl-status, and the page itself inside data-tpl-content. The overlay is fixed inset-0 z-50, so it sits above everything. Inside it are two .tpl-ring SVGs that rotate in opposite directions, the breathing .tpl-mark logo tile, a role="progressbar" track and the data-tpl-bar fill.

On DOMContentLoaded the script adds tpl-js to the root, marks the content aria-busy and inert, and starts a timer that eases the progress value toward 90% while cycling the texts in the MESSAGES array. When the page fires load and at least data-tpl-min-duration milliseconds have passed, the bar jumps to 100%, .tpl-overlay--done fades the overlay out, the content becomes interactive again and focus moves to the data-tpl-focus element. The Replay loader button (data-tpl-replay) runs the sequence again.

Without JavaScript the tpl-failsafe animation in style.css hides the overlay after 10 seconds, so the page is never locked behind it.

Customization

  • data-tpl-min-duration on .tpl-root: minimum time in milliseconds the loader stays visible; set 0 to hide it as soon as the page is ready.
  • data-tpl-wait="event" on .tpl-root: keep the loader until you call root.dispatchEvent(new CustomEvent('tpl:ready')), for example after your fetch() resolves.
  • --tpl-bg on .tpl-overlay in style.css: change the base color behind the two radial glows.
  • --tpl-fade on .tpl-overlay: make the fade-out faster or slower.
  • MESSAGES at the top of script.js: replace or translate the rotating status texts.
  • from-violet-400 to-fuchsia-400 on data-tpl-bar and the stops in #tpl-ring-gradient: swap them for your brand colors.
  • Replace the hexagon SVG inside .tpl-mark with your own logo.

Accessibility

The progress track uses role="progressbar" with aria-label, aria-valuemin, aria-valuemax and an aria-valuenow updated on every tick. The decorative rings and rotating text are aria-hidden; screen readers hear only "Loading page" and "Page loaded" from the polite role="status" region. While loading, the content is inert and aria-busy="true", so keyboard focus cannot reach hidden controls, and afterwards focus moves to the main element. Under prefers-reduced-motion: reduce the rings stop spinning and the transitions are removed.

Usage notes

Place the markup as the first element in body so the overlay is painted before the rest of the page. Use one loader per page; the gradient id inside the SVG must stay unique.

Requirements

Add these to your page (already included in the download):

  • <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>

The Tailwind browser build is for prototyping. In production, compile Tailwind with its CLI or your bundler.

Full-Page Loader – Tailwind CSS loaders & spinners component screenshot
Full-Page Loader · Tailwind CSS Loaders & Spinners

More Loaders & Spinners

CSS Spinner Collection – Pure CSS loaders & spinners preview

CSS Spinner Collection

Eight lightweight pure CSS loading spinners in a labelled grid, each with role="status" and screen reader text, no JavaScript.