CSS - How add gradient over image

CSS - How add gradient over image

If you’re wanting to add a gradient to an image I have found a lot of posts that explain how to do it with background images. This has been the go-to strategy of mine for a while but I thought it didn’t feel quite right for every case.

In order to help keep a codebase maintainable the background image solution didn’t seem like the best solution. Whenever possible I want to keep my content in the html and the styles in the css. I don’t feel like that is what the background-image property is for. If an image is a part of the content and not the background, separation of concerns says to put the image in the html.

::after css pseudo-element

When I needed to add a gradient on an image this week I decided to get a cup of coffee and think about it for a minute before going with the background-image approach. The quick ponder paid off as I sat back down to try what came to mind. ::after

And here is output:

solution 1

.img-gradient {
  position:relative;
}


.img-gradient::after {
  content: '';
  position: absolute;
  left: 0; top: 0;
  width: 100%; height: 100%;
  background: linear-gradient(rgba(0, 0, 0, 0.7),rgba(0, 0, 0, 0.7));
}
<h2>Before</h2>
<img src="https://www.mybluelinux.com/img/post/posts/0130/pytest_database_testing.webp"/>
 
<h2>After</h2>
<div class="img-gradient">
  <img src="https://www.mybluelinux.com/img/post/posts/0130/pytest_database_testing.webp"/>
</div>

solution 2

img {
  /*  To contain the image to the confines of the div  */
  max-width: 100%;
}

.img-gradient {
  max-width: 100%; 
  width: 800px;
  margin: auto;
}

.img-gradient::after {
  display: block;
  position: relative;
  background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0, #fff 100%);
  margin-top: -150px;
  height: 150px;
  width: 100%;
  content: '';
}
<div class="img-gradient">
  <img src="https://www.mybluelinux.com/img/post/posts/0130/pytest_database_testing.webp" />
</div>

  • ::after vs :after: If you’re referring to content, :: should be used. after and before are examples of content whereas active or hover aren’t content. The :: is supported above IE8 but if you need IE8 support you can’t use linear-gradient and thus all this is for not. I understand…IE must be supported in some cases. Your pain is real.
  • ::after vs :before: You could do this with a before but after feels right here. If you want a gradient from the top then before would be perfect. Adapt this to your needs.

Bonus: How to add a gradient overlay to text with CSS


To add a gradient overlay to a text element, we need to set three different CSS properties to the text we want to style:

  • background-image:
  • background-clip: text
  • text-fill-color: transparent

Step 1: Add the gradient as a background

In this example we'll use a linear gradient, which can be drawn this way:

.gradient-text {
    background-image: linear-gradient(45deg, #f3ec78, #af4261);
    background-size: 100%;
}

To make the gradient cover the full width and height of your text field, set background-size: 100%, which is what I did in this example.

Step 2: Clipping the background to the text

At this point we have our gradient in the background, and the text is displayed on top of it.

The next thing we want to do is setting background-clip: text. This will only render the background where there's text. If you test this it will seem like your gradient has disappeared completely, which is because the text is still rendered as well, and the gradient layer is hidden underneath.

That's why we have to set the text-fill-color to transparent. It will remove the fill from the text, making the gradient visible again.

Step 3: Adding fallbacks

Gradients as background images clipped on top of text isn't supported by all browsers, so it's important to add fallbacks. We can do this by adding a background-color property to the text as well.

.gradient-text {
  /* Fallback: Set a background color. */
  background-color: red;
  
  /* Create the gradient. */
  background-image: linear-gradient(45deg, #f3ec78, #af4261);
  
  /* Set the background size and repeat properties. */
  background-size: 100%;
  background-repeat: repeat;

  /* Use the text as a mask for the background. */
  /* This will show the gradient as a text color rather than element bg. */
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent; 
  -moz-background-clip: text;
  -moz-text-fill-color: transparent;
}
<header>
  <h1 class="gradient-text">www.mybluelinux.com</h1>
</header>

<link href="https://fonts.googleapis.com/css?family=Archivo+Black&display=swap" rel="stylesheet">

result: