Box-shadow side-effect blur not smooth. inner square in shadow

2.3k views Asked by At

I have a slider on my page to change the box-shadow values. At some high blurring values there is an unwanted box-like breaking the shadow, when it is supposed to be a smooth shadow all the way. Is there anyway to avoid this easily? Thanks for the help. P. S. I actually need it to work with 'inset' too.

enter image description here

div
{
  width:200px;
  height:200px;
  border-radius: 100px;
 background-color:blue;
 -webkit-box-shadow: 169px 129px 300px -15px rgba(0,0,0,1);
 -moz-box-shadow: 169px 129px 300px -15px rgba(0,0,0,1);
 box-shadow: 169px 129px 300px -15px rgba(0,0,0,1);
}
<div></div>

2

There are 2 answers

7
Stewartside On BEST ANSWER

For circular box-shadows the blur cannot go above the width & height of the element. The spread can though.

Since your element is 200px * 200px, the maximum for the blur value is 200px.

Have a look below at the example which doesn't go above 200px and you will see that it creates the box-shadow as expected

div {
  width: 200px;
  height: 200px;
  border-radius: 100px;
  background-color: blue;
  box-shadow: 169px 129px 200px -15px rgba(0, 0, 0, 1);
}
<div></div>

The spread value can alternatively go above the element width and height and therefore you can make bigger spreads.

div {
  width: 200px;
  height: 200px;
  border-radius: 100px;
  background-color: blue;
  box-shadow: 169px 129px 0 250px rgba(0, 0, 0, 1);
}
<div></div>

You also didn't really need the prefixes since CSS3 Box-shadows are very well supported now. CanIUse

You can read more about CSS Box shadows in the MDN Documentation

2
Persijn On

If you want to go outside its dimensions on the shape to be blurred:

The code creates a copy of the circle then colours it black and uses the filter:blur(length);

.circle {
  border-radius: 50%;
  width: 100px;
  height: 100px;
  position: relative;
}
.circle::after {
  position: absolute;
  display: block;
  content: " ";
  border-radius: 50%;
  width: 100%;
  height: 100%;
  background-color: blue;
}
.circle::before {
  position: absolute;
  display: block;
  content: " ";
  border-radius: 50%;
  width: 100%;
  height: 100%;
  background-color: black;
  top: 50%;
  left: 50%;
  -webkit-filter: blur(50px);
  filter: blur(50px);
}
<div class="circle"></div>

You can also create inset shadows this way.

How it works: 1. The initial shape is the shadow-color 2. Set overflow:hidden so nothing goes outside the shape. 3. Put a shape on top 4. Blur the shape on top

By doing this the shape under shines through creating the inner shadow effect

.circle {
  border-radius: 50%;
  width: 100px;
  height: 100px;
  position: relative;
  background-color: black;
  overflow: hidden;
}
.circle::before {
  position: absolute;
  display: block;
  content: " ";
  border-radius: 50%;
  width: calc(100%);
  height: calc(100%);
  background-color: blue;
  transform: translate(-50%, -50%);
  top: 50%;
  left: 50%;
  -webkit-filter: blur(20px);
  filter: blur(20px);
}
<div class="circle"></div>