Summarize this article with:

Nobody likes staring at a blank screen. When content takes time to load, users need visual feedback that something is happening.

That’s where CSS loaders come in.

These lightweight loading animations run purely on stylesheets, no JavaScript required. They keep visitors engaged during data fetches, form submissions, and page transitions.

This collection features working CSS loaders examples you can copy directly into your projects. Spinners, progress bars, skeleton screens, dot animations, and pulse effects.

Each example includes complete code, implementation tips, and guidance on animation timing, centering techniques, and accessibility best practices.

What is a CSS Loader

A CSS loader is a visual animation that displays while content loads on a webpage.

It tells users something is happening. Data fetching, image processing, page transitions.

These loading animations use CSS keyframes, transforms, and transitions to create movement without JavaScript dependencies.

Pure CSS spinners run lighter than script-based alternatives. They don’t block the main thread.

You’ll find them on landing pages, form submissions, Ajax requests, and anywhere async operations occur.

CSS Loaders Examples To Check Out

CSS Loader Generator

A powerful CSS Loader Generator for creating custom loading animations with zero hassle.

Where is web design headed next?

Discover the latest web design statistics: industry growth, design trends, technology adoption, and insights defining the future of the web.

Explore the Data →

This interactive generator lets you:

  • Create 12 different loader styles from spinners to pulsing hearts
  • Customize dimensions from 20px to 100px
  • Adjust animation speed between 0.5x and 2x
  • Pick any color to match your design

Neumorphism Gradient Vibes

See the Pen
Neumorphism Gradient Loader
by samuel garcia (@sam_garcia2)
on CodePen.

The CSS Animation Show

See the Pen
CSS Animated Loader
by Christofer Vilander (@c_vilander)
on CodePen.

SVG Sassiness

See the Pen
SVG ∞ loader (no JS, cross-browser, minimal code)
by Ana Tudor (@thebabydino)
on CodePen.

Morning Brew Time

See the Pen
cup of coffee loader
by Elena Nazarova (@nazarelen)
on CodePen.

Spiral Serenity

See the Pen
Spiral Loading
by alphardex (@alphardex)
on CodePen.

Daily Dose of Beauty

See the Pen
Daily UI #20 | CSS loader
by Håvard Brynjulfsen (@havardob)
on CodePen.

Get Your Game On

See the Pen
Battlenet Loader
by Stix (@stix)
on CodePen.

Android Sleekness

See the Pen
Android 4.4 Kitkat Loading Screen
by Simon Clavey (@simoncla)
on CodePen.

Spinning Stories

See the Pen
Loader
by Alex Rutherford (@Ruddy)
on CodePen.

Liquid Dreams

See the Pen
Liquid loader
by Mikael Ainalem (@ainalem)
on CodePen.

Starry Corporate Nights

See the Pen
Nutanix Loading Screen
by Ken Chen (@kenchen)
on CodePen.

Burrito Magic

See the Pen
Magic Burrito
by Cody Ogden (@codyogden)
on CodePen.

Chroma Spin

See the Pen
Chrome Cast Loader
by Robin Brons (@bronsrobin)
on CodePen.

Cube World

See the Pen
CSS Loader
by Glen Cheney (@Vestride)
on CodePen.

HexaVibes All Around

See the Pen
Hexagon Loading With CSS (2)
by Osama Belal (@osama-belal)
on CodePen.

Stairway to Trust

See the Pen
CSS Stairs Loader
by Irko Palenius (@ispal)
on CodePen.

Redirect with a Twist

See the Pen
Redirecting Loader
by Mr Alien (@mr_alien)
on CodePen.

For the Quirkmasters

See the Pen
Weird Loader
by Sikriti Dakua (@dev_loop)
on CodePen.

Cube Roller Alert

See the Pen
Loader css3
by Mathieu Richard (@MathieuRichard)
on CodePen.

Gearing Up

See the Pen
Cog loading animation
by Jamie Coulter (@jcoulterdesign)
on CodePen.

Swing and Sway

See the Pen
Swing Masking Loader
by Nikhil Krishnan (@nikhil8krishnan)
on CodePen.

Flipping Pancakes, Literally

See the Pen
‘Making pancake’ loader
by Pawel (@pawelqcm)
on CodePen.

Bubbling Donut

See the Pen
Pure CSS bubbles float in 🍩 loader animation
by Ana Tudor (@thebabydino)
on CodePen.

Poppin’ Bubbles

See the Pen
Bubble Gum Loader
by ilithya (@ilithya)
on CodePen.

A Fancy Spin Party

See the Pen
Fancy CSS loaders / spinners
by Jenning (@jenning)
on CodePen.

Cyclone of Simplicity

See the Pen
CSS3 Loaders
by Siddharth Parmar (@Siddharth11)
on CodePen.

Dash to Load

See the Pen
CSS Dash Loader
by Cassidy (@cassidoo)
on CodePen.

Chill Float Vibes

See the Pen
Floating Loading Animation
by Mario Duarte (@MarioDesigns)
on CodePen.

Hashtag Breakup

See the Pen
Single element Slack loader
by CrocoDillon (@CrocoDillon)
on CodePen.

That Glow Though

See the Pen
The Glowing Loader – Pure CSS Animation
by Maxime Rossignol (@Maxoor)
on CodePen.

Spin to Win

See the Pen
Vivid CSS3 Spinner
by Kevin Jannis (@kevinjannis)
on CodePen.

Old School Loading

See the Pen
Awesome loading screen using only HTML & CSS
by Ahmad Emran (@ahmadbassamemran)
on CodePen.

Legos for Days

See the Pen
LEGO Loader
by Chris Gannon (@chrisgannon)
on CodePen.

Outer Space Feels

See the Pen
Pure CSS Planet Loader Animation #cpc-planets
by Rafaela Lucas (@rafaelavlucas)
on CodePen.

The Must-Have

See the Pen
Escalade Loader
by Yoav Kadosh (@ykadosh)
on CodePen.

Ride the Wave

See the Pen
#4
by Sasha (@sashatran)
on CodePen.

Taste the Rainbow

See the Pen
Single Element Rainbow Pen Loader
by Dario Corsi (@dariocorsi)
on CodePen.

It’s Gooey

See the Pen
gooey css loader
by Shrikanth (@megatroncoder)
on CodePen.

Borderline Genius

See the Pen
CSS loader with borders
by Jesgrapa (@JesGraPa)
on CodePen.

Arrows Making Waves

See the Pen
Untitled
by Jules Forrest (@julesforrest)
on CodePen.

Bacon All the Way

See the Pen
Bacon Loader
by Chris Gannon (@chrisgannon)
on CodePen.

Slide Into The Future

How Does a CSS Loader Work

Every loading animation CSS effect relies on three core mechanisms.

Keyframe Animations

The @keyframes rule defines animation states. You set a start point, end point, and everything between.

The browser interpolates the values automatically.

Transform Functions

Rotate, scale, translate. These properties handle the actual movement.

Transform rotate spins elements around a center point. Scale grows or shrinks them. Translate shifts position.

Animation Properties

Six properties control playback:

  • animation-duration sets how long one cycle takes
  • animation-timing-function controls speed curves (linear, ease, cubic-bezier)
  • animation-iteration-count determines repeat behavior (infinite for loaders)
  • animation-delay staggers multiple elements
  • animation-direction reverses playback
  • animation-fill-mode defines styles before/after execution

Combine these with border-radius for circles, opacity for fades, and box-shadow for pulse effects.

Types of CSS Loaders

Different loading states call for different visual approaches.

Spinner Loaders

The classic. A circle with a colored segment that rotates continuously.

Uses border properties with one transparent side and transform rotate animation. Most recognizable loading indicator on the web.

Progress Bar Loaders

Horizontal bars that fill from left to right. Two types exist.

Determinate bars show actual progress percentage. Indeterminate bars loop continuously when completion time is unknown.

Check out CSS progress bar examples for implementation patterns.

Skeleton Loaders

Skeleton screens show placeholder shapes matching incoming content layout.

Gray boxes pulse where text, images, and cards will appear. Reduces perceived wait time significantly.

Dot Loaders

Three or more dots with staggered bounce animation or opacity changes.

Animation-delay creates the wave effect. Simple to build, universally understood.

Pulse Loaders

Elements that grow and fade rhythmically using scale transform and opacity.

Often circles or rings. The box-shadow property adds glow effects during expansion.

Best CSS Loader Examples

Working code you can copy. Each example covers different techniques and use cases.

Simple Circle Spinner

.spinner { width: 40px; height: 40px; border: 4px solid #f3f3f3; border-top: 4px solid #3498db; border-radius: 50%; animation: spin 1s linear infinite; }

@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } `

Border-radius creates the circle. One colored border segment produces the spinner effect.

Dual Ring Loader

` .dual-ring { width: 48px; height: 48px; border: 5px solid transparent; border-top-color: #3498db; border-bottom-color: #3498db; border-radius: 50%; animation: spin 1.2s linear infinite; } `

Two opposing colored segments. Feels more balanced than single-segment spinners.

Three Dot Bounce

` .dot-container { display: flex; gap: 8px; }

.dot { width: 12px; height: 12px; background: #3498db; border-radius: 50%; animation: bounce 0.6s ease-in-out infinite; }

.dot:nth-child(2) { animation-delay: 0.1s; } .dot:nth-child(3) { animation-delay: 0.2s; }

@keyframes bounce { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-15px); } } `

Staggered delays create the wave. Adjust timing for faster or slower rhythms.

Pulse Ring

` .pulse { width: 40px; height: 40px; border: 3px solid #3498db; border-radius: 50%; animation: pulse-ring 1.5s ease-out infinite; }

@keyframes pulse-ring { 0% { transform: scale(0.5); opacity: 1; } 100% { transform: scale(1.5); opacity: 0; } } `

Scale and opacity together. Starts small and visible, expands while fading.

Gradient Spinner

` .gradient-spinner { width: 50px; height: 50px; border-radius: 50%; background: conic-gradient(from 0deg, transparent, #3498db); animation: spin 1s linear infinite; }

.gradient-spinner::before { content: ”; position: absolute; inset: 4px; background: white; border-radius: 50%; } `

Conic gradient creates smooth color transition. Inner circle masks the center.

Use the CSS Gradient Generator for custom color combinations.

Square Flip Loader

` .flip-square { width: 30px; height: 30px; background: #3498db; animation: flip 1.2s ease-in-out infinite; }

@keyframes flip { 0% { transform: perspective(120px) rotateX(0) rotateY(0); } 50% { transform: perspective(120px) rotateX(-180deg) rotateY(0); } 100% { transform: perspective(120px) rotateX(-180deg) rotateY(-180deg); } } `

D transforms with CSS perspective. Creates depth during rotation.

Bar Wave Loader

` .bar-container { display: flex; gap: 4px; align-items: center; height: 40px; }

.bar { width: 6px; background: #3498db; animation: wave 1s ease-in-out infinite; }

.bar:nth-child(1) { animation-delay: 0s; } .bar:nth-child(2) { animation-delay: 0.1s; } .bar:nth-child(3) { animation-delay: 0.2s; } .bar:nth-child(4) { animation-delay: 0.3s; } .bar:nth-child(5) { animation-delay: 0.4s; }

@keyframes wave { 0%, 100% { height: 10px; } 50% { height: 40px; } } `

Audio visualizer style. Height animation with staggered timing.

Rotating Squares

` .rotating-squares { width: 40px; height: 40px; position: relative; }

.rotating-squares::before, .rotating-squares::after { content: ”; position: absolute; width: 20px; height: 20px; background: #3498db; animation: rotate-squares 1.8s ease-in-out infinite; }

.rotating-squares::after { animation-delay: -0.9s; }

@keyframes rotate-squares { 0%, 100% { transform: rotate(0) scale(1); } 50% { transform: rotate(180deg) scale(0.5); } } `

Two pseudo-elements with offset timing. Creates interlocking rotation pattern.

How to Create a CSS Spinner Loader

Step-by-step breakdown of the most common loader type.

Step One: HTML Structure

` <div class="loader"></div> `

Single element. No nested markup needed for basic spinners.

Step Two: Base Styles

` .loader { width: 48px; height: 48px; border: 5px solid #e0e0e0; border-radius: 50%; } `

Creates a gray circle. Border-radius at 50% turns the square into a perfect circle.

Step Three: Accent Border

` .loader { border-top-color: #3498db; } `

Override one side with your brand color. This segment becomes the visible spinner.

Step Four: Animation

` .loader { animation: spin 1s linear infinite; }

@keyframes spin { to { transform: rotate(360deg); } } `

Linear timing keeps speed constant. Infinite loop runs until you hide the element.

Complete Code

` .loader { width: 48px; height: 48px; border: 5px solid #e0e0e0; border-top-color: #3498db; border-radius: 50%; animation: spin 1s linear infinite; }

@keyframes spin { to { transform: rotate(360deg); } } `

Eight lines total. Lightweight, performant, cross-browser compatible.

For more variations, try the CSS Loader Generator tool.

How to Create a CSS Progress Bar Loader

Two approaches exist: determinate (shows actual percentage) and indeterminate (loops continuously).

Indeterminate Progress Bar

` .progress-bar { width: 200px; height: 4px; background: #e0e0e0; border-radius: 2px; overflow: hidden; }

.progress-bar::before { content: ”; display: block; width: 50%; height: 100%; background: #3498db; animation: progress 1.5s ease-in-out infinite; }

@keyframes progress { 0% { transform: translateX(-100%); } 100% { transform: translateX(300%); } } `

The pseudo-element slides across repeatedly. Overflow hidden clips it at container edges.

Determinate Progress Bar

` .progress-container { width: 200px; height: 8px; background: #e0e0e0; border-radius: 4px; }

.progress-fill { height: 100%; background: #3498db; border-radius: 4px; width: 0%; transition: width 0.3s ease; } `

Update width via JavaScript as operations complete. Transition smooths the visual change.

How to Create a CSS Skeleton Loader

Placeholder content that mimics final layout structure.

Basic Skeleton Element

` .skeleton { background: linear-gradient( deg, #e0e0e0 25%, #f0f0f0 50%, #e0e0e0 75% ); background-size: 200% 100%; animation: shimmer 1.5s infinite; border-radius: 4px; }

@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } } `

Gradient animation creates the shimmer effect. Apply to any element needing a placeholder.

Skeleton Card Layout

` .skeleton-card { padding: 16px; background: white; border-radius: 8px; }

.skeleton-avatar { width: 48px; height: 48px; border-radius: 50%; }

.skeleton-title { height: 20px; width: 60%; margin: 12px 0 8px; }

.skeleton-text { height: 14px; width: 100%; margin-bottom: 8px; }

.skeleton-text:last-child { width: 80%; } `

Match dimensions to your actual content. Users perceive faster load times when layout stays stable.

CSS Loader Animation Properties

Fine-tuning these values separates amateur loaders from polished ones.

Animation Duration

Sweet spot sits between 0.8s and 1.5s for most loaders.

Too fast feels frantic. Too slow suggests system lag. Spinners work best at 1s; pulse effects at 1.5s.

Animation Timing Function

Linear keeps constant speed, ideal for rotating spinners.

Ease-in-out creates natural acceleration and deceleration for bouncing dots.

Cubic-bezier allows custom curves. Try cubic-bezier(0.68, -0.55, 0.265, 1.55) for elastic bounce.

Animation Delay

Staggers multi-element animations. Calculate intervals by dividing total duration by element count.

Five dots at 1s total: delays of 0s, 0.2s, 0.4s, 0.6s, 0.8s.

How to Center a CSS Loader

Three reliable methods depending on your layout context.

Flexbox Method

` .loader-container { display: flex; justify-content: center; align-items: center; height: 100vh; } `

Works on any container. Set height to available space.

Grid Method

` .loader-container { display: grid; place-items: center; height: 100vh; } `

Single property centers both axes. Cleaner than flexbox for this specific task.

Absolute Positioning

` .loader { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } `

Centers relative to positioned parent. Use when flex or grid isn’t available.

How to Add a CSS Loader to a Website

Implementation patterns for common scenarios.

Page Load Overlay

` <div class="page-loader"> <div class="spinner"></div> </div> `

` .page-loader { position: fixed; inset: 0; background: white; display: grid; place-items: center; z-index: 9999; transition: opacity 0.3s; }

.page-loader.hidden { opacity: 0; pointer-events: none; } `

Add hidden class when page loads via JS.

Button Loading State

` <button class="btn loading"> <span class="btn-text">Submit</span> <span class="btn-loader"></span> </button> `

` .btn { position: relative; }

.btn.loading .btn-text { visibility: hidden; }

.btn.loading .btn-loader { position: absolute; inset: 0; display: grid; place-items: center; }

.btn-loader::after { content: ”; width: 16px; height: 16px; border: 2px solid transparent; border-top-color: white; border-radius: 50%; animation: spin 0.8s linear infinite; } `

Toggle loading class during form submission. Size spinner to fit button height.

Inline Content Loader

` .content-area { min-height: 200px; position: relative; }

.content-area.loading::before { content: ”; position: absolute; inset: 0; background: rgba(255,255,255,0.8); }

.content-area.loading::after { content: ”; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 32px; height: 32px; border: 3px solid #e0e0e0; border-top-color: #3498db; border-radius: 50%; animation: spin 1s linear infinite; } `

Overlays existing content during refresh. Remove class when new data renders.

CSS Loader vs JavaScript Loader

Choose based on your specific requirements.

When CSS Wins

  • Simple spinning, pulsing, or bouncing animations
  • No progress tracking needed
  • Performance matters (CSS runs on GPU)
  • Fewer dependencies preferred

When JavaScript Wins

  • Dynamic progress percentage display
  • Complex sequenced animations
  • Conditional animation states
  • Integration with API responses

Most sites use CSS for visual animation, JS only for show/hide logic.

CSS Loader Browser Compatibility

Modern CSS animations work everywhere that matters.

Full Support

Chrome 43+, Firefox 16+, Safari 9+, Edge 12+. All current versions handle keyframes and transforms natively.

Vendor Prefixes

Still needed for older Safari versions:

` @-webkit-keyframes spin { to { -webkit-transform: rotate(360deg); transform: rotate(360deg); } }

.loader { -webkit-animation: spin 1s linear infinite; animation: spin 1s linear infinite; } `

Use CSS Minifier tools with autoprefixer for production builds.

Fallback Strategy

Static loading text for ancient browsers:

` .loader { / Fallback / content: 'Loading...'; }

@supports (animation: spin 1s) { .loader { / Full animation / } } `

CSS Loader Accessibility

Loading states need proper communication for all users.

ARIA Attributes

` <div class="loader" role="status" aria-label="Loading content"> <span class="visually-hidden">Loading...</span> </div> `

Screen readers announce the loading state. ARIA role tells assistive tech this is a status message.

Reduced Motion

` @media (prefers-reduced-motion: reduce) { .loader { animation: none; }

.loader::after { content: ‘Loading…’; } } `

Respects user system preferences. Some users experience motion sickness or vestibular disorders.

Check web accessibility checklist guidelines for complete implementation.

Color Contrast

Loader colors need 3:1 minimum contrast ratio against backgrounds.

Test with WCAG tools. Gray spinners on white backgrounds often fail.

FAQ on CSS Loaders

What is a CSS loader?

A CSS loader is a visual animation that displays while webpage content loads. It uses keyframe animations and transform properties to create spinning, pulsing, or bouncing effects without JavaScript dependencies.

How do I create a simple CSS spinner?

Create a div with equal width and height, apply border-radius: 50% for a circle, add a colored border-top, then animate with transform: rotate(360deg) using @keyframes. Takes about eight lines of code.

What’s the best animation duration for loaders?

Most loading animations work best between 0.8 and 1.5 seconds. Spinners typically use 1 second with linear timing. Pulse effects feel natural at 1.5 seconds with ease-in-out timing function.

How do I center a CSS loader on the page?

Use display: grid with place-items: center on the container, or display: flex with justify-content and align-items set to center. Set container height to 100vh for full viewport coverage.

Can CSS loaders work without JavaScript?

Yes. Pure CSS spinners and animations run entirely on stylesheets using @keyframes, transforms, and animation properties. JavaScript is only needed to show or hide the loader element.

What’s the difference between spinner and skeleton loaders?

Spinners are animated icons indicating activity. Skeleton loaders display placeholder shapes matching the incoming content layout, reducing perceived wait time by showing where elements will appear.

How do I make a loader accessible?

Add role=”status” and aria-label=”Loading” to the loader element. Include visually hidden text for screen readers. Respect prefers-reduced-motion media query for users with vestibular disorders.

Why is my CSS loader not spinning smoothly?

Check your animation-timing-function. Use linear for constant rotation speed. Avoid animating properties that trigger layout recalculation. Stick to transform and opacity for GPU-accelerated, smooth performance.

How do I add a loader to a button?

Position a small spinner inside the button using absolute positioning. Toggle a loading class that hides button text and displays the spinner. Size the animated spinner to fit button height.

Do CSS loaders affect page performance?

Minimal impact. CSS animations using transform and opacity run on the GPU, avoiding main thread blocking. They’re lighter than JavaScript-based alternatives and don’t increase bundle size significantly.

Conclusion

These CSS loaders examples give you ready-to-use code for any loading scenario. Copy them directly into your stylesheets.

Pure CSS animation keeps things lightweight. No external libraries, no JavaScript overhead, just clean keyframe-based motion that runs on the GPU.

Pick the right loader type for your context. Spinners work for quick operations. Progress bars suit file uploads. Skeleton screens reduce perceived wait time on content-heavy pages.

Don’t forget accessibility. Add ARIA labels, respect reduced motion preferences, and maintain proper contrast ratios.

Test your loading animations across browsers. Modern CSS transform and animation properties enjoy wide support, but vendor prefixes still help older Safari versions.

Start simple. A basic circular spinner takes eight lines of code and solves most use cases.

Author

Bogdan Sandu specializes in web and graphic design, focusing on creating user-friendly websites, innovative UI kits, and unique fonts.Many of his resources are available on various design marketplaces. Over the years, he's worked with a range of clients and contributed to design publications like Designmodo, WebDesignerDepot, and Speckyboy, Slider Revolution among others.