Simple blur hover effect with just HTML and CSS

Patrick Cho
5 min readMay 20, 2021
Isn’t this a lot of fun? One might say it’s a llama fun…

Ever wondered how those cool blur effects work on mouse hover? Or perhaps you’re simply looking for another way to jazz up your web project and add a tool to your bag of web tricks. Either way, I’m here to show you how to get a silky smooth blur hover effect using just HTML and CSS.

(Note: ‘backdrop-filter’ is not supported by IE, Firefox for Android and Firefox v70+. You can use ‘filter’ instead for improved support.)

Show me the code!

For those who already know HTML and CSS like the back of their keyboard, here’s the Codepen. For everyone else, read on for a step by step tutorial.

HTML structure

First establish the skeletal structure of the HTML.

All you need:
1) A wrapping parent div, which for us has class = “tile”
2) Two children divs for “tile”, both of which are ‘position: absolute’
3) class = “image” is the div that has the llama image as its background
4) class = “overlay” is the div with the blur AND whatever text/content you want over the image

<div class="tile">
<div class="image"></div>
<div class="overlay"></div>
</div>

Lets style it a little

  • Make the parent “tile” div to the dimensions you want. You could make it square, a circle, tall, short, add border-radius with ‘overflow: hidden’, the world’s your oyster … mine’s a simple rectangle, ‘height:450px’ and ‘width:350px’.
  • Don’t forget to give it relative positioning so that the children can have absolute positioning!
.tile {
width: 350px;
height: 450px;
position: relative;
}
  • Make the “image” div ‘position: absolute’ and have its height and width 100% to cover the whole “tile”. This percentage is with respect to its parent container which is what we want.
  • Use the ‘background-image’ CSS property and insert an image URL
  • ‘Background-size: cover’ should ensure the image covers the whole “image” div
  • Do the same for the “overlay” div. Position absolute and 100% dimensions
  • This “overlay”, as the name suggests, simply lies on top of the “image” div
.image {
position: absolute;
width: 100%;
height: 100%;
background-image: url('enter your image URL here');
background-size: cover;
}
.overlay {
position: absolute;
width: 100%;
height: 100%;
}

This is where the fun starts

  • Give the “overlay” div the CSS properties ‘backdrop-filter: blur(8px)’ and ‘transition: all 0.5s’
  • Obviously, the blur amount is up to you and the transition can be more specific (not ‘all’) with a time span of your preference, but we haven’t specified WHAT we’re transitioning so just leave it for now
.overlay {
position: absolute;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
backdrop-filter: blur(8px);
transition: all 0.5s;
}
  • Your tile should look like this:
  • Using ‘clip-path’ we will make “overlay” div only be a small rectangle that’s 100px tall. To go from complete rookie to pro on clip-paths, use this website : https://bennettfeely.com/clippy/
    It’s a lifesaver!
.overlay {
...
clip-path: polygon(0 calc(100% - 100px), 100% calc(100% - 100px), 100% 100%, 0% 100%;
...
}
The new “overlay” div is highlighted in dotted red
  • You should be able to tell by now that ‘clip-path’ combined with ‘backdrop-filter: blur’ is the magic combo that creates the hover.
  • The transition is simply going to make the ‘clip-path’ polygon cover the whole tile, returning the “overlay” div to its original state of covering 100% of the height and width. Let’s make it happen!
  • In simple terms, we want it so that when you hover over the “tile”, “overlay” div’s clip-path goes from being 100px tall to being 100% tall. I find it very helpful to phrase CSS transitions like this in plain English before going to the code:
.tile:hover .overlay {
clip-path: polygon(0 0,100% 0,100% 100%,0% 100%);
}

You’re almost there!

Well done on making it this far. Your basic layout should be done and the hover transition animation should be working as intended.

All that’s left to do is put in some content inside “overlay” that sits on the blurry clip-path and some other content that shows on mouse hover as the clip-path expands.

The reason I personally made the clip-path 100px tall is because I wanted to show text in a div that’s 100px tall at the bottom of the tile, with further text showing upon hover.

So I took my HTML code from this:

<div class="tile">
<div class="image"></div>
<div class="overlay"></div>
</div>

To this:

<div class="tile">
<div class="image"></div>
<div class="overlay">
<div class="hidden-text">
Now you can read the hidden text.
Imagine all the ways you could use this to add a little fun to your web projects!
</div>
<div class="visible-text">
Hover for more
</div>
</div>
</div>

Now all I had to do styling-wise was some basic CSS to position the new divs within “overlay” and to center their texts:

  • Make “overlay” a flexbox with column direction
  • Use flex property to make “visible-text” 100px tall (the same height as “overlay” div’s clip-path) and “hidden-text” to grow auto
  • Use flexbox to center the texts inside of “hidden-text” and “visible-text” with align-items: center; text-align: center;
.hidden-text {
flex: 1 0 auto;
display: flex;
align-items: center;
text-align: center;
width: 60%;
margin: 0 auto;
color: white;
}
.visible-text {
flex: 0 0 100px;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
text-transform: uppercase;
font-size: 2rem;
color: white;
}

Et voilà

And there you go, you’ve just added another neat HTML and CSS transition to your arsenal of design tricks to keep users engaged and hungry for more.

I hope this has been helpful and straightforward for you. This is my first mini-tutorial on Medium so any feedback would be greatly appreciated!

Stay tuned for more tutorials and articles on web development, UX design and product management :)

--

--

Patrick Cho

Web development, UX design, product management <3 ... need I say more