Как добавить эффект свечения (тень) для SVG при наведении

27.04.2020

Простой пример, как добавить эффект свечения для svg-элемента с помощью добавления тени.

Итак, у нас есть такой svg-файл с градиентом:

Первым делом, кидаем файл в SVGOMG для того, чтобы оптимизировать и убрать все лишнее из кода svg. По итогу получим такой вычищенный код svg:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 222.4 109">
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="0" y1="54.5" x2="222.392" y2="54.5">
  <stop offset="0" stop-color="#40b99d"/>
  <stop offset="1" stop-color="#2ed8de"/>
</linearGradient>
<path d="M208.2 105c.6-.1 1.1-.6 1.1-1.2V51.3c0-.7-.5-1.2-1.2-1.2h-64.4V3.6c0-2-1.6-3.6-3.6-3.6H26.4c-2 0-3.6 1.6-3.6 3.6v70.6c0 2 1.6 3.6 3.6 3.6h54.7v.5c0 9.5-22.1 8.3-23 8.5H58c-.1 0-.1.1-.1.2v1c0 .1 0 .1.1.2h50.4c.1 0 .1-.1.1-.2v-1c0-.1 0-.1-.1-.2h-.1c-.9-.2-23 .7-23-8.5v-.5H124v26.1c0 .6.5 1.1 1.1 1.2H111v1.9s1.7 2.1 6.7 2.1H215.8c5 0 6.7-2.1 6.7-2.1v-2h-14.3zM83.3.8c.6 0 1 .5 1 1 0 .6-.5 1-1 1-.6 0-1-.5-1-1 0-.6.5-1 1-1zM124 51.3v8.6H30.9v-9H124v.4zm-95.1-2.4v13H124v1.9H26.5V3.6h113.6v46.5h-1.8v-1.2H28.9zm177 52.3h-78.5V53.1h78.5v48.1zm-58.5-34.7h-18v22.3h18V66.5zm-2 20.3h-14V68.5h14v18.3zM1.7 102.6h4.5V75.9H1.7v26.7zm2-24.7h.5v22.7h-.5V77.9zM7 82.7h10v-6.8H7v6.8zm2-4.8h6v2.8H9v-2.8zm-2 24.7h5V97H7v5.6zM9 99h1v1.7H9V99zm-2-2.9h5V83.5H7v12.6zm2-10.6h1v8.6H9v-8.6zm3.7 17.1H17V83.5h-4.3v19.1zm2-17.1h.3v15.1h-.3V85.5zm166.9 4.3h-52.2v9.7h52.2v-9.7zm-2 7.7h-48.2v-5.7h48.2v5.7zM28.9 47.1h30.6V5.5H28.9v41.6zm2-39.6h26.6v37.6H30.9V7.5zm31 39.6h31.2V35.7H61.9v11.4zm2-9.4h27.2v7.4H63.9v-7.4zm31.5 9.4h14.7V35.7H95.4v11.4zm2-9.4h10.7v7.4H97.4v-7.4zm41-18.6h-25.8v28h25.8v-28zm-2 26h-21.8v-24h21.8v24zm12 43.7h33.2v-12h-33.2v12zm2-10h29.2v8h-29.2v-8zm-2-3h33.2v-9.3h-33.2v9.3zm2-7.3h29.2v5.3h-29.2v-5.3zM16 69.3H2.7c-1.5 0-2.7 1.2-2.7 2.8v34.2c0 1.5 1.2 2.7 2.7 2.7H16c1.5 0 2.7-1.2 2.7-2.7V72.1c0-1.5-1.2-2.8-2.7-2.8zm1.6 34.2c0 .1-.1.2-.2.2H1.3c-.1 0-.2-.1-.2-.2V75c0-.1.1-.2.2-.2h16.2c.1 0 .2.1.2.2v28.5zm92.5-84.4H61.9v14.8h48.2V19.1zm-2 12.8H63.9V21.1h44.2v10.8zm95.8 23h-74.5v10.6h74.5V54.9zm-2 8.6h-70.5v-6.6h70.5v6.6zm-63.5-58H61.9v11.8h76.5V5.5zm-2 9.8H63.9V7.5h72.5v7.8zm46.2 84.2h21.3v-33h-21.3v33zm2-31h17.3v29h-17.3v-29z" fill="url(#a)"/></svg>

Необходимо, чтобы при наведении на него, он как бы подсвечивался, делать это буду с помощью тени.

На выходе получился такой код, который я буду использовать в HTML:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="-15 -15 252.4 139">

  <defs>
    <filter id="shadow" class="shadow">
      <feDropShadow dx="0" dy="0" stdDeviation="6" flood-color="#00c6a0" />
    </filter>

    <linearGradient id="a" gradientUnits="userSpaceOnUse" x1="0" y1="54.5" x2="222.392" y2="54.5">
      <stop offset="0" stop-color="#40b99d" />
      <stop offset="1" stop-color="#2ed8de" />
    </linearGradient>
  </defs>

  <path d="M208.2 105c.6-.1 1.1-.6 1.1-1.2V51.3c0-.7-.5-1.2-1.2-1.2h-64.4V3.6c0-2-1.6-3.6-3.6-3.6H26.4c-2 0-3.6 1.6-3.6 3.6v70.6c0 2 1.6 3.6 3.6 3.6h54.7v.5c0 9.5-22.1 8.3-23 8.5H58c-.1 0-.1.1-.1.2v1c0 .1 0 .1.1.2h50.4c.1 0 .1-.1.1-.2v-1c0-.1 0-.1-.1-.2h-.1c-.9-.2-23 .7-23-8.5v-.5H124v26.1c0 .6.5 1.1 1.1 1.2H111v1.9s1.7 2.1 6.7 2.1H215.8c5 0 6.7-2.1 6.7-2.1v-2h-14.3zM83.3.8c.6 0 1 .5 1 1 0 .6-.5 1-1 1-.6 0-1-.5-1-1 0-.6.5-1 1-1zM124 51.3v8.6H30.9v-9H124v.4zm-95.1-2.4v13H124v1.9H26.5V3.6h113.6v46.5h-1.8v-1.2H28.9zm177 52.3h-78.5V53.1h78.5v48.1zm-58.5-34.7h-18v22.3h18V66.5zm-2 20.3h-14V68.5h14v18.3zM1.7 102.6h4.5V75.9H1.7v26.7zm2-24.7h.5v22.7h-.5V77.9zM7 82.7h10v-6.8H7v6.8zm2-4.8h6v2.8H9v-2.8zm-2 24.7h5V97H7v5.6zM9 99h1v1.7H9V99zm-2-2.9h5V83.5H7v12.6zm2-10.6h1v8.6H9v-8.6zm3.7 17.1H17V83.5h-4.3v19.1zm2-17.1h.3v15.1h-.3V85.5zm166.9 4.3h-52.2v9.7h52.2v-9.7zm-2 7.7h-48.2v-5.7h48.2v5.7zM28.9 47.1h30.6V5.5H28.9v41.6zm2-39.6h26.6v37.6H30.9V7.5zm31 39.6h31.2V35.7H61.9v11.4zm2-9.4h27.2v7.4H63.9v-7.4zm31.5 9.4h14.7V35.7H95.4v11.4zm2-9.4h10.7v7.4H97.4v-7.4zm41-18.6h-25.8v28h25.8v-28zm-2 26h-21.8v-24h21.8v24zm12 43.7h33.2v-12h-33.2v12zm2-10h29.2v8h-29.2v-8zm-2-3h33.2v-9.3h-33.2v9.3zm2-7.3h29.2v5.3h-29.2v-5.3zM16 69.3H2.7c-1.5 0-2.7 1.2-2.7 2.8v34.2c0 1.5 1.2 2.7 2.7 2.7H16c1.5 0 2.7-1.2 2.7-2.7V72.1c0-1.5-1.2-2.8-2.7-2.8zm1.6 34.2c0 .1-.1.2-.2.2H1.3c-.1 0-.2-.1-.2-.2V75c0-.1.1-.2.2-.2h16.2c.1 0 .2.1.2.2v28.5zm92.5-84.4H61.9v14.8h48.2V19.1zm-2 12.8H63.9V21.1h44.2v10.8zm95.8 23h-74.5v10.6h74.5V54.9zm-2 8.6h-70.5v-6.6h70.5v6.6zm-63.5-58H61.9v11.8h76.5V5.5zm-2 9.8H63.9V7.5h72.5v7.8zm46.2 84.2h21.3v-33h-21.3v33zm2-31h17.3v29h-17.3v-29z" fill="url(#a)" filter="url(#shadow)" />
</svg>

И такие правила в CSS для эффекта сияния при наведении:

svg defs stop{
  transition: .4s;
}
svg:hover defs stop{
  stop-color: #b6fff1;
}
svg defs feDropShadow {
  transition: .4s;
  flood-color: transparent;
}
svg:hover feDropShadow{
  flood-color: #06deb5;
}

Немного разберу важные моменты, а рабочий пример будет ниже.

Для эффекта тени добавили фильтр

<filter id="shadow" class="shadow">
  <feDropShadow dx="0" dy="0" stdDeviation="6" flood-color="#00c6a0" />
</filter>

И вызвали этот фильтр в элементе path:

<path ... filter="url(#shadow)" />

Для плавного эффекта свечения задали фильтру прозрачный цвет, а при наведении нужный цвет #06deb5 – это цвет нашей тени:

svg defs feDropShadow {
  transition: .4s;
  flood-color: transparent;
}
svg:hover feDropShadow{
  flood-color: #06deb5;
}

Думаю, есть и другие способы для плавного появления тени, но именно этот сработал как нужно.

Так же в стилях добавили правило для смены цвета нашего svg-элемента. Если просто указать fill="b6fff1" вместо fill="url(#a)", то плавного изменения цвета не будет, поэтому в стилях зададим для градиента stop-color: #b6fff1; – на самом деле, я без понятия, насколько это правильно, но это работает:

svg defs stop{
  transition: .4s;
}
svg:hover defs stop{
  stop-color: #b6fff1;
}

Важные нюансы:

  • если подключать svg как файл, а не добавлением кода в HTML, то правила CSS не будут влиять на код svg.
  • если на странице используется несколько одинаковых иконок со схожими фильтрами, тогда у каждой иконки должны быть уникальные ID фильтров и событий, иначе срабатывать эффекты будут на всех элементах при наведении на самый первый в коде элемент:
<filter id="shadow" ...
<linearGradient id="a" ...
...
... fill="url(#a)" filter="url(#shadow)" />
  • или для аналогичных элементов с одинаковыми инструкциями внутри <defs> можно применять уже однажды объявленные инструкции. Элемент <defs> содержит идентифицируемые инструкции, которые могут быть использованы несколько раз по всему документу; он устанавливает определение, которое не будет отображаться, пока оно не будет вызвано. Еще раз. Можно один раз у первого элемента указать инструкции для градиента и теней внутри <defs>, а у остальных элементов просто вызвать нужные эффекты через идентификатор … fill="url(#a)" filter="url(#shadow)" />.
  • простой совет – сначала добавить нужные эффекты, а затем уже привязать их к событию hover

Пример работы анимированной подсвечивающейся svg – просто наведите курсор на иконку:

See the Pen Glowing Gradient Button Animation Effects on Hover Using Html and CSS by Denis (@deniscreative) on CodePen.dark

Подробнее про svg градиенты здесь – https://www.sitepoint.com/getting-started-svg-gradients/

Полезная инфа:

Оставить комментарий