CSS фильтр drop-shadow не обеспечивает плавного перехода - PullRequest
0 голосов
/ 26 мая 2020

У меня есть пользовательские рамки изображений (в данном случае ноутбук), и я хочу, чтобы вокруг каждой появлялся переход тени при наведении курсора мыши. Здесь я использую переход drop-shadow , но я не могу добиться плавного кроссбраузерного поведения с этим решением.

В сафари переход вообще не работает:

enter image description here

В chrome он работает намного лучше, но все же не идеально - вы можете заметить, как тень скачет в самом конце анимации:

enter image description here

Как мне исправить текущее решение, или, может быть, кто-нибудь может посоветовать другие подходы для достижения того же? Я могу думать только о дополнительном теневом изображении с анимацией opacity / scale, но это означает, что для каждого кадра, который я хочу добавить, мне понадобится отдельное изображение для теневого слоя, поэтому я надеюсь, что у сообщества есть лучшие решения.

UPD: не забудьте добавить will-change: opacity поверх потрясающего решения от @Stuart, чтобы исправить проблемы с рендерингом 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>

Ответы [ 2 ]

2 голосов
/ 26 мая 2020

Если вы начнете с начальной тени того же размера, но просто прозрачной, вы получите гораздо более плавный переход, потому что выпадающая тень уже существует:

.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>
1 голос
/ 26 мая 2020

Вот решение, с которым я столкнулся (отлично работает как в 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>
...