Why is the CSS drop-shadow filter offset on Chrome but not Firefox? - Stack Overflow

I have been trying to use the CSS drop-shadow() filter to apply an outline on transparent images and te

I have been trying to use the CSS drop-shadow() filter to apply an outline on transparent images and text, like so:

img {
  filter: drop-shadow(1px 1px 0 black)
    drop-shadow(-1px 1px 0 black)
    drop-shadow(1px -1px 0 black)
    drop-shadow(-1px -1px 0 black);
}
<img src="/images/navigation/statue2/frame_00_delay-0.1s.gif">

I have been trying to use the CSS drop-shadow() filter to apply an outline on transparent images and text, like so:

img {
  filter: drop-shadow(1px 1px 0 black)
    drop-shadow(-1px 1px 0 black)
    drop-shadow(1px -1px 0 black)
    drop-shadow(-1px -1px 0 black);
}
<img src="https://sen.fish/images/navigation/statue2/frame_00_delay-0.1s.gif">

This works as I expected on Firefox/Gecko:

But on Chromium browsers, this is the result that I get:

Is there a way to prevent the filter from becoming offset on Chromium browsers? And is there a reason why they render differently? (i.e., this is a bug right?)

Share Improve this question edited Mar 13 at 15:26 fish asked Mar 13 at 0:32 fishfish 1942 silver badges12 bronze badges 5
  • 1 What version of Chrome are you using? I can't reproduce on sable 134.0.6998.89 nor on Canary 136.0.7065.0 both on macOS, with or without hardware acceleration. – Kaiido Commented Mar 13 at 0:54
  • I'm using Chrome 134.0.6998.89 on Windows 11, hardware acceleration doesn't make a difference for me either. – fish Commented Mar 13 at 0:57
  • 2 @Kaiido I've identified where it's going wrong! Chrome does this behavior because my default display scale is 125%! Using a display scale 100% makes it behave like Firefox. – fish Commented Mar 13 at 1:12
  • 1 Windows default scaling? Don't know why they do this... But anyway, that makes for a good self-answer. You can edit your previous answer with this info and even keep your workaround. That might be useful for future readers. – Kaiido Commented Mar 13 at 1:24
  • 1 I only tried the workaround on my display so I feel like it wouldn't be useful since it would break if your display scale was set to anything other than 125%. I will add an answer about how the rendering was affected by the display scale. – fish Commented Mar 13 at 1:35
Add a comment  | 

1 Answer 1

Reset to default 3

Why this occurs, and how to fix it

This occurs because Chrome doesn't handle non-integer pixel values well for the drop-shadow() function (surely a bug, right? It looks like they round down when they should round up). While I didn't use non-integer values for the drop-shadow example above, my display scale was set to 125%—the default for my laptop. I've been able to reproduce this effect at 100% display scale by using a drop-shadow of 1.5px:

img {
  filter: drop-shadow(1.5px 1.5px 0 black)
    drop-shadow(-1.5px 1.5px 0 black)
    drop-shadow(1.5px -1.5px 0 black)
    drop-shadow(-1.5px -1.5px 0 black);
}
<img src="https://sen.fish/images/navigation/statue2/frame_00_delay-0.1s.gif">

The above snippet will work fine in Firefox, but will have the ugly offset effect on Chromium browsers. You can bypass this by using your own svg filters, which don't render this way in Chrome, like so (thanks to this answer for the idea):

img {
  filter: url(#dropshadow-one)
    url(#dropshadow-two)
    url(#dropshadow-three)
    url(#dropshadow-four);
}
<svg x="0px" y="0px" width="0px" height="0px" width="0px" viewbox="0 0 200 200">
  <defs>
    <filter id="dropshadow-one" height="130%">
      <feGaussianBlur in="SourceAlpha" stdDeviation="1" /> <!-- stdDeviation is how much to blur -->
      <feOffset dx="1" dy="1" result="offset" /> <!-- how much to offset -->
      <feComponentTransfer>
        <feFuncA type="linear" slope="1" /> <!-- slope is the opacity of the shadow -->
      </feComponentTransfer>
      <feMerge>
        <feMergeNode /> <!-- this contains the offset blurred image -->
        <feMergeNode in="SourceGraphic" /> <!-- this contains the element that the filter is applied to -->
      </feMerge>
    </filter>
    <filter id="dropshadow-two" height="130%">
      <feGaussianBlur in="SourceAlpha" stdDeviation="1" />
      <feOffset dx="-1" dy="1" />
      <feComponentTransfer>
        <feFuncA type="linear" slope="1" />
      </feComponentTransfer>
      <feMerge>
        <feMergeNode />
        <feMergeNode in="SourceGraphic" />
      </feMerge>
    </filter>
    <filter id="dropshadow-three" height="130%">
      <feGaussianBlur in="SourceAlpha" stdDeviation="1" />
      <feOffset dx="1" dy="-1" />
      <feComponentTransfer>
        <feFuncA type="linear" slope="1" />
      </feComponentTransfer>
      <feMerge>
        <feMergeNode />
        <feMergeNode in="SourceGraphic" />
      </feMerge>
    </filter>
    <filter id="dropshadow-four" height="130%">
      <feGaussianBlur in="SourceAlpha" stdDeviation="1" />
      <feOffset dx="-1" dy="-1" />
      <feComponentTransfer>
        <feFuncA type="linear" slope="1" />
      </feComponentTransfer>
      <feMerge>
        <feMergeNode />
        <feMergeNode in="SourceGraphic" />
      </feMerge>
    </filter>
  </defs>
</svg>

<img src="https://sen.fish/images/navigation/statue2/frame_00_delay-0.1s.gif">

Old answers

Old answer two

I still don't really know, but I've identified that it's related to my display scale (in Windows: Settings > System > Display > Scale), which I have set to 125%—the default for my laptop. At a display scale of 100% there is parity between Firefox and Chrome, but at other display scales (and actually, I think it's most pronounced at 125%), Chrome has this unusual rendering of the drop-shadow() function.

I've kept the original answer I wrote here, but it's probably not useful since it only applies to my specific display scale of 125%.

Old answer one

While drafting this question, I played around on codepen and found this solution to fix the rendering for Chromium browsers by using two separate filters:

img {
  filter: drop-shadow(1px 1px 0 black)
drop-shadow(0px 1px 0 black)
drop-shadow(1px -1px 0 black)
drop-shadow(-1px 0px 0 black);
}

@-moz-document url-prefix() {
  img {
filter: drop-shadow(1px 1px 0 black)
  drop-shadow(-1px 1px 0 black)
  drop-shadow(1px -1px 0 black)
  drop-shadow(-1px -1px 0 black);
  }
}
<img src="https://sen.fish/images/navigation/statue2/frame_00_delay-0.1s.gif">

Firefox vs Chrome:

However, I still don't understand why this rendering difference occurs, outside of the obvious—that they implement svg rendering differently.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744724325a4590091.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信