【问题标题】:CSS filter drop-shadow does not provide smooth transitionCSS过滤器阴影不提供平滑过渡
【发布时间】:2020-06-16 00:48:41
【问题描述】:

我有自定义图像框架(在本例中为笔记本电脑),并且我希望鼠标悬停时每个框架周围都有阴影过渡。这里我使用drop-shadow 转换,但我无法通过此解决方案实现平滑的跨浏览器行为。

在 safari 中过渡根本不起作用:

在 chrome 中它的效果要好得多,但仍然不理想 - 你可以注意到在动画的最后阴影是如何跳跃的:

我该如何解决当前的解决方案,或者任何人都可以建议其他方法来实现相同的目标?我只能考虑带有 opacity / scale 动画的额外阴影图像,但这意味着对于我要添加的每一帧 - 我需要单独的阴影层图像,所以我希望社区有更好的解决方案。

UPD:不要忘记在 @Stuart 的出色解决方案之上添加 will-change: opacity 以修复 OSX Safari 渲染问题

.wrapper {
  position: relative;
  transition: filter .5s;
  display: inline-flex;
}

.content {
  top: 7px;
  bottom: 4px;
  left: 13px;
  right: 13px;
  overflow: hidden;
  position: absolute;
  background: #F4F4F5;
  z-index: 0;
}

img {
  position: relative;
  width: 100%;
  height: 100%;
}

svg {
  position: relative;
  z-index: 1;
}

.wrapper:hover {
  filter: drop-shadow(2px 2px 2px #44444444);
}
<div class="wrapper">
  <div class="content">
    <img src="https://picsum.photos/133/96" />
  </div>
  <svg width="161" height="107" viewBox="0 0 161 107" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path fill-rule="evenodd" clip-rule="evenodd" d="M15.9128 0C11.7771 0 8.42442 3.91065 8.42442 8.73469V99.3571H0.936047C0.419082 99.3571 0 99.846 0 100.449V103.724C0 105.534 1.25725 107 2.80814 107H158.192C159.743 107 161 105.534 161 103.724V100.449C161 99.846 160.581 99.3571 160.064 99.3571H152.576V8.73469C152.576 3.91065 149.223 0 145.087 0H15.9128ZM147.895 100.449V8.73469H13.1047V100.449H65.5233C65.5233 101.655 66.3614 102.633 67.3954 102.633H91.7326C92.7665 102.633 93.6047 101.655 93.6047 100.449H147.895ZM79.0959 6.55102C79.8714 6.55102 80.5 5.81778 80.5 4.91327C80.5 4.00875 79.8714 3.27551 79.0959 3.27551C78.3205 3.27551 77.6919 4.00875 77.6919 4.91327C77.6919 5.81778 78.3205 6.55102 79.0959 6.55102Z" fill="white"/>
    <path fill-rule="evenodd" clip-rule="evenodd" d="M9.36047 100.449H0.936047V103.724C0.936047 104.931 1.77421 105.908 2.80814 105.908H158.192C159.226 105.908 160.064 104.931 160.064 103.724V100.449H151.64V8.73469C151.64 4.51366 148.706 1.09184 145.087 1.09184H15.9128C12.294 1.09184 9.36047 4.51366 9.36047 8.73469V100.449ZM8.42442 8.73469C8.42442 3.91065 11.7771 0 15.9128 0H145.087C149.223 0 152.576 3.91065 152.576 8.73469V99.3571H160.064C160.581 99.3571 161 99.846 161 100.449V103.724C161 105.534 159.743 107 158.192 107H2.80814C1.25725 107 0 105.534 0 103.724V100.449C0 99.846 0.419082 99.3571 0.936047 99.3571H8.42442V8.73469ZM80.5 4.91327C80.5 5.81778 79.8714 6.55102 79.0959 6.55102C78.3205 6.55102 77.6919 5.81778 77.6919 4.91327C77.6919 4.00875 78.3205 3.27551 79.0959 3.27551C79.8714 3.27551 80.5 4.00875 80.5 4.91327Z" fill="#E8E8EA"/>
  </svg>
</div>

【问题讨论】:

    标签: css css-animations css-transitions


    【解决方案1】:

    如果您从具有相同尺寸但只是透明的初始投影开始,您将获得更平滑的过渡,因为投影已经存在:

    .wrapper {
      position: relative;
      transition: filter .5s;
      display: inline-flex;
      filter: drop-shadow(2px 2px 2px transparent);
    }
    
    .content {
      top: 7px;
      bottom: 4px;
      left: 13px;
      right: 13px;
      overflow: hidden;
      position: absolute;
      z-index: 0;
    }
    
    img {
      position: relative;
      width: 100%;
      height: 100%;
    }
    
    svg {
      position: relative;
      z-index: 1;
    }
    
    .wrapper:hover {
      filter: drop-shadow(2px 2px 2px #44444444);
    }
    <div class="wrapper">
      <div class="content">
        <img src="https://picsum.photos/133/96" />
      </div>
      <svg width="161" height="107" viewBox="0 0 161 107" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path fill-rule="evenodd" clip-rule="evenodd" d="M15.9128 0C11.7771 0 8.42442 3.91065 8.42442 8.73469V99.3571H0.936047C0.419082 99.3571 0 99.846 0 100.449V103.724C0 105.534 1.25725 107 2.80814 107H158.192C159.743 107 161 105.534 161 103.724V100.449C161 99.846 160.581 99.3571 160.064 99.3571H152.576V8.73469C152.576 3.91065 149.223 0 145.087 0H15.9128ZM147.895 100.449V8.73469H13.1047V100.449H65.5233C65.5233 101.655 66.3614 102.633 67.3954 102.633H91.7326C92.7665 102.633 93.6047 101.655 93.6047 100.449H147.895ZM79.0959 6.55102C79.8714 6.55102 80.5 5.81778 80.5 4.91327C80.5 4.00875 79.8714 3.27551 79.0959 3.27551C78.3205 3.27551 77.6919 4.00875 77.6919 4.91327C77.6919 5.81778 78.3205 6.55102 79.0959 6.55102Z" fill="white"/>
        <path fill-rule="evenodd" clip-rule="evenodd" d="M9.36047 100.449H0.936047V103.724C0.936047 104.931 1.77421 105.908 2.80814 105.908H158.192C159.226 105.908 160.064 104.931 160.064 103.724V100.449H151.64V8.73469C151.64 4.51366 148.706 1.09184 145.087 1.09184H15.9128C12.294 1.09184 9.36047 4.51366 9.36047 8.73469V100.449ZM8.42442 8.73469C8.42442 3.91065 11.7771 0 15.9128 0H145.087C149.223 0 152.576 3.91065 152.576 8.73469V99.3571H160.064C160.581 99.3571 161 99.846 161 100.449V103.724C161 105.534 159.743 107 158.192 107H2.80814C1.25725 107 0 105.534 0 103.724V100.449C0 99.846 0.419082 99.3571 0.936047 99.3571H8.42442V8.73469ZM80.5 4.91327C80.5 5.81778 79.8714 6.55102 79.0959 6.55102C78.3205 6.55102 77.6919 5.81778 77.6919 4.91327C77.6919 4.00875 78.3205 3.27551 79.0959 3.27551C79.8714 3.27551 80.5 4.00875 80.5 4.91327Z" fill="#E8E8EA"/>
      </svg>
    </div>

    【讨论】:

    • 老兄这是预渲染drop-shadow的完美主意!对于 Safari,我将在原始框架下放置带有 drop-shadow 的相同帧图像,并将转换其 opacity 而不是 filter
    • (如果您发现它是可接受的解决方案,请勾选已接受的答案:))
    • 完成,在下面发布我的解决方案以供参考。顺便说一句,你认为 will-change 应该在这里应用吗?我认为这可能会影响浏览器的性能(因为我在页面上有几十张这样的卡片并且卡片might 更改,但will 不会更改,如果用户将鼠标悬停)
    • 我可能会提前避免使用will-change - 如果你确实发现你有性能问题,那么到时候访问它。了解它是件好事,但当然不要过早使用它。
    • UPD:​​> 在来自@Stuart 的超棒解决方案之上,确实在包装器上使用投影而不是 SVG 本身 - 工作非常稳定
    【解决方案2】:

    这是我最终得到的解决方案(在 chrome/safari 中都可以正常工作),基于 @Stuart 的回答:

    在实际代码中,我不会使用重复的内联 svg,但为了简化解决方案,我只是将其复制粘贴以创建应用了 drop-shadow 的额外层,我只会更改阴影层的 transform/opacity鼠标悬停时。

    .wrapper {
      position: relative;
      transition: filter .5s;
      display: inline-flex;
    }
    
    .content {
      top: 7px;
      bottom: 4px;
      left: 13px;
      right: 13px;
      overflow: hidden;
      position: absolute;
      background: #F4F4F5;
      z-index: 0;
    }
    
    img {
      position: relative;
      width: 100%;
      height: 100%;
    }
    
    .shadow-holder {
      left: 0;
      top: 0;
      right: 0;
      bottom: 0;
      position: absolute;
      filter: drop-shadow(2px 2px 2px #44444444);
      opacity: 0;
      z-index: -1;
      transition: opacity .3s;
      transform: translateX(-1px) translateY(-1px);
    }
    
    svg {
      position: relative;
      z-index: 1;
    }
    
    .wrapper:hover .shadow-holder {
      opacity: 1;
      transform: none;
    }
    <div class="wrapper">
      <div class="content">
        <img src="https://picsum.photos/133/96" />
      </div>
      <svg width="161" height="107" viewBox="0 0 161 107" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path fill-rule="evenodd" clip-rule="evenodd" d="M15.9128 0C11.7771 0 8.42442 3.91065 8.42442 8.73469V99.3571H0.936047C0.419082 99.3571 0 99.846 0 100.449V103.724C0 105.534 1.25725 107 2.80814 107H158.192C159.743 107 161 105.534 161 103.724V100.449C161 99.846 160.581 99.3571 160.064 99.3571H152.576V8.73469C152.576 3.91065 149.223 0 145.087 0H15.9128ZM147.895 100.449V8.73469H13.1047V100.449H65.5233C65.5233 101.655 66.3614 102.633 67.3954 102.633H91.7326C92.7665 102.633 93.6047 101.655 93.6047 100.449H147.895ZM79.0959 6.55102C79.8714 6.55102 80.5 5.81778 80.5 4.91327C80.5 4.00875 79.8714 3.27551 79.0959 3.27551C78.3205 3.27551 77.6919 4.00875 77.6919 4.91327C77.6919 5.81778 78.3205 6.55102 79.0959 6.55102Z" fill="white"/>
        <path fill-rule="evenodd" clip-rule="evenodd" d="M9.36047 100.449H0.936047V103.724C0.936047 104.931 1.77421 105.908 2.80814 105.908H158.192C159.226 105.908 160.064 104.931 160.064 103.724V100.449H151.64V8.73469C151.64 4.51366 148.706 1.09184 145.087 1.09184H15.9128C12.294 1.09184 9.36047 4.51366 9.36047 8.73469V100.449ZM8.42442 8.73469C8.42442 3.91065 11.7771 0 15.9128 0H145.087C149.223 0 152.576 3.91065 152.576 8.73469V99.3571H160.064C160.581 99.3571 161 99.846 161 100.449V103.724C161 105.534 159.743 107 158.192 107H2.80814C1.25725 107 0 105.534 0 103.724V100.449C0 99.846 0.419082 99.3571 0.936047 99.3571H8.42442V8.73469ZM80.5 4.91327C80.5 5.81778 79.8714 6.55102 79.0959 6.55102C78.3205 6.55102 77.6919 5.81778 77.6919 4.91327C77.6919 4.00875 78.3205 3.27551 79.0959 3.27551C79.8714 3.27551 80.5 4.00875 80.5 4.91327Z" fill="#E8E8EA"/>
      </svg>
      <svg class="shadow-holder" width="161" height="107" viewBox="0 0 161 107" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path fill-rule="evenodd" clip-rule="evenodd" d="M15.9128 0C11.7771 0 8.42442 3.91065 8.42442 8.73469V99.3571H0.936047C0.419082 99.3571 0 99.846 0 100.449V103.724C0 105.534 1.25725 107 2.80814 107H158.192C159.743 107 161 105.534 161 103.724V100.449C161 99.846 160.581 99.3571 160.064 99.3571H152.576V8.73469C152.576 3.91065 149.223 0 145.087 0H15.9128ZM147.895 100.449V8.73469H13.1047V100.449H65.5233C65.5233 101.655 66.3614 102.633 67.3954 102.633H91.7326C92.7665 102.633 93.6047 101.655 93.6047 100.449H147.895ZM79.0959 6.55102C79.8714 6.55102 80.5 5.81778 80.5 4.91327C80.5 4.00875 79.8714 3.27551 79.0959 3.27551C78.3205 3.27551 77.6919 4.00875 77.6919 4.91327C77.6919 5.81778 78.3205 6.55102 79.0959 6.55102Z" fill="white"/>
        <path fill-rule="evenodd" clip-rule="evenodd" d="M9.36047 100.449H0.936047V103.724C0.936047 104.931 1.77421 105.908 2.80814 105.908H158.192C159.226 105.908 160.064 104.931 160.064 103.724V100.449H151.64V8.73469C151.64 4.51366 148.706 1.09184 145.087 1.09184H15.9128C12.294 1.09184 9.36047 4.51366 9.36047 8.73469V100.449ZM8.42442 8.73469C8.42442 3.91065 11.7771 0 15.9128 0H145.087C149.223 0 152.576 3.91065 152.576 8.73469V99.3571H160.064C160.581 99.3571 161 99.846 161 100.449V103.724C161 105.534 159.743 107 158.192 107H2.80814C1.25725 107 0 105.534 0 103.724V100.449C0 99.846 0.419082 99.3571 0.936047 99.3571H8.42442V8.73469ZM80.5 4.91327C80.5 5.81778 79.8714 6.55102 79.0959 6.55102C78.3205 6.55102 77.6919 5.81778 77.6919 4.91327C77.6919 4.00875 78.3205 3.27551 79.0959 3.27551C79.8714 3.27551 80.5 4.00875 80.5 4.91327Z" fill="#E8E8EA"/>
      </svg>
    </div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-22
      • 1970-01-01
      • 1970-01-01
      • 2021-09-14
      • 2016-05-03
      • 2013-07-19
      • 2016-10-07
      相关资源
      最近更新 更多