Having images on your page is nice, but what if you want to create a fading effect (like the banner image for this article)? As it turns out, you can easily do this in CSS using ::before and ::after pseudo-elements. That’s what we’ll explore in this article.
I built a small demo on CodePen. We’ll go through it in detail below. Feel free to keep referring back here to better understand how the effect works:
Setting Up the Page
Assuming you’ve applied a basic CSS reset and have your HTML in place, we will start by styling the body to occupy the whole page and center its contents:
body {
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
Next, we create two divs to demonstrate the fade. We’ll give each of these a width and height. We’ll also set the positioning of each to relative. That way, we have control over how to position their children. ::before and ::after pseudo-elements can be treated and styled as children of their parents. They can also only be positioned relative to the last positioned ancestor. Since we want the pseudo-elements positioned relative to the two divs we create, we’ll set the position of the divs to relative. You can learn more about positioning here and more about pseudo-elements here.
HTML:
CSS:
.first-div, .second-div{
position: relative;
background: #ccc;
height: 200px;
width: 200px;
}
.second-div {
margin-top: 10px;
}
Now that we have the divs in place, we’ll style the pseudo-elements.
For the first div, I will add the fading effect to the bottom. We position the ::after pseudo-element on the bottom, give it a width and height, and set a linear gradient on it. Don’t forget to set the content of the pseudo-element or it won’t work. Also, the linear gradient should end at completely transparent for the fading effect to blend into the rest of the div.
.first-div::after {
content: "";
position: absolute;
left: 0;
bottom: 0;
background: linear-gradient(to top, #999, transparent);
width: 100%;
height: 50px;
}
We’ll do the same for the second div, except this time we’ll use a ::before element (it really doesn’t matter whether you use a ::before or ::after element, I just decided to use both to demonstrate that it can work with both). We’ll position it at the top and give it a linear gradient going down instead of up.
.second-div::before {
content: "";
position: absolute;
left: 0;
top: 0;
background: linear-gradient(to bottom, #999, transparent);
width: 100%;
height: 50px;
}
The two divs should look something like below:
Let’s try and do the same for an image. First, we set up some HTML to organize everything:
You can, of course, set the src
attribute to any source you like.
Next, we’ll style the container div so it arranges the children properly:
.container {
display: flex;
width: 60%;
justify-content: space-between;
margin-top: 50px;
}
The margin property is so that it has some room to breathe from the divs above that we created earlier.
Next, we’ll style the children so they also look good (and similar to our earlier divs:
.no-fade, .bottom-fade {
position: relative;
background: #ccc;
height: 200px;
width: 200px;
}
And then we’ll style the images so they fit properly in the divs. We will explicitly set the height and width of the image and then use object-fit: cover
so the image maintains its aspect ratio. You can learn more about object-fit here.
img {
width: 100%;
height: 100%;
object-fit: cover;
}
Now we can finally style the pseudo-element on the right div to create the effect:
.bottom-fade::after {
content: "";
position: absolute;
left: 0;
bottom: 0;
background: linear-gradient(to top, #111, transparent);
width: 100%;
height: 100px;
}
The end result shows the original image and its faded version side by side:
I did the same with the images fading from the top. I’ll share the complete CodePen again so you can play around with it.
And that’s it for now. What do you think about this trick? Drop a comment below!