Lazy Loading Using HTML, CSS & JavaScript

5 min read
Lazy Loading Demo

Project Overview

This project demonstrates a "Lazy Loading" effect using HTML, CSS, and JavaScript, creating a visually engaging loading experience. It features a full-screen background image that starts blurred and gradually sharpens as a loading percentage counter increments from 0% to 100%. This effect simulates content loading in the background, providing a smooth transition from a placeholder state to a fully loaded view.

The design uses a large, prominent background image that is initially heavily blurred. A large, red percentage text overlays this background, indicating the loading progress. The core of the functionality lies in JavaScript, which uses `setInterval` to increment the `load` counter, updates the `loadingText` opacity (fading out as it loads), and dynamically adjusts the `background` image's `filter` (blurring less as it loads). A `scale` function is used to map the loading percentage to appropriate opacity and blur values. CSS is used to style the background and text, ensuring a full-screen, centered, and visually appealing loading animation. This project is an excellent example of combining HTML structure, CSS visual effects, and JavaScript for dynamic content loading and user feedback.

HTML Structure

The HTML structure for this lazy loading effect is minimal and focused on the visual elements. It is contained within a `main` element with the class `loader-container`. Inside, there are two `section` elements: `background-section` and `progress-section`. The `background-section` contains a `div` with the class `background` and `id="background"`, which will serve as the blurred background image. The `progress-section` contains a `div` with the class `loading-text` and `id="loadingText"`, which will display the loading percentage. Both the `background` and `loadingText` elements have `aria-label` for accessibility. A `script` tag links to an external JavaScript file (`app.js`) to handle the loading animation logic. This structure provides a clear separation of the background image and the loading text display.


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Lazy Loading</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <main class="loader-container">
      <section class="background-section>
        <div 
          class="background" 
          id="background"
          aria-label="Loading background"
        ></div>
      </section>

      <section class="progress-section">
        <div 
          class="loading-text" 
          id="loadingText"
          aria-label="Loading percentage"
        >0%</div>
      </section>
    </main>

    <script src="app.js"></script>
  </body>
</html>
                        

CSS Styling

The CSS for this project styles the lazy loading effect, focusing on the background image and the loading text. The `body` is set to take up the full viewport height, centering its content and preventing overflow. The `.background` element is positioned absolutely to cover the entire viewport, with a large, centered background image (`url(...) no-repeat center center/cover`). It's initially positioned slightly off-screen (`top: -30px; left: -30px;`) and scaled up to create a subtle parallax effect and ensure full coverage when blurred. The `z-index: -1` places it behind other content. The `.loading-text` is styled with a large `font-size` and red color for prominence. Importantly, the `filter: blur(0)` property is used on the background, which will be dynamically controlled by JavaScript to create the blurring effect. This combination of styles sets up the visual foundation for the lazy loading animation.


* {
  box-sizing: border-box;
}

body {
  font-family: sans-serif;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
  overflow: hidden;
  margin: 0;
}

.background {
  background: url(https://images.unsplash.com/photo-1592394675778-4239b838fb2c?crop=entropy&cs=tinysrgb&fm=jpg&ixlib=rb-1.2.1&q=80&raw_url=true&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1074)
    no-repeat center center/cover;
  position: absolute;
  top: -30px;
  left: -30px;
  width: calc(100vw + 60px);
  height: calc(100vh + 60px);
  z-index: -1;
  filter: blur(0); /* Initial blur, JavaScript will control this */
}

.loading-text {
  font-size: 50px;
  color: red;
}

                        

JavaScript

The JavaScript for this project brings the lazy loading effect to life. It first selects the loading text element (`loadText`) and the background element (`background`). A `load` variable is initialized to `0`, and a `setInterval` function named `blurring` is set to run every `30` milliseconds. Inside `blurring`, the `load` counter increments. Once `load` reaches `100`, the interval is cleared. The `loadText.innerText` is updated to display the current percentage. Crucially, the `loadText.style.opacity` and `background.style.filter` (for blur) are dynamically updated using a `scale` function. This `scale` function maps a number from one range to another, allowing the `load` percentage (0-100) to control the opacity (1-0) and blur (30px-0px) of the elements, creating a smooth fading and sharpening effect as the page "loads".


const loadText = document.querySelector(".loading-text");
const background = document.querySelector(".background");

let load = 0;
let int = setInterval(blurring, 30);

function blurring() {
  load++;

  if (load > 99) {
    clearInterval(int);
  }

  loadText.innerText = `${load}%`;
  loadText.style.opacity = scale(load, 0, 100, 1, 0);
  background.style.filter = `blur(${scale(load, 0, 100, 30, 0)}px)`;
}

// Function to map a number from one range to another
const scale = (num, in_min, in_max, out_min, out_max) => {
  return ((num - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min;
};

                        

Live Demo: Lazy Loading Effect

Watch a live demonstration of the Lazy Loading effect below.

Final Thoughts

This "Lazy Loading" project provides a visually appealing and user-friendly way to indicate content loading on a web page. By combining a blurred background with a fading percentage counter, it creates a smooth and engaging transition. This technique is particularly effective for pages with large images or content that takes time to load, as it provides immediate feedback to the user and prevents a blank screen experience.

You can easily customize this component by:

  • Changing the background image to suit your content.
  • Adjusting the `setInterval` delay for faster or slower loading animations.
  • Modifying the `scale` function parameters to change the intensity of the blur or opacity transitions.
  • Integrating this loading effect with actual content loading (e.g., fetching data from an API).
  • Adding different loading animations or progress indicators.

Pro Tip

For a more realistic lazy loading experience, you can combine this visual effect with actual asynchronous content loading (e.g., fetching images or data via JavaScript's `fetch` API). The `load` counter could then be tied to the progress of these actual loading operations, providing a more accurate representation of the content readiness.

Ready to Use This Project?

Click the button below to download the full source code. Download will be ready in 10 seconds.

Stay Updated

Receive coding tips and resources updates. No spam.

We respect your privacy. Unsubscribe at any time.