Drop-Shadow: недооцененный CSS-фильтр

Drop-Shadow: недооцененный CSS-фильтр

Если вы знакомы с CSS, вы, вероятно, знаете все о свойстве box-shadow. Но знаете ли вы, что есть CSS-фильтр drop-shadow, который делает нечто подобное? Как и box-shadow, мы можем передавать значения для x-offset, y-offset, радиуса размытия и цвета:

.my-element {
  filter: drop-shadow(0 0.2rem 0.25rem rgba(0, 0, 0, 0.2));
}

В отличие от box-shadow, он не принимает параметр распространения (подробнее об этом позже).

Чем полезна drop-shadow?

Если у нас есть box-shadow, зачем нам вообще drop-shadow?

Непрямоугольные формы

Использование drop-shadow позволяет нам добавить тень к элементу, которая не соответствует его ограничивающему прямоугольнику, но вместо этого использует альфа-маску элемента. Например, мы могли бы добавить тень к прозрачному логотипу PNG или SVG.

img {
  filter: drop-shadow(0.35rem 0.35rem 0.4rem rgba(0, 0, 0, 0.5));
}

Мы можем сравнить эффект box-shadow и drop-shadow:
Логотип розового кота с тенью коробки слева и такой же логотип с тенью справа


Использование box-shadow дает нам прямоугольную тень, даже если элемент не имеет фона, а drop-shadow создает тень от непрозрачных частей изображения.

Это будет работать независимо от того, встроено ли изображение в HTML (либо как встроенный SVG, либо в тег <img>) или как фоновое изображение CSS. Это означает, что мы также можем добавить тень к градиентному фону. Эти формы создаются с фоновыми градиентами с примененным фильтром падающей тени.

Обрезанные элементы

Если мы обрезаем или маскируем элемент с помощью clip-path или mask-image, любая добавляемая нами тень блока также будет обрезана - поэтому она будет невидимой, если находится за пределами обрезанной области.

Но мы можем создать тень на обрезанном элементе, применив фильтр тени к родительскому элементу. Довольно круто!

.parent-element {
	filter: drop-shadow(0.35rem 0.35rem 0.4rem rgba(0, 0, 0, 0.5));
}

.clipped-element {
	clip-path: polygon(0 0, 50% 0, 100% 50%, 50% 100%, 0 100%, , 50% 50%))
}



Сгруппированные элементы

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

Если мы добавим box-shadow ко всему компоненту, у нас останутся странные пустые места:

Если мы добавим box-shadow к каждому элементу по отдельности, то каждый будет отбрасывать свою собственную тень, что может оказаться нежелательным эффектом. Чтобы скрыть тени в местах наложения элементов, нам нужно использовать хитрый CSS.

Но, используя drop-shadow для всего компонента, мы получаем тень именно там, где нам нужно, не прибегая к хитростям:



Множественные тени

Вот что интересно: вы можете использовать несколько drop-shadow для получения довольно интересных эффектов!

(Боковое примечание: переход и анимация фильтров CSS не особенно эффективны, и, вероятно, лучше избегать одновременной анимации такого количества фильтров в реальных проектах. Но это просто для удовольствия!)

Ограничения

Как упоминалось выше, drop-shadow не включает параметр распространения. Это означает, что в настоящее время мы не можем использовать его для создания эффекта контура, что, я думаю, было бы действительно полезно. Например, если бы это поддерживалось, мы могли бы использовать drop-shadow для создания контура на градиентном фоне так же, как мы можем с box-shadow или text-shadow на других элементах.

Подводные камни

drop-shadow не отображает точно такой же эффект тени, как box-shadow, даже при тех же параметрах. box-shadow имеет тенденцию давать более темную и тяжелую тень, чем drop-shadow, когда используются те же значения. Я подозреваю, что это как-то связано с фильтрами CSS, основанными на примитивах фильтров SVG. В любом случае вам, скорее всего, придется компенсировать разницу, немного скорректировав значения тени.

Поддержка браузеров

CSS-фильтры (включая drop-shadow) поддерживаются во всех современных браузерах. Я склонен использовать его как прогрессивное усовершенствование, без необходимости обходного пути для старых браузеров, поскольку обычно это не то, что могло бы существенно повлиять на взаимодействие с пользователем. Но если вам действительно нужно предоставить совместимость со старыми браузерами, вы можете сделать это с помощью запроса функции с резервным вариантом box-shadow:

.my-element > * {
  box-shadow: 0 0.2rem 0.25rem rgba(0, 0, 0, 0.2);
}

@supports (filter: drop-shadow(0 0.2rem 0.25rem rgba(0, 0, 0, 0.2))) {
  .my-element {
    filter: drop-shadow(0 0.2rem 0.25rem rgba(0, 0, 0, 0.2));
  }

  .my-element > * {
    box-shadow: none;
  }
}

Вывод

Несмотря на отличную поддержку, drop-shadow используется крайне редко. Я надеюсь, что в этой статье освещены некоторые случаи, когда вы могли бы сэкономить на работе с box-shadow - возможно, вы могли бы использовать его в своем следующем проекте!

Комментарии

Чтобы оставить комментарии небходимо войти с помощью своего аккаунта.
Пока никто не оставил комментарий. Станьте первым.