DEV Community

Cover image for Two ways to create an image with a colour overlay in CSS
Ellen Macpherson
Ellen Macpherson

Posted on

CSS Image Overlay Two ways to create an image with a colour overlay in CSS

Using an image with a dark overlay is one of the quickest ways to make a beautiful hero header for a blog, landing page or portfolio. It's a trick I use constantly.

Why should you add an overlay to your image?

An overlay on an image not only improves aesthetics but it makes text much more readable.

Consider this hero header I've mocked up. It's not great, is it?

Hero header with no overlay

The text here is readable. But only just, and it's because I've used H1 and H2 headers. Yet, it's not very accessible for people with reduced vision, and it's also really busy to look at. Overlays vastly improve readability, along with making your design much more sleek. In this post, I'll be showing you a couple of ways to code them up.

There are, of course, many ways you can get to your end goal here. These are the two methods I find easiest to remember. Which method you choose will depends on the purpose of the image. If you're only after a pretty background, you can go about this any way you like. Alternatively, if your image isn't just decorative and you want people to notice it, you should use an image tag with an alt description for accessibility.

Using an image tag and a section background.

Again, this is your best option if your image isn't just decorative. This might not be in a header; it might be in an image aside or as part of an article.

First, place an img tag in a section.

<header>
   <img src="https://bit.ly/2rlzaXi" alt="Five developers at work.">
   <section class='hero-header-text'>
      <h1>Ellen Macpherson</h1>
      <h2>Just another tech blog.</h2>
      <button>Read more.</button>
   </section>
</header>
Enter fullscreen mode Exit fullscreen mode

I've purposely avoided a div here. If you're creating a header, make sure you're using semantic HTML to define it as such. This will help with both accessibility and SEO considerations. For more on why you should use semantic HTML elements, see this helpful blog post.

Now for the CSS. Make sure the image fills the header, either by using height: 100%, width: 100%, or by using object-fit: cover.

Set the background to your desired colour. In this case, i've just kept it black, but you could also make clever use of a linear gradient to really make things pop (see the next section for details). Set the opacity of the image somewhere between 0.3 - 0.5.

header {
    height: 600px;
    width: 100vw;
    background: black;
    overflow: hidden;
}

img {
   object-fit: cover;
   opacity: 0.4;
}
Enter fullscreen mode Exit fullscreen mode

And viola! You've got a much nicer looking background that draws the eye immediately to the text and call-to-action button.

Header with dark overlay

Pros: Allows you to set alt text for the image. Browser-friendly.

Cons: Involves more HTML and styling than other methods.

Using a linear gradient

This is my preferred method. There's less styling and thinking involved around the layout. Often, you won't be using these images for descriptive purposes, so it seems more intuitive to handle the background in CSS.

In this case, you don't need to reference the image in the HTML at all, so the code only involves the header (or whichever tag you want to style) and any text or buttons on top:

<header>
    <section class='hero-header-text'>
        <h1>Ellen Macpherson</h1>
        <h2>Just another tech blog.</h2>
        <button>Read more.</button>
    </section>
</header>
Enter fullscreen mode Exit fullscreen mode

Remember, you can't set alt tags without HTML, so make sure the image you're using is purely decorative.

Although CSS linear gradients is well-supported now, I'm going to use a fallback colour along with the webkit prefix to make sure I cover all browser possibilities. This also gives you a fallback if, for any reason, the background image is slow to load. Remember the C in CSS; everything cascades. Therefore, your foolproof fallback colour and alternative webkit prefixed styles should always come before the least-supported solution. In this case, that's linear-gradient().

header {
    height: 600px;
    width: 100vw;
    background: black;
    overflow: hidden;
    background: #C33764;  /* fallback colour. Make sure this is just one solid colour. */
    background: -webkit-linear-gradient(rgba(29, 38, 113, 0.8), rgba(195, 55, 100, 0.8)), url("https://bit.ly/2rlzaXi");
    background: linear-gradient(rgba(29, 38, 113, 0.8), rgba(195, 55, 100, 0.8)), url("https://bit.ly/2rlzaXi"); /* The least supported option. */
}

img {
   object-fit: cover;
}

Enter fullscreen mode Exit fullscreen mode

Here we are with a more colourful interpretation of an overlay:

Header with pink and purple gradient overlay

In this example, I've used the RGBA colour format to make the gradient transparent and set the opacity to 0.8 for a bold finish. However, colour gradients will never look the same on different images. Play around with the opacity to make sure it works well with your design. For more impact, make the image underneath grayscale and alter its contrast.

Pros: Uses fewer lines of code. Easier to implement.

Cons: Issues around browser support mean you'll have to remember to set a fallback image or colour for your background.

That's it! If you have any other great ways to implement an overlay, let me know in the comments. Let me know your favourite gradients, too πŸ‘‡

Discussion (20)

Collapse
sonawaneapekshit profile image
sonawaneapekshit

We can also use a solution like below but it will require some what more CSS.
Here is the link: codepen.io/sonawaneapekshit/pen/Rw...

Collapse
timonwa profile image
Pelumi Eyitimonwa Akintokun

I have never thought about doing it this way b4. It's usually the two mentioned in the post. Thanks for sharing this.

Collapse
redcrew profile image
Deborah Edwards-Onoro

I like these solutions, thank you for sharing. Did you notice a performance difference between the two solutions for color overlay?

Collapse
felipperegazio profile image
Felippe Regazio

pretty cool, ellen!

Collapse
ellen_dev profile image
Ellen Macpherson Author

Cheers, Felippe!

Collapse
karenefereyan profile image
Efereyan Karen Simisola

This was so helpful to me Ellen. Thank you

Collapse
drozumek profile image
Damian Rozumek

The first method won't work. You have to position absolutely img or section tag. Otherwise the img will fit all the available space and push section tag with text out out the view.

Collapse
gracefrank profile image
Grace Frank

yea, I tried it, the section was at the bottom. and now I have to give the section positioning

Collapse
enieber profile image
Enieber Cunha

this solution is very elegant, thanks...

Collapse
gistkitmedia profile image
GistKit.com

i have successfully applied this tutorial on my blog, gistkit.com.ng

Thanks for the helpful tutorial.

Collapse
courtneypure profile image
C. Pure

Thanks for this post! I’m excited to try this out and spice up my portfolio site πŸ‘©πŸ½β€πŸ’»πŸ‘πŸΌπŸ‘πŸΌ

Collapse
sbateswar profile image
Stanley Bateswar

Cool!

Collapse
weptim profile image
WEPUKHULU TIMOTHY

Lol

Collapse
adisaktijrs01 profile image
Adi Sakti Jrs

Ah, genius! Big thanks

Collapse
gaspar profile image
Diogo Gaspar

Thank you, helped me a lot.

Collapse
weptim profile image
WEPUKHULU TIMOTHY

How can you use it with a video background

Collapse
ellen_dev profile image
Ellen Macpherson Author

I don't work with videos too often, but theres a solution here: stackoverflow.com/questions/489620...

Collapse
bam92 profile image
Abel Lifaefi Mbula

Typo: VIOLA, should be VOILA.

Collapse
dominic profile image
Dom

I used this post today for a project! thanks Ellen

Collapse
kellyrhabin profile image
Neza Regis

This article helped me to solve fuck codes I struggled with 2 weeks 🀝🀝 writer