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:
- Set the image to the
background
property of the div. - 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).
- 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).
- 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
What's the Trick to Inspect Popout/Dropdown Menu Style with Firebug
@Font-Face Custom Icon Font Only Showing Unicodes
Google Chrome Developer Tools - CSS File Showing as an Image Resource
Antialiased Text in Firefox After CSS Rotation
CSS 3 Gradients for Styling Svg Elements
Is Opacity Is Inherited in a Div
How to Set a Value of 'Inherit' to a CSS Custom Property
CSS White-Space:Nowrap Horizontal Scroll Bug
How to Create a Dynamic Grid Using Vue
MVC CSS Not Rendering in Visual Studio When Debugging
Disable CSS Stylesheet for a Specific Action in Symfony
Crop an Image to Square Using Percentages and Max Widths
CSS Url() Not Recognized in Internet Explorer 10