DEV Community

Cover image for CSS Smart Image Glow
Andrew Jones
Andrew Jones

Posted on • Edited on

CSS Smart Image Glow

Recently I saw this UI design for a Nintendo Switch Store mobile app concept from Orizon Design on Dribbble:

My first thought was "Wow, what a cool glow effect - based on the image itself." This got me thinking about a reusable approach to do this.

Implementation

I started by creating a simple HTML page with a transparent-background picture of Majora's Mask (following the Nintendo theme with my favorite game).



    <h1>"Smart" Image Glow Effect</h1>
    <div id="maskparent">
      <img src="/mask.png" id="mask" alt="Majora's Mask with glow" />
    </div>


Enter fullscreen mode Exit fullscreen mode

At first, I tried adding filters to the mask picture, like the drop-shadow:



#mask {
  filter: drop-shadow(0 0 0.75rem rgb(255, 217, 0));
}


Enter fullscreen mode Exit fullscreen mode

This was the result:
Poorly done, simple glow
However, this was a super basic, single-color glow, and the color had to be manually set. It wouldn't be reusable across images either, because the single color would be different for each image. Plus, the single-color doesn't look good with a colorful image like Majora's Mask.

After some research and testing, I found that the best way to accomplish this would be using a copy of the mask in the background.

I added this code to the CSS:



#maskparent {
  background-repeat: no-repeat;
  background-image: url("/mask.png");
}


Enter fullscreen mode Exit fullscreen mode

This successfully placed a copy of the image directly behind the image, but next we needed to blur it to actually create a glow effect instead of just a double image.

I accomplished this with a backdrop-filter on the mask element. This allows an element to apply a filter to the element behind itself. So, applying backdrop-filter to the mask actually applies a filter to the background image of the div underneath the mask.



#mask {
  /* This line:
   1. blurs the background so we can see it around the 
         image as "glow"
   2. increases the background saturation so we get colors 
         back after the shadow effect dulls them out
  */
  backdrop-filter: blur(15px) saturate(3);
}


Enter fullscreen mode Exit fullscreen mode

This was an "aha!" moment, we almost have the effect I was looking for:
Correct glow with clipped edges
However, you can see there's one issue left: the parent div clips the backdrop blur, creating a weird hard edge.

To solve this, we can use a trick to make the element div border-box bigger without moving the element:



#mask {
  ...
  /* These lines prevent the border box from clipping the blur 
     effect */
  padding: 20px;
  margin: -20px;
}


Enter fullscreen mode Exit fullscreen mode

Ta-da! This was exactly the effect I was looking for:
Finished Mask with Smart Glow

Taking it Further

One note, this vanilla-HTML/CSS implementation doesn't exactly solve the re-usability problem I mentioned, because the picture URL is hardcoded twice. This could easily be solved with JS or in a JS framework. For example, we could make a React component to wrap <img> which sets the same picture URL for the background image and the HTML image.

You can play with this effect in the codesandbox below. (on mobile, you might need to open it in a new window)

If you liked this article, let me know in the comments or check out my Twitter, @ajones_codes. Thanks for reading!

Top comments (0)