Last update:
CSS shadows under adjacent elements
The problem
Having several elements close to each other and applying a box shadow on them may cause the shadow from an element to render on top of the previous element, like this:
See the Pen Overlapping shadows
1
This is caused by the fact that the shadow of an element is tied to it and nothing can be inserted between a box and its shadow. This, of course, may be perfectly fine in some cases, but let’s focus on changing this behavior – we would like to have shadows under all element.
Shadows under elements
To overcome this, we’ll have to somehow separate the element and its shadow. Fortunately, CSS makes it possible with pseudoelements. We’ll render the shadow in a pseudoelement (could be either before
or after
, it doesn’t matter) and assign a negative z-index
to it. It is important that the element itself does not have a z-index
property (or has it set to auto):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
.withShadow { position: relative; } .withShadow:before { content: ""; position: absolute; top: 0; bottom: 0; left: 0; right: 0; z-index: -1; box-shadow: -5px 5px 20px 5px #000; } |
The :before
pseudoelement is a box that has the same size as the original element, but thanks to the lower z-index, it is rendered below other elements.
See the Pen Fixed overlapping shadows1
“All right, but why can’t we set any z-index to the original element?” – you may ask. The reason is that setting the z-index creates a new local static context and elements from these contexts can’t be interwoven.
Why would I need it?
For example, to create complex interfaces with drop shadows:
See the Pen Complex layout1
Throw in some border radius to create even more crazy stuff:
See the Pen Large box vertices1
Browser support?
I tested it in IE >=9, latest Chrome and Firefox on Windows and I didn’t spot any problems. Older IEs don’t support box-shadow, so nope.
Hey, I just wanted to let you know that you were a huge help! I was using some pseudo-material design with an interactive box, with multiple buttons, making up the bottom. Thanks to this post, I was able to fix the shadowing on it!
I’m glad I could help!
I found this post to be very informative and helpful. I will have to recommend you to my friends. I am very thankful to you for giving this post.
Wow! the first one codepen is a very simple and really awesome solution! it costs me the whole working day before . decided to look up in google and founf yours!!
really helpful) thanks a lot!
and i have more interesting task: to make outer-rounded corners inbetween.. right where i put stars
_________________
| ___ ____ |
| ( * ) ( * ) |
|__| |__| |__|
hope you understood what i mean..)
Anyway I’ll fork your codepen and try to find easy solution. you inspired me. thanks a lot)
Thanks so much for this. Worked like a charm. Very useful info. Bookmarked for future in case I forget!
Dzięki wielkie. Męczyłem się właśnie z pewnym menu z przyciskami podbitym cieniami, kombinowałem z z-indexami i cały czas fiasko. Ten artykuł bardzo pomógł.
I am trying to add animation for the element, I forked your playground but it did not work.
Do you have any idea?
https://codepen.io/simongcc/pen/LqKGBM
Thanks a lot! 🙂
Hey this is suuuper helpful and I have come back to use this guide twice now. Very nice!
Thanks for this, it’s been a huge help with my latest small project on CodePen using Neumorphism! Still a work in progress but check it out if you want 🙂 https://codepen.io/gavinsykesuk/full/dyoXPzg
Thanks🤘
You sir are a life saver and a genius!
Thanks 3000!
Just in case this catches anyone else, be aware that your pseudo element will be on top of the main element and so to be on the safe side, you might need to add pointer-events: none e.g.
.withShadow:before {
content: “”;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: -1;
box-shadow: -5px 5px 20px 5px #000;
pointer-events: none;
}
You’re a fucking genius… Thank you!!
You just saved my day. Thanks!!!