【譯】不止是 box-shadow,用 css 能表現的各類影子,以及各類陷阱!

正在從事網頁設計者或者從事前端的小夥伴們,必定會有想要加陰影的時候吧。
那麼陰影會是什麼樣的表現,以及須要那些參數,你瞭解的多少呢?
複製代碼

通常要加陰影,就會想到要用 css 的 box-shadow 吧,實際上還有好幾種表現方式。暫且不說網頁,在逐年變化的設計潮流裏,怎麼處理陰影也是很重要的一個課題。css

就好比說早些時間流行的長投影,以及今年開始流行的 Neumorphism(擬態)什麼的。其獨特的影子表現手法,也是各顯千秋。html

▼ 用 css 製做的 長投影,和 擬態 的例子:前端

在這篇文章,將會介紹各類影子的技術手段,以及各個參數。git

box-shadow 基礎

用 css 添加陰影,最最最最最容易想到的就是 box-shadow 了。
複製代碼

複習 box-shadow 參數

首先看一下 box-shadow 的參數。 github

就算最基本的 box-shadow,也是能夠實現的各類效果。 chrome

/* 1. 基礎的 box-shadow */
.basic1 {
  box-shadow: 0 10px 25px 0 rgba(0, 0, 0, .5);
}
/* 2. 使用 inset 添加內陰影。圓也沒問題。 */
.basic2 {
  box-shadow: inset 0 10px 25px 0 rgba(0, 0, 0, .5);
}
/* 3. 能夠指定任意的顏色以及透明度 */
.basic3 {
  box-shadow: 0 10px 25px 0 rgba(60, 194, 235, 0.5);
}
/* 4.經過偏移量,寫出像 border 同樣的效果 */
.basic4 {
  box-shadow: 15px 15px 0px 0 rgb(60, 194, 235);
}
複製代碼

多個陰影重疊

咱們能夠寫任意個陰影,而且重疊,來看看下面的例子吧!windows

/* 1. 經過 6 層陰影重疊,實現更加真實的投影 */
.layer1 {
  box-shadow:
    0 1.9px 2.5px rgba(0, 0, 0, 0.057),
    0 5px 6.1px rgba(0, 0, 0, 0.076),
    0 10.1px 11.4px rgba(0, 0, 0, 0.086),
    0 19.2px 19.8px rgba(0, 0, 0, 0.092),
    0 38.4px 34.8px rgba(0, 0, 0, 0.1),
    0 101px 74px rgba(0, 0, 0, 0.13);
}
/* 2. 影子朝不一樣的方向,指定不一樣顏色 */
.layer2 {
  box-shadow:
    -10px 10px 25px rgba(230, 180, 15, 0.9),
    10px -10px 25px rgba(8, 131, 161, 0.9)
}
/* 3. 利用多層重疊,讓陰影看起來像不少層紙 */
.layer3 {
  box-shadow:
    0 20px 0 -10px rgb(198, 224, 231),
    0 40px 0 -20px rgb(105, 171, 209),
    0 60px 0 -30px rgb(27, 115, 165)
}
複製代碼

經過多層的陰影重疊,是一種常見的用法。就好比在 google 瀏覽器的彈窗,隨處可見。瀏覽器

非 box-shadow,僞元素模擬的陰影

box-shadow 雖然很簡單,但也有實現不了的場景。 下圖的左邊,是藍色的 box-shadow 實現的陰影。下圖右邊是僞元素實現的陰影,右邊的是否是看起來更加真實呢?svg

demo 示例🔗性能

解析僞元素模擬陰影

box-shadow 只是給加上指定顏色的 blur(模糊)效果,影子的顏色跟背景組合在一塊兒的話,看起來不太天然。 若是要實現更加真實的陰影,咱們能夠利用 css 的 filter 跟 mix-blend-mode 配合。(不要跟我談 ie,那是什麼,能夠吃嗎!)

.box::after {
  /* 經過僞元素設置相同的大小,而且在背面表示 */
  content: '';
  display: block;
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;

  /* ①添加顏色 */
  background-color: rgb(42, 159, 226);
  /* ②添加模糊*/
  filter: blur(15px);
  /* ③調整位置和大小 */
  transform: translateY(10px) scale(1.05);
  /* ④添加混合效果 */
  mix-blend-mode: multiply;
}
複製代碼

跟只有一行的 box-shadow 比起來確實麻煩了很多,可是僞元素能夠調整大小,加上任意的 filter,能夠實現更加自由的組合。 咱們來看幾個例子吧!

給漸變色或者照片加上陰影

跟 box-shadow 不一樣,僞元素能夠投影漸變圖像以及任意的圖片。這樣模糊的陰影,畫面的印象更深!

改變混合效果

出了普通的投影以外,咱們還能夠試着改變不一樣的混合效果。

上面的例子,是用 color-dodge 表象出來發光的效果,另外能夠利用 color-burn、 hard-light 等等表象出各式各樣的效果。

另外一種陰影 dorp-shadow

還有一個咱們不要忽視的是 drop-shadow。box-shadow 只可以給元素的四個邊角加上投影,但 drop-show 能夠跟實際內容結合來產生投影。實際內容是指位圖、svg 圖、文本、子元素等等,基本上全部的東西均可以。若是隻想給看到的東西、直接給其加上陰影的話,那就使用 drop-shadow 吧!

drop-shadow 跟 box-shadow 寫法不一樣之處

drop-shadow 是屬於 css 的 filter 的一種。雖然參數少了幾個,但跟 box-shadow 基本一致。

有幾個注意點:

  1. 就算跟 box-shadow 設定成一樣的值,drop-shadow 看起來會更加模糊。
  2. drop-shadow 不可使用 inset。
  3. drop-shadow 算上 x、y 的偏移量就只有 4 個參數,設定錯了會沒效果。
  4. drop-shadow 不支持 ie。雖然能夠經過(filter: progid:DXImageTransform.Microsoft.DropShadow),這裏不作介紹。

下圖是比較一樣值,box-shadow 跟 drop-shadow 的比較,若是最求設計稿跟畫面高度一致的話,能夠注意一下。

drop-shadow 能夠解決陰影重疊

接下來這個例子是 css animation 製做的 loading 效果。用旋轉着的 8 個小圓圈來模仿 windows 加載動畫的效果。

兩個示例都是給加的左側陰影、box-shadow 的表現挺差強人意的:

  • 由於給每一個元素加上了陰影,因此看起來不像是一個總體。
  • 若是加上了動畫的話,會更加的混亂。

左側是給每一個子元素加上 box-shadow 的,而右邊是給子元素的父元素加上的 drop-shadow,這是沒法避免的,這裏稍微提醒一下。

總而言之,drop-shadow 支持投影的重疊。

陰影的內幕 - 陷阱與對策

box-shadow 跟 drop-shadow,背後是瀏覽器複雜的渲染運算,所以會有不少坑,這裏,咱們再去試着跟 animation 組合,看看會有哪些坑,而且會介紹一下應對策略。

陷阱1:卡頓(Safari)

在元素 hover 狀態下加上 transition 的投影動畫,chrome、safari 表現不一樣,safari 會稍微有點卡頓。

這個現象的產生緣由,主要是由於變動了 box-shadow 的模糊半徑。雖然不可以達到徹底一致的效果,可是若是注重流暢的效果的話,能夠替換成改變顏色透明度。

/* 1. 改變模糊半徑 */
.box1{
  transition: box-shadow 2s ease-out, transform 2s ease-out;
}
.box1:hover {
  box-shadow: 0 15px 10px 5px rgb(0, 0, 0);
  transform: translateY(-10px);
}

/* 2. 只改變透明度 */
.box2{
  transition: box-shadow 2s ease-out, transform 2s ease-out;
  box-shadow: 0 15px 10px 5px rgba(0, 0, 0, 0);
}
.box2:hover {
  box-shadow: 0 15px 10px 5px rgba(0, 0, 0, 1);
  transform: translateY(-10px);
}
複製代碼

陷阱2:hover 的陰影會被溢出隱藏(Safari)

hover 的狀態下,drop-shadow 也會出問題。 溢出會被裁切掉。

在 safari 改變 drop-shadow 的話,內部會從新渲染產生了這個問題。雖然有點麻煩,可是若是實在須要的話,咱們須要給元素加上足夠空間的 padding。

.ok {
  display: inline-block;
  font-size: 0;
  /* 添加足夠空間的padding */
  padding: 100px; 
  filter: drop-shadow(0 0px 3px rgba(0, 0, 0, .9));
}
.ok:hover {
  filter: drop-shadow(0 10px 60px rgba(0, 0, 0, .9));
}
複製代碼

陷阱3: 動畫過程當中,陰影沒法顯示(Safari)

這個也是在 safari 的現象。

用三個 div 配合 transition 動畫作了一個菜單,若是給 icon 全體都加上 dorp-shadow 的話,在 safari 裏面陰影會消失。

如下是這個現象發生的條件:

  • 多個子元素加上了 transition 跟 transform。
  • 兩個以上的子元素使用了 drop-shadow。

多個陰影重疊的手法在設計中會常常出現,若是直接複製的話,說不定就達成了條件。

陷阱4: 添加了太多陰影動畫的話,瀏覽器會難消化(Chrome、Firefox)

最後一個是在 chrome、firefox 出現的陷阱。咱們試着給 100 個 div 加上陰影、配合 css 的 animation。進行下面 3 種實驗

  1. 給每一個子元素加上 box-shadow。
  2. 給每一個子元素加上 drop-shadow。
  3. 給父元素加上 drop-shadow。

可能機器個體性能不一樣,寫這片文章的時候使用的平臺是 iMac(iMac 5K, 27-inch, 2019)

demo 示例🔗

瀏覽器 每一個子元素加上 box-shadow 給每一個子元素加上 drop-shadow 給父元素加上 drop-shadow
Chrome(80) 超慢
Safari(13.1) 通常
Firefox(74)

每一個瀏覽器的傾向都不一樣。特別是 chrome 的 drop-shadow。若是給元素增長到 200 個的話,只剩 10 fps 了。

safari從一開始就用 gpu 處理渲染了,而 chrome 的話會讓 cpu 爆炸。若是是這樣的場景的話,那麼各個瀏覽器得好好確認了。不過,如今應該很難見到 box-shadow 加上 animation 這種場景了吧。

總結

這片文章介紹了 box-shadow、drop-shadow、已經僞元素配合 css filter 模擬的陰影的各類手段。特別是在使用動畫的時候,會有各類不同的效果,須要注意一小下,只要遵照這些隱藏規定的話,css 表現陰影仍是挺強的。期待您掌握 css 的陰影技術,下次在實際應用場景上發揮地更加出色。

譯者記錄

在瞭解這片文章以前,我仍是隻知道 box-shadow 能夠產生陰影,徹底沒有注意到 drop-shadow 也能夠作投影。元素模擬卻是有知道一點,可是表現的這麼出色,卻是不多見。

偶然間發現這片文章,介紹了陰影的各類手法,每一個點都很細緻的介紹到了,很是的不錯,特地花了點時間翻譯了一下,分享給你們,但願可以派的上用場,讓你們對 css 的陰影可以有更加深入的理解。

原文地址:ics.media/entry/20040…

做者:松本 ゆき

翻譯:view

相關文章
相關標籤/搜索