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

Css

Css Problem Overview


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.

<main>
    <img src="whiteimage.png">
</main>

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;
}

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

Live demo

Css Solutions


Solution 1 - Css

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%;
}
    

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

Solution 2 - Css

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/

Solution 3 - Css

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;
}

Solution 4 - Css

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.

Solution 5 - Css

You could set the image as the div's background instead:

background-image:url(http://www.placehold.it/500x500)

jsFiddle example

Solution 6 - Css

https://stackoverflow.com/a/21415060/6235358 that's a great way to do it but we can do it in a better way using the ::after pseudo-class so you'll not have to add an empty <div> to your HTML

Solution 7 - Css

The best way to achieve this in 2020 would be to use mix blend mode on the image. use the box-shadow on the parent element of the img and use mix-blend-mode: multiply.

Solution 8 - Css

One simple fix if you are clever with your decimals is to store your content in a separate div which you then select and implement a certain number of pixels from the top.

For example, let's say your header has a height of 50px. You could begin your #content div id 53.45px from the top (or whatever height your drop shadow is) and then your shadow would appear above the images.

One issue with this is that if you are using a rather transparent shadow, the more transarent it is the more tacky it may look by implementing this css.

In practice the code would be as follows:

HTML:

  <header>
Whatever's in your header
</header>

<div id="content>
Page content
</div>

CSS:

header {
    height: 50px;
    box-shadow: 0 5px 5px rgba(0,0,0,1);
}

#content {
    top: 55px;
}

Solution 9 - Css

As Rilus mentioned we could use a pseudo class. Unfortunately this does not seem to work on an img tag for some reason however we can use a combination of inner and outer containers to achieve the affect we need.

.outer:hover .inner:after {
position: absolute;
content: '';
color: white;
display:block;
bottom: -0px;
right: -0px;
width: 100%;
height: 100%;
z-index: 11;
border: solid 10px red;
}

http://jsbin.com/kabiwidego/1/

not sure about ie 10 though as it seems to handle pseudo classes that are absolutely positioned slightly differently to most browsers.

Solution 10 - Css

Even if i'm late for the party, I had the same issue these days and worked on a solution. For me, the best solution (mobile friendly) is this one:

JSFiddle:

.image-inset-container {
  margin-bottom: 30px;
}

.image-inset-shadow {
  position: relative;
}

.image-inset-shadow img {
  border-radius: 20px;
}

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

<body>
  <h4>Reimagined Web Design</h4>
  <p>With your input and business goals in mind, we bring your brand to life through custom human-facing graphics and
    visual elements targeted toward your audience for good user experience and created in future-forward technology,
    guaranteeing a successful new web design.</p>
  <div class="image-inset-container">
    <div class="image-inset-shadow"><img src="https://upload.wikimedia.org/wikipedia/commons/d/d2/Solid_white.png" alt="img1" />
      <div class="image-shadow"></div>
    </div>
  </div>
  <p>We initiate a collaborative process where your team is involved in every step to create a frictionless and
    delightful
    experience for your customers. Our designers immerse themselves in your industry and your brand aesthetic to
    deliver
    a website that represents your business while achieving your goals for a connected future.</p>
</body>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFalconCView Question on Stackoverflow
Solution 1 - CssRillusView Answer on Stackoverflow
Solution 2 - CssRyanSView Answer on Stackoverflow
Solution 3 - CssbrouxhahaView Answer on Stackoverflow
Solution 4 - CssbencergazdaView Answer on Stackoverflow
Solution 5 - Cssj08691View Answer on Stackoverflow
Solution 6 - CssMathieu FerrarisView Answer on Stackoverflow
Solution 7 - CssPrakhar ThakurView Answer on Stackoverflow
Solution 8 - CssJames LewisView Answer on Stackoverflow
Solution 9 - CssDanielView Answer on Stackoverflow
Solution 10 - CssClaude DumontView Answer on Stackoverflow