Rendering CSS3 Inset Shadow with an Image

Rendering CSS3 inset shadow with an image

Box-shadow is just above the background on the stacking order when using inset. Therefore, any image you have inside the div will cover the shadow.

Per the W3C Specs

In terms of stacking contexts and the
painting order, the outer shadows of
an element are drawn immediately below
the background of that element, and
the inner shadows of an element are
drawn immediately above the background
of that element (below the borders and
border image, if any).

In other words, Chrome and Opera are doing it correctly (FTR, FF 3.6.13 does the same thing as Opera).

If you want the shadow to overlap the image, you have a few different options, depending on your needs:

  1. Set the image to the background property of the div.
  2. Absolutely position a div over the one with the image, make it the same size, and put the shadow there (not really recommended, as it's convoluted and adds non-semantic markup).
  3. Make sure the backgrounds of the images are transparent (this will allow the shadow to show through, but non-transparent pixels will still cover the shadow).
  4. Consider using border-image and gradient, instead. (This one is also a little convoluted, but puts the gradient in the border itself, and you can fade to transparent using RGBA.)

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

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/

Problems with CSS Box-Shadow:Inset on image

In the end I found the' Overlay & Inset Method', the second of Jordon Dobsons's techniques to be the most effective and least reliant on negative z-indexes:

/* Border & Vignette Setup */

figure{
position: relative;
display: block;
line-height: 0;
width: 500px;
height: 333px;
margin-bottom: 2em;
border: 1em solid #fff;
-webkit-box-shadow: 0 .1em .3em rgba(0,0,0,.25);
-moz-box-shadow: 0 .1em .3em rgba(0,0,0,.25);
}

figure::before{
content: "";
position: absolute;
top: -1em;
bottom: -1em;
left: -1em;
right: -1em;

}

figure::before,
figure img{
outline: 1px solid #ccc;
}

figure.vignette img{
z-index: 1;
position: relative;
display: block;
width: 100%;
height: 100%;

}

/* Overlay & Inset Method */

figure.overlay.inset::after{

/* Mozilla Settings */
-moz-box-shadow: inset 0 0 150px rgba(0,0,0,.75);

/* Webkit Setting */
-webkit-box-shadow: inset 0 0 150px rgba(0,0,0,.75);
}

(jsFiddle demo using original layout)

How to add inner shadow to image in CSS

Add display: block to the img elements to remove the padding below. This is because img elements are rendered inline by default. All inline-block elements has some vertical-align value by default- reset it either by applying vertical-align: top or reset the display property by applying display: block. See demo below:

/* apply a natural box layout model to all elements */*, *:before, *:after {  -moz-box-sizing: border-box;  -webkit-box-sizing: border-box;  box-sizing: border-box;}
.shadow { display: inline-block; position: relative; -webkit-border-radius: 50%; -moz-border-radius: 50%; border-radius: 50%; -moz-box-shadow: rgba(0, 0, 0, 0.8) 3px 3px 10px inset; -webkit-box-shadow: rgba(0, 0, 0, 0.8) 3px 3px 10px inset; box-shadow: rgba(0, 0, 0, 0.8) 3px 3px 10px inset; -webkit-transition: box-shadow 0.2s ease-in; -moz-transition: box-shadow 0.2s ease-in; transition: box-shadow 0.2s ease-in;}.shadow:hover { -moz-box-shadow: rgba(0, 0, 0, 0.8) 5px 5px 55px inset; -webkit-box-shadow: rgba(0, 0, 0, 0.8) 5px 5px 55px inset; box-shadow: rgba(0, 0, 0, 0.8) 5px 5px 55px inset;}.shadow img { max-width: 100%; position: relative; z-index: -1; -webkit-border-radius: 50%; -moz-border-radius: 50%; border-radius: 50%; display: block; /* ADDED */}
.column { float: left; width: 25%; padding: 0 15px;}
<div class="column">  <div class="shadow">    <img src="http://fillmurray.com/250/250">  </div>  </div>
<div class="column"> <div class="shadow"> <img src="http://fillmurray.com/370/370"> </div></div>
<div class="column"> <div class="shadow"> <img src="http://fillmurray.com/200/200"> </div></div>
<div class="column"> <div class="shadow"> <img src="http://fillmurray.com/400/400"> </div></div>

BoxShadow: inset on img tag

CSS3 inset shadows don’t work on images, but there is a workaround,

Check here: http://bavotasan.com/2011/adding-inset-shadow-to-image-css3/

How to render inset box-shadow over the child element's background?

As you mentioned container2 to show the intended structure, I removed that from my code. here is how I do this task with the help of position CSS property:

.container {
display: flex;
}

.container1 {
box-shadow: inset 0 0 30px red;
width: 200px;
height: 200px;
position: relative;
}


.inner {
width: 200px;
height: 100px;
background: yellow;
position: absolute;
z-index: -1;
top: 0;
left: 0;
}

.text {
width: 200px;
height: 100px;
position: absolute;
top: 50%;
left: 0;
}

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">

<div class="container1">
<div class="inner"></div>
<div class="text">Some text</div>
</div>
<!--
<div class="container2">
<div class="inner"></div>
<div class="text">Some text</div>
</div>
-->
</div>
</body>
</html>

Whole site inner shadow overlay?

I was able to fix it by using this code,

.overlay{
position: fixed;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
overflow-y:scroll;
box-shadow: inset 0 0 100px #000;
}

And my HTML looks like,

<body>
<div class="overlay">
Stuff...
</div>
</body>

The only problem with that is that without the position:fixed it would not be 100%, only 100% of the viewport. Making it fixed however, made it cover everything but you couldn't scroll, so adding overflow-y:scroll allows it to then scroll.



Related Topics



Leave a reply



Submit