被低估的CSS濾鏡:drop-shadow

image

首發於公衆號《前端全棧開發者》,第一時間閱讀最新文章,會優先兩天發表新文章。關注後私信回覆:大禮包,送某網精品視頻課程網盤資料,準能爲你節省很多錢!

若是你熟悉CSS,則可能瞭解 box-shadow 屬性。可是你知道有一個CSS濾鏡 drop-shadow 能夠作相似的事情嗎?就像 box-shadow 同樣,咱們能夠輸入x-offset、y-offset、模糊半徑和顏色的值。css

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

box-shadow 不一樣,它不須要 spread 參數(稍後會詳細介紹)。html

爲何drop-shadow頗有用?

若是咱們有 box-shadow ,爲何還須要 drop-shadow 呢?前端

非矩形形狀

使用 drop-shadow 可讓咱們給一個元素添加陰影,這個陰影並不對應於它的邊界框,,而是使用該元素的Alpha蒙版。例如,咱們能夠在透明的PNG或SVG徽標中添加投影。瀏覽器

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

咱們能夠比較 box-shadowdrop-shadow 的效果:性能

使用 box-shadow 爲咱們提供了一個矩形陰影,即便元素沒有背景,而 drop-shadow 則爲圖像的非透明部分建立陰影。動畫

Demospa

不管圖像是內聯在HTML中(做爲內聯SVG,仍是在 <img> 標籤中)或CSS背景圖像,這都將起做用,這意味着咱們還能夠爲漸變背景添加陰影。這些形狀是經過背景漸變建立的,並應用了 drop-shadow 濾鏡:3d

<div class="grad"></div>
<div class="grad"></div>
<div class="grad"></div>
.grad {
  width: 15rem;
  height: 15rem;
  margin: 1rem;
  background: linear-gradient(45deg, deeppink 50%, transparent 50%);
  filter: drop-shadow(0.6rem 0.6rem 1rem rgba(20, 20, 180, 0.8));
}

.grad:nth-child(2) {
  background: radial-gradient(circle at center, deeppink 50%, transparent 50%);
}

.grad:nth-child(3) {
  background: linear-gradient(45deg, transparent 60%, deeppink 60%), linear-gradient(135deg, transparent 60%, deeppink 60%);
}

效果code

https://codepen.io/michellebarker/pen/RwrXXaB

剪裁元素

若是咱們使用 clip-pathmask-image 修剪或遮罩元素,則咱們添加的任何 box-shadow 也會被修剪——所以,若是它在修剪區域以外,則將不可見。視頻

但咱們能夠經過在元素的父元素上應用 drop-shadow 濾鏡,在剪切的元素上建立一個陰影。至關酷!

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%))
}

drop-shadow 濾鏡應用於剪切形狀的父元素。

查看demo

分組元素

有時候,我須要構建由重疊元素組成的組件,這自己就須要投射陰影。

若是咱們在整個組件上添加 box-shadow ,則會留下奇怪的空白區域:

box-shadow應用於組件

若是咱們給每一個元素單獨添加一個 box-shadow,那麼每一個元素都會投下本身的陰影,這可能不是咱們想要的效果。咱們須要採用一些巧妙的CSS來隱藏那些元素重疊的陰影。

box-shadow應用於列

可是經過在整個組件上使用 drop-shadow,咱們能夠準確地在咱們想要的地方獲得陰影,而不須要求助於奇技淫巧。

box-shadow應用於組件

查看demo

多重投射陰影

這是一件有趣的事情:你可使用多個陰影以得到一些很酷的效果!查看如下演示。

<div class="parent-element">
  <div class="clipped-element"></div>
</div>
.parent-element {
  filter: drop-shadow(10rem 0 0 rgba(0, 30, 200, 0.8)) drop-shadow(-10rem 0 0 rgba(0, 30, 200, 0.8)) drop-shadow(20rem 0 0 rgba(0, 30, 200, 0.8)) drop-shadow(-20rem 0 0 rgba(0, 30, 200, 0.8));
  transition: filter 600ms;
}

.parent-element:hover {
  filter: drop-shadow(0 0 0 rgba(0, 30, 200, 0.8));
}

.clipped-element {
  width: 20rem;
  height: 20rem;
  margin: 0 auto;
  background-color: deeppink;
  clip-path: polygon(0 0, 50% 0, 100% 50%, 50% 100%, 0 100%, 50% 50%)
}

效果:

https://codepen.io/michellebarker/pen/MWygYdm

附帶說明:過渡和動畫CSS濾鏡的性能並非特別好,在實際項目中可能最好不要同時製做這麼多濾鏡的動畫。不過這個只是爲了好玩!

侷限性

如上所述, drop-shadow 不包含 spread 參數。這意味着咱們目前沒法使用它來建立輪廓效果,我認爲這將很是有用。例如,若是它被支持,咱們可使用 drop-shadow 在漸變的背景上建立一個輪廓,就像咱們在其餘元素上使用 box-shadowtext-shadow 同樣。

陷阱

即便給定相同的參數, drop-shadow 也沒法渲染與 box-shadow 徹底相同的陰影效果。我懷疑這與CSS過濾器是基於SVG過濾器原語有關。不管哪一種狀況,你均可能須要經過稍微調整 drop-shadow 值來補償差別。

瀏覽器支持

全部現代瀏覽器均支持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的 狀況,也許你能夠在你的下一個項目中使用它!

相關文章
相關標籤/搜索