87

I am trying to achieve something like this:

this effect

When I hover over an image, I would like to put on that image this dark color with some text and the icon.

I am stuck here. I found some tutorials but they didn't work out for this case. Also, another issue -- every image has a different height. The width is always the same.

How can this effect be achieved?

numaroth
  • 1,295
  • 4
  • 25
  • 36
user984621
  • 46,344
  • 73
  • 224
  • 412
  • possible duplicate of [How to overlay images](http://stackoverflow.com/questions/403478/how-to-overlay-images) – Ranveer Jan 13 '14 at 08:10

5 Answers5

140

You can achieve this with this simple CSS/HTML:

.image-container {
    position: relative;
    width: 200px;
    height: 300px;
}
.image-container .after {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: none;
    color: #FFF;
}
.image-container:hover .after {
    display: block;
    background: rgba(0, 0, 0, .6);
}

HTML

<div class="image-container">
    <img src="http://lorempixel.com/300/200" />
    <div class="after">This is some content</div>
</div>

Demo: http://jsfiddle.net/6Mt3Q/


UPD: Here is one nice final demo with some extra stylings.

.image-container {
    position: relative;
    display: inline-block;
}
.image-container img {display: block;}
.image-container .after {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: none;
    color: #FFF;
}
.image-container:hover .after {
    display: block;
    background: rgba(0, 0, 0, .6);
}
.image-container .after .content {
    position: absolute;
    bottom: 0;
    font-family: Arial;
    text-align: center;
    width: 100%;
    box-sizing: border-box;
    padding: 5px;
}
.image-container .after .zoom {
    color: #DDD;
    font-size: 48px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -30px 0 0 -19px;
    height: 50px;
    width: 45px;
    cursor: pointer;
}
.image-container .after .zoom:hover {
    color: #FFF;
}
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css" rel="stylesheet"/>

<div class="image-container">
    <img src="http://lorempixel.com/300/180" />
    <div class="after">
        <span class="content">This is some content. It can be long and span several lines.</span>
        <span class="zoom">
            <i class="fa fa-search"></i>
        </span>
    </div>
</div>
dfsq
  • 191,768
  • 25
  • 236
  • 258
  • 1
    But the problem is that I don't know the height of the **.image-container**. – user984621 Jan 13 '14 at 08:24
  • I played with it and it seems to be working, thanks **dfsq**! Just one thing - how could I stick the text always at the bottom of the respective image? Thank you – user984621 Jan 13 '14 at 08:56
  • I am fighting yet with placing the icon in the middle of the hovered area -- is there any effective way how to put it there? Thx – user984621 Jan 13 '14 at 09:50
  • 1
    By using display:none, you've stopped the ability to use any sort of animation and transition effect, Which I think is an important aesthetic to getting overlays to look good. – GibsonFX Mar 23 '17 at 10:14
  • @LukeJonGibson Haha, and that's why this answer is not useful and needs to be downvoted. – dfsq Mar 23 '17 at 10:24
  • @user984621 did you find a way to place the text in the middle? – Adam Dec 11 '19 at 08:26
  • use
    on HTML element as much as you want till satisfied.


    This is some content
    – Camille Basbous Apr 12 '21 at 20:57
43

You could use a pseudo element for this, and have your image on a hover:

.image {
  position: relative;
  height: 300px;
  width: 300px;
  background: url(http://lorempixel.com/300/300);
}
.image:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  transition: all 0.8s;
  opacity: 0;
  background: url(http://lorempixel.com/300/200);
  background-size: 100% 100%;
}
.image:hover:before {
  opacity: 0.8;
}
<div class="image"></div>
lubilis
  • 3,942
  • 4
  • 31
  • 54
jbutler483
  • 24,074
  • 9
  • 92
  • 145
41

Putting this answer here as it is the top result in Google.

If you want a quick and simple way:

    filter: brightness(0.2);

*Not compatible with IE

Andrew Samole
  • 695
  • 7
  • 7
  • 3
    The post is 6 years old and the accepted answer has 100+ votes, some of which are in the past few months. There's nothing wrong with your answer, but perhaps you can expand more as to why your answer might be useful for people reading this in 2020. Is this a new feature of css? – Cohan Jan 23 '20 at 16:37
  • 1
    Filter has been around for years. I didn't see it in any of the answers so I thought I could help people who are still navigating to this page for a much quicker solution. – Andrew Samole Jan 23 '20 at 21:45
  • Hopefully it's useful to those who come across it. Your post just had showed up in the "Late Answers" queue. Since it's not really my realm, I think it would be cool to see a little more in your answer as to how this compares to the other answers. Maybe supply a jsfiddle to compare against the top answer. – Cohan Jan 23 '20 at 21:47
  • This is exactly what I was looking for! Thank you. – salsaverde Mar 28 '21 at 01:10
  • this is a nice additional comment / insight – Sri Nithya Sharabheshwarananda Apr 24 '22 at 02:11
  • This is precisely what I needed, thanks! – Ascent Sep 27 '22 at 12:37
20

A bit late for this, but this thread comes up in Google as a top result when searching for an overlay method.

You could simply use a background-blend-mode

.foo {
    background-image: url(images/image1.png), url(images/image2.png);
    background-color: violet;
    background-blend-mode: screen multiply;
}

What this does is it takes the second image, and it blends it with the background colour by using the multiply blend mode, and then it blends the first image with the second image and the background colour by using the screen blend mode. There are 16 different blend modes that you could use to achieve any overlay.

multiply, screen, overlay, darken, lighten, color-dodge, color-burn, hard-light, soft-light, difference, exclusion, hue, saturation, color and luminosity.

Emil Mladenov
  • 320
  • 1
  • 4
  • 10
  • 3
    This is a great idea. However the main problem is that it requires both images to be background images. If the primary image is an HTML ``, it doesn't work. Also, at the time, `background-blend-mode` is *not* well supported: late versions of Chrome and FF with partial support in Safari (http://caniuse.com/#search=background-blend-mode) – bassplayer7 Aug 02 '16 at 22:40
1
.bg-img{
  text-align: center;
  padding: 130px 0px;
  width: 100% !important;
  background-size: cover !important;
  background-repeat: no-repeat !important;
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.86), rgba(0, 0, 0, 0.86)), url(your-img-path);
}
Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62
Akash Pise
  • 90
  • 2
  • 13