8

Is there a way to not apply multiple drop shadows on top of each other? I am trying to use drop shadow to simulate stroke around an element. I needed to use drop shadow because I needed it to work when we had masks or images with transparent spots in it and I couldn't find another way to accomplish the same thing. The other alternative of using a background color didn't work for png images with transparency.

The problem is that when I define a drop shadow for the left and top sides for example, instead of making a nice overlap it actually applies extra drop shadow to the element where there was overlap. This ends up with flat edges instead of rounded ones like they should have been. Note that while this is a rounded image, we allow users to define their own masks and upload png's so it could be just about any shape.

Here is a jsfiddle example of the problem: https://jsfiddle.net/a67fqne2/17/

The code itself:

<div style="width: 391.6px; height: 369.6px; left: 239.6px; top: 28.9px; position: absolute; cursor: default; z-index: 52;">
  <div class="imageOuterStyleWrapper">
    <div class="imageMiddleStyleWrapper" style="filter: drop-shadow(rgb(139, 69, 19) 19.6px 0px 0px) drop-shadow(rgb(139, 69, 19) 0px 19.6px 0px) drop-shadow(rgb(139, 69, 19) -19.6px 0px 0px) drop-shadow(rgb(139, 69, 19) 0px -19.6px 0px); width: calc(100% - 39.16px); height: calc(100% - 39.16px); padding: 19.58px;">
      <div class="imageInnerStyleWrapper" style="clip-path: url(&quot;#Mask-2&quot;);"><img style="width: 100%; height: 133.083%; left: 0%; top: -16.5415%;" src="https://plicimgstaging-d6d.kxcdn.com?url=https%3A%2F%2Fplic-staging.s3.amazonaws.com%2Fphotos%2F4dbf8644-0751-4e9f-afaf-f5c4a00f6bae%2Foriginal%2FAbdulKarim-Naeemah-01195-00007.JPG%3FX-Amz-Algorithm%3DAWS4-HMAC-SHA256%26X-Amz-Credential%3DAKIAIZ3GLWGI2FROIRRA%252F20180712%252Fus-east-1%252Fs3%252Faws4_request%26X-Amz-Date%3D20180712T165503Z%26X-Amz-SignedHeaders%3DHost%26X-Amz-Expires%3D604800%26X-Amz-Signature%3Dd32c01d8dd7f82206b5f15028fc90a1ff6d5aadd71738648d8e477799e27816b&amp;op=resize,rotate&amp;deg=auto&amp;mode=clip&amp;filter=bilinear&amp;q=90&amp;w=450&amp;plic-ref=plic-books-dev&amp;sig=4ee24d37aa0356fe61c9500d370ca81944338fe5"></div>
    </div>
  </div>
</div>

<svg width="0" height="0" id="globalMaskDefinitions">
  <defs>
    <clipPath id="Mask-2" clipPathUnits="objectBoundingBox">
      <circle x="0" y="0" width="1" height="1" cx=".5px" cy=".5px" r=".5px"/>
    </clipPath>
  </defs>
</svg>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Floss
  • 637
  • 4
  • 16
  • what is the intended result? it's seems logical to me what you are having – Temani Afif Jul 12 '18 at 18:47
  • The intended result would be to have an even rounded stroke around the image just like the image itself is. – Floss Jul 12 '18 at 20:39
  • May be using SVG filters ? take a look here https://stackoverflow.com/q/22486039/1926369 – vals Jul 17 '18 at 12:57
  • It seems that there is another parameter to the drop shadow function which is the spread but sadly this is not working in Webkit based browsers... However, would this property be a viable solution to your problem ? Maybe we can figure out a way to emulate it – Thomas Milan Jul 17 '18 at 13:03
  • While reading the description makes me think it should, I tried in FF and Edge and it didn't appear to work there either. Not sure if I was doing it wrong or what but I don't think *anything* renders the spread property right now. – Floss Jul 17 '18 at 22:18

1 Answers1

4

The issue is related to the shape which is a circle in this case so stacking all these drop-shadow with different positions will not keep a circle shape.

Here is a better illustration of the issue if you change the colors:

div,
img {
  width: 100%;
  height: 100%;
  box-sizing: content-box;
}

.imageOuterStyleWrapper {
  width: 391.6px;
  height: 369.6px;
}

.imageMiddleStyleWrapper {
  filter: drop-shadow(red 19.6px 0px 0px) 
          drop-shadow(blue 0px 19.6px 0px) 
          drop-shadow(green -19.6px 0px 0px) 
          drop-shadow(yellow 0px -19.6px 0px);
  width: calc(100% - 39.16px);
  height: calc(100% - 39.16px);
  padding: 19.58px;
}
.imageInnerStyleWrapper {
  clip-path: url("#Mask-2");
}
<div class="imageOuterStyleWrapper">
  <div class="imageMiddleStyleWrapper">
    <div class="imageInnerStyleWrapper" style=""><img src="http://wiesmann.codiferes.net/share/bitmaps/test_pattern.svg"></div>
  </div>



  <svg width="0" height="0">
  <defs>
    <clipPath id="Mask-2" clipPathUnits="objectBoundingBox">
      <circle x="0" y="0" width="1" height="1" cx=".5px" cy=".5px" r=".5px"/>
    </clipPath>
  </defs>
</svg>

But if the shape was square you won't have this issue and it will work perfectly:

div,
img {
  width: 100%;
  height: 100%;
  box-sizing: content-box;
}

.imageOuterStyleWrapper {
  width: 391.6px;
  height: 369.6px;
}

.imageMiddleStyleWrapper {
  filter: drop-shadow(red 19.6px 0px 0px) 
          drop-shadow(blue 0px 19.6px 0px) 
          drop-shadow(green -19.6px 0px 0px) 
          drop-shadow(yellow 0px -19.6px 0px);
  width: calc(100% - 39.16px);
  height: calc(100% - 39.16px);
  padding: 19.58px;
}
<div class="imageOuterStyleWrapper">
  <div class="imageMiddleStyleWrapper">
    <div class="imageInnerStyleWrapper" style=""><img src="http://wiesmann.codiferes.net/share/bitmaps/test_pattern.svg"></div>
  </div>

An idea of fix would be to use SVG and rely on stroke to obtain what you want:

<svg width="200" height="200">
  <defs>
  <pattern id="img" patternUnits="userSpaceOnUse" width="200" height="200">
    <image  xlink:href="http://wiesmann.codiferes.net/share/bitmaps/test_pattern.svg" x="0" y="0" width="200" height="200" />
  </pattern>
  </defs>
  <circle fill="url(#img)" cx="100px" cy="100px" r="80px" stroke="rgb(139, 69, 19)" stroke-width="10"/>
</svg>

I used a circle here but you can easily use any kind of shape:

<svg width="200" height="200">
  <defs>
  <pattern id="img" patternUnits="userSpaceOnUse" width="200" height="200">
    <image  xlink:href="http://wiesmann.codiferes.net/share/bitmaps/test_pattern.svg" x="0" y="0" width="200" height="200" />
  </pattern>
  </defs>>
  <polygon points="190,10 60,100 160,190" fill="url(#img)" stroke="rgb(139, 69, 19)" stroke-width="10" />
</svg>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415