Pure CSS Frosted Glass Image Reveal Effect: Inspired By 4o Image Generation

Category: CSS & CSS3 , Loading | March 28, 2025
AuthorCSSScript
Last UpdateMarch 28, 2025
LicenseMIT
Views64 views
Pure CSS Frosted Glass Image Reveal Effect: Inspired By 4o Image Generation

This is a frosted glass image loading/revealing effect inspired by ChatGPT-4o Image Generation.

The effect provides an interesting way to handle image loading states, especially when you want something more dynamic than a simple fade-in.

It solves the “blank space” problem during load, replacing it with a stylized placeholder that smoothly transitions to the final image.

See It In Action:

Features:

  • Pure CSS Animation: The reveal animation relies entirely on CSS transitions.
  • Frosted Glass Effect: Uses backdrop-filter: blur() for the core visual.
  • Smooth Reveal: Employs mask-image with a linear gradient for a soft edge during the transition.
  • Customizable Timing: Easily adjust animation speed and easing via the transition property.
  • Simple Structure: Requires minimal HTML markup (a container, image, and overlay div).
  • Responsive: Adapts well using standard CSS techniques like max-width and aspect-ratio.

How to use it:

1. Place your image and blur overlay in a container div:

<div class="image-container">
  <!-- Your target image -->
  <img src="https://www.jqueryscript.net/dummy/1.jpg" alt="Image Alt">
  <!-- The frosted glass overlay -->
  <div class="blur-overlay"></div>
</div>

2. The core CSS styles for the frosted glass overlay. I’ve included comments explaining the key parts.

  • aspect-ratio: Using aspect-ratio on the container is good practice. It prevents layout shifts as the image loads. Adjust the ratio (e.g., 1/1 for square, 4/3) based on your images.
  • object-fit: cover;: This makes the image fill the container nicely, but be aware it might crop parts of the image if the aspect ratios don’t match exactly. Use object-fit: contain; if you need to see the whole image, but you might get letterboxing.
  • backdrop-filter Performance: This property can be computationally intensive, especially with large blur radii or on complex pages. Test performance on target devices. On lower-end hardware, it might cause jank. Keep the blur radius reasonable (e.g., 10px-30px).
  • mask-image Gradient: The 25% value in the linear-gradient controls how soft the transition edge is. A smaller percentage means a sharper edge; a larger percentage means a softer, more feathered edge. Experiment to find what looks best.
.image-container {
  position: relative; /* Needed for absolute positioning of the overlay */
  width: 500px;      /* Or your desired width */
  max-width: 90%;    /* Make it responsive */
  aspect-ratio: 16 / 9; /* Maintain aspect ratio - adjust as needed */
  overflow: hidden;  /* Crucial: hides the overlay as it moves out */
  border-radius: 8px; /* Optional: styling */
  box-shadow: 0 4px 15px rgba(0,0,0,0.1); /* Optional: styling */
}
.image-container img {
  display: block;    /* Avoids mystery space below image */
  width: 100%;
  height: 100%;
  object-fit: cover; /* Ensures image covers container, may crop */
  border-radius: 8px; /* Match container rounding if any */
}
.blur-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255, 255, 255, 0.2); /* Light overlay, adjust opacity */
  /* The core blur effect */
  /* Note: Check browser compatibility for backdrop-filter */
  backdrop-filter: blur(20px);
  /* You might still need the -webkit- prefix for older Safari */
  /* -webkit-backdrop-filter: blur(20px); */
  /* The soft edge reveal using a mask */
  mask-image: linear-gradient(
      to bottom,
      transparent 0%, /* Top is fully masked (invisible) */
      black 25%       /* Becomes fully opaque (visible) below 25% */
  );
  /* Prefix for compatibility */
  -webkit-mask-image: linear-gradient(
      to bottom,
      transparent 0%,
      black 25%
  );
  /* Animation settings */
  /* Adjust duration and easing function here */
  transition: transform 8s cubic-bezier(0.25, 0.1, 0.25, 1.0);
  /* Initial position: overlay covers the image */
  transform: translateY(0%);
}
/* The state when the image is 'loaded' */
.image-container.loaded .blur-overlay {
  /* Move the overlay down out of view */
  transform: translateY(100%);
}

3. The CSS handles the look and the animation, but something needs to trigger the end state. This is done by adding the .loaded class to the .image-container. You’ll typically do this with JavaScript once the image is actually loaded, or after a simulated delay.

document.addEventListener('DOMContentLoaded', () => {
  const imageContainers = document.querySelectorAll('.image-container'); // Select all containers if multiple
  imageContainers.forEach(container => {
    const img = container.querySelector('img');
    // Option 1: Trigger after real image load
    if (img.complete) { // Handle cached images
        container.classList.add('loaded');
    } else {
        img.addEventListener('load', () => {
            container.classList.add('loaded');
        });
        // Optional: Add error handling here too
        img.addEventListener('error', () => {
            console.error('Image failed to load:', img.src);
            // Maybe add an error class instead?
            // container.classList.add('error');
        });
    }
    // Option 2: Simulate delay (like the example) - Useful for demos
    // setTimeout(() => {
    //     container.classList.add('loaded');
    // }, 1500); // Adjust delay as needed
  });
});

You Might Be Interested In:


Leave a Reply