Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't inset box-shadow work over images?

Tags:

css

I have a container that uses inset box shadow. The container contains images and text. The inset shadow apparently does not work on images:

The problem

The white section here is the container. It contains a white image, and there is inset box shadow applied to it.

body {
  background-color: #000000;
}

main {
  position: absolute;
  bottom: 0;
  right: 0;
  width: 90%;
  height: 90%;
  background-color: #FFFFFF;
  box-shadow: inset 3px 3px 10px 0 #000000;
}
<main>
  <img src="https://upload.wikimedia.org/wikipedia/commons/d/d2/Solid_white.png">
</main>

Is there a way to make the inset box shadow overlap images?

like image 371
FalconC Avatar asked Jan 28 '14 19:01

FalconC


People also ask

Does Box shadow work on images?

Box-shadow inset will not work on image, you need to create a div and give box-shadow to that div and put image inside that div. You can also use a negative z-index on the img element, and use the box-shadow with inset value on the div element.

Why drop shadow is not working?

Found the answer! Drop shadow will work when the subject and background are on separate layers.


4 Answers

Because the shadow is part of the parent container it renders below the image. One alternative is to have a div which places a shadow overtop the image like so:

<main>
    <img src="https://upload.wikimedia.org/wikipedia/commons/d/d2/Solid_white.png" />
    <div class="shadow"></div>
</main>

CSS:

.shadow {
    position: absolute;
    width: 100%;
    height: 100%;
    box-shadow: inset 3px 3px 10px 0 #000000;
    border-radius: 20px;
    top: 0;
    left: 0;
}

Edit: I've updated the fiddle to include border radius on the shadow and on the img which solves the issue identified in the comments.

https://jsfiddle.net/WymFE/3/

like image 143
RyanS Avatar answered Oct 19 '22 06:10

RyanS


Just to chime in on this, because I was just creating something similar...

I hate polluting my markup with extra elements for the sake of styling, so the CSS solution is to use the :after pseudo element:

main::after {
  box-shadow: inset 3px 3px 10px 0 #000000;
  content: '';
  display: block;
  height: 100%;
  position: absolute;
  top: 0;
  width: 100%;
}
<main>
  <img src="https://upload.wikimedia.org/wikipedia/commons/d/d2/Solid_white.png">
</main>

It's probably too late for what you were trying to do, but is the better solution in my estimation.

like image 33
Rillus Avatar answered Oct 19 '22 07:10

Rillus


The reason it's not overlapping is because the image is inside the div, so the image is on top of it. The image is higher (closer to the user) than the div.

You can change the image to use position: relative; z-index: -1, and have the containing div use a border instead of setting background color on the body. You'll need to use box-sizing: border-box to include the border in the width of the div.

DEMO

body {
    background-color: #FFF;
}

main {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 100%;
    height: 100%;
    border: 60px solid black;
    box-shadow: inset 3px 3px 10px 0 #000000;
    box-sizing: border-box;
}

img {
    z-index:-1;
    position: relative;
}
like image 9
brouxhaha Avatar answered Oct 19 '22 08:10

brouxhaha


For those, who're using absolute-positioned, full-size :before/:after pseudo elements, consider using pointer-events: none on the pseudo-element so the original elements remain clickable.

like image 8
bencergazda Avatar answered Oct 19 '22 08:10

bencergazda