How to create a CSS shadow that applies transparency to an element behind it

62 Views Asked by At

I'm trying to have an element project a shadow / blurred edge onto an element behind it, causing the latter to "dissolve", without impacting the background. Hopefully the following images can better illustrate my problem.

This is what I was able to get: Shadow clearly stands out from the background

While this is the result I'm trying to achieve: Shadow works sort of like a mask on the element behind

This is the code I used to make the first image:

html {
  height: 500px;
  background: url('https://picsum.photos/id/106/2592/1728');
}

#back {
  position: absolute;
  top: 100px;
  left: 100px;
  width: 200px;
  height: 200px;
  background-color: #FFBBBB;
}

#front {
  position: absolute;
  top: 200px;
  left: 200px;
  width: 200px;
  height: 200px;
  background-color: #BBFFBB;
  box-shadow: -30px -30px 15px #85ACC9;
}
<div id="back"></div>
<div id="front"></div>

I should note that the position of the green square may not be fixed in a real setting and its "shadow" should follow it around.

1

There are 1 best solutions below

2
MHD Alaa Alhaj On

While you can't have a box-shadow: linear-gradient(#9198E5, #E66465), you could take advantage of Pseudo-elements to have the same gradient, mixing it with filter: blur(10px) to have the same effect of shadow. Note that #back must have z-index: -2 to sit behind the pseudo-element.

Also, note that because of the different sizes between html height and #front height the gradient spread color will be different, so to make sure that it will have an effect like dissolve I used Chrome DevTools to pick the hex colors. The first color was picked from the bottom of the green rectangle and the second color was picked from the top of the green rectangle.

html {
  height: 500px;
  background: linear-gradient(#9198E5, #E66465);
}

#back {
  position: absolute;
  top: 100px;
  left: 100px;
  width: 200px;
  height: 200px;
  background-color: #FFBBBB;
  z-index: -2;
}

#front {
  position: absolute;
  display: block;
  top: 200px;
  left: 200px;
  width: 200px;
  height: 200px;
  background-color: #BBFFBB;
}

#front:before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(#ac87bc, #d17085);
  filter: blur(10px);
  transform: translate(-40px, -40px);
  z-index: -1;
}
<div id="back"></div>
<div id="front"></div>