63

I want to add some shine to an element on webpage. I would prefer if I don't have to add additional html to the page. I want the image to appear in front of the element rather than behind. What's the best way to do this?

Rob W
  • 341,306
  • 83
  • 791
  • 678
Himmators
  • 14,278
  • 36
  • 132
  • 223
  • Are the dimensions of the element fixed? – Rob W Sep 30 '12 at 09:08
  • Yes they are. More charcters to allow me to comment. – Himmators Sep 30 '12 at 09:10
  • I'm trying to make it work with the :after psuedo-element now... – Himmators Sep 30 '12 at 09:14
  • "I would prefer if I don't have to add additional html to the page." That's not possible: You have to use a wrapper element and a pseudo-element `(::before)` as you see in [Rob W's answer](https://stackoverflow.com/a/12660106/478018), or an `` element as you see in [my answer](https://stackoverflow.com/a/71449486/478018). – Mori Mar 16 '22 at 07:47

5 Answers5

78

To achieve a "foreground image" (without extra HTML code), you can use a pseudo-element (::before / :before) plus the CSS pointer-events. The last property is needed so that the user can actually click through the layer "as if it did not exist".

Here's an example (using a colour whose alpha channel is 50% so that you can see that the real elements can actually be focused). http://jsfiddle.net/JxNdT/

#cont {
  width: 200px;
  height: 200px;
  border: 1px solid #aaa;
  /*To show the boundaries of the element*/
}

#cont:before {
  position: absolute;
  content: '';
  background: rgba(0, 0, 0, 0.5);
  width: 200px;
  height: 200px;
  pointer-events: none;
}
<div id="cont">
  Test<br>
  <input type="text" placeholder="edit">
</div>

​ PS. I picked the ::before pseudo-element, because that naturally leads to the correct positioning. If I pick ::after, then I have to add position:relative; to the real element (#cont), and top:0;left:0; to the pseudo-element (::after).


PPS. To get the foreground effect on elements without a fixed size, an additional element is needed. This wrapper element requires the position:relative;display:inline-block; styles. Set the width and height of the pseudo-element to 100%, and the pseudo-element will stretch to the width and height of the wrapper element. Demo: http://jsfiddle.net/JxNdT/1/.

Mori
  • 8,137
  • 19
  • 63
  • 91
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • great stuff! As the image already has alpha-transparency, i wont need the background-element, but apart from i'll just copy paste! – Himmators Sep 30 '12 at 09:23
  • Just curious, is there a similair solution if the element size is not static? – Himmators Sep 30 '12 at 09:28
  • 2
    @KristofferNolgren You need a wrapper which has `position:relative;` (and `display:inline-block;`), then use `100%` for `width` and `height` on the pseudo-element. The pseudo-element will stretch to the width and height of the wrapper element. Demo: http://jsfiddle.net/JxNdT/1/ – Rob W Sep 30 '12 at 09:33
  • 4
    @RobW You don't need a wrapper and you can stretch the absolutely positioned `:after` pseudo-element with *trbl* properties all set to 0; see updated fiddle: http://jsfiddle.net/JxNdT/2/ – FelipeAls Sep 30 '12 at 11:43
  • @FelipeAls Great! I didn't even consider that option. – Rob W Sep 30 '12 at 12:34
  • +1 for a creative approach and while this works perfectly in chrome under IE-8 the color still appears behind the content. If i find a solution for older browsers ill post it here. – Reahreic Nov 05 '14 at 17:59
  • @Reahreic did you find a solution? – Crashalot Jan 10 '19 at 02:51
  • 1
    Nice solution! I actually had to use z-index to make it completely work but that was specific to my situation I guess – Mike Mar 12 '20 at 16:21
4

If you need a white-transparent foreground

This is for future visitors like me who are considering adding a white-transparent foreground to an element to communicate that it's hidden / disabled for instance. You can often achieve your goal by simply lowering the opacity below 1:

.is-hidden {
    opacity: 0.5;
}
visible
<span class="is-hidden">hidden</span>
visible
Bart S
  • 1,698
  • 1
  • 16
  • 21
3

You can use this css

#yourImage
{
z-index: 1; 
}

NOTE

Set the z-index to index greater the the z-index of the element over which you are putting the image.

If you have not specified any z-index then 1 would do the work.

You can also set z-index to -1,in that case the image would always be at background!

Anirudha
  • 32,393
  • 7
  • 68
  • 89
0

A neat solution: box-sizing + padding-left, see more at css-tricks

Somewhere in your HTML:

<img id="test_replacement" src="test.png" alt="test" />

The CSS for replacing the image (on hovering)

#test_replacement {
    width: 200px; //must be the size of your image (and the replacement one)
    height: 200px; //idem
    display: block;
}
#test_replacement:hover {
    box-sizing: border-box;
    background-image: url('somewhere/other_image.png');
    padding-left: 200px; //at least the size of the width
}
nicolallias
  • 1,055
  • 2
  • 22
  • 51
0

Use an absolutely positioned <img> element:

img {
  position: absolute;
  opacity: 0.3;
  pointer-events: none;
}

iframe {
  width: 500px;
  height: 300px;
  border: 0;
}
<img src="https://i.stack.imgur.com/rET57.jpg" alt="Foreground image">

<iframe src="https://example.com/"></iframe>
Mori
  • 8,137
  • 19
  • 63
  • 91