教你用 css 寫一個擬物化圖示

TONGZ發表於2018-03-28

擬物化(Skeuomorphism)風格的圖示在iOS7釋出之前廣為流行。相當長一段時間,無論系統、網頁還是第三方應用都爭相使用擬物化的設計風格。那時候的dribbble網,各色優秀的擬物化設計作品也爭奇鬥豔、層出不窮。

下面先展示幾張優秀的擬物化設計作品,讓你們進一步瞭解這一風格,甚至愛上這個風格。大可不必站在產品的角度來較真,just欣賞它們的美,感受細節的震撼。

教你用 css 寫一個擬物化圖示
教你用 css 寫一個擬物化圖示
教你用 css 寫一個擬物化圖示
教你用 css 寫一個擬物化圖示
是不是很震撼,很精緻,那豐富的細節讓觀者不禁感嘆設計師的一絲不苟。

放兩張鄙人當年設計的作品,略顯粗糙,跟大神的作品比起來多有不足,見笑了哈哈。

教你用 css 寫一個擬物化圖示
教你用 css 寫一個擬物化圖示

好了,談正事。設計師們設計的擬物化圖示,一般兩種方式:純ps繪製,或者3D軟體建模渲染+ps調細節。但今天我要說的是如何用css寫一個擬物化圖示出來,不需要任何的圖片素材。很驚訝是不是!很驚訝是不是! 少囉嗦,先看東西。

一個掛在牆上的旋鈕
跟ps繪製出來的圖示是比不了的,有很多細節是純css程式碼沒法實現的,這沒辦法。不過沒關係,我就是通過這個練習讓大家瞭解一下這個設計風格的原理,還有,你儘可以發到朋友圈裝逼,並配上一句話“碼農能幹的事多了”。

ok,教程開始~

理論基礎

在寫程式碼之前,先說一些簡單的光影原理(不涉及到透視還有材質,追求極簡^_^),即素描的基礎:三大面和五大調。

三大面:

  • 亮面
  • 灰面
  • 暗面

五大調:

  • 高光
  • 中間調
  • 明暗交界線
  • 反光
  • 投影

不同人叫法可能不同,但本質一樣。 三大面是指一個物體在光源照射下,會出現明暗的三種狀態: 亮面——受光面; 灰面——側光面; 暗面——背光面。

五大調是指在三大面中,根據受光強弱的不同,產生更多明顯的區別: 高光——受光物體最亮的點; 中間調——高光與明暗交界線之間的區域; 明暗交界線——區分亮面與暗面的區域,不是一條真實的線,它的形狀、明暗、虛實會隨物體結構轉折發生變化; 反光——物體的背光部分受其他物體或物體所處環境的反射光影響的部分; 投影——物體本身遮擋光線後在空間中產生的暗影。

來一張圖,具象化這些理論。

教你用 css 寫一個擬物化圖示

明白了這些概念之後,我們在設計這個圖示的時候,就有理可循了。因為這個圖示結構本就不復雜,不需要做到那麼精準,該有的都有就好了。

形狀

先把形狀寫出來,這個圖示的形狀非常簡單,你可以按我的寫,也可以任意微調,先不用管顏色,什麼顏色都行。 包括牆面、底座、凹槽、旋鈕和小紅條(我也不知道叫什麼)。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .wall {
            position: relative;
            width: 1000px;
            height: 750px;
            background: #eaeaea;
        }

        .base {
            position: absolute;
            top: 50%;
            left: 50%;
            margin-left: -170px;
            margin-top: -170px;
            width: 340px;
            height: 340px;
            border-radius: 60px 60px;
            background: #fafafa;
        }

        .groove {
            position: absolute;
            top: 50%;
            left: 50%;
            margin-left: -113px;
            margin-top: -113px;
            width: 226px;
            height: 226px;
            border-radius: 50%;
            background: #dddddd;
            z-index: 50;
        }

        .knob {
            position: absolute;
            top: 50%;
            left: 50%;
            margin-left: -100px;
            margin-top: -100px;
            width: 200px;
            height: 200px;
            border-radius: 50%;
            background: #fafafa;
            z-index: 100;
        }

        .spot {
            position: absolute;
            top: 50%;
            left: 50%;
            margin-left: -4px;
            margin-top: -74px;
            width: 8px;
            height: 30px;
            border-radius: 10px;
            background: red;
            z-index: 150;
        }
    </style>
</head>

<body>
    <div class="wall"><!--牆面-->
        <div class="base"></div><!--底座-->
        <div class="groove"></div><!--凹槽-->
        <div class="knob"></div><!--旋鈕-->
        <div class="spot"></div><!--紅色指示條-->
    </div>

</body>

</html>
複製程式碼

效果如圖:

先把形狀繪製出來

顏色

這一步我們來調整一下顏色。要知道生活中的物體是沒有絕對的純色的,只要有光,勢必產生明暗,這意味著所有的顏色都有或多或少的漸變。這個圖示設計中,為了簡單易懂,我們不考慮環境光了,除了那個紅色條,其他都用黑白灰,不摻雜色相。

1.確定光源

我們規定光源為位置在正上方稍微偏左的軟光,這樣看著比較舒服的。

2.牆面

我們先給牆面設定一個徑向漸變,漸變圓心在中上方位置,圓心亮,四周相對暗。但不要有太大對比,柔和才好看。

參考色值:

background: radial-gradient(circle at 50% 20%, rgb(241, 241, 241) 10%, rgb(221, 221, 221));
複製程式碼

效果如下:

牆面顏色
由於光源位置在偏上方,所以牆面最亮的點也對應在偏上方,光源略微偏左在這裡暫且忽略,為追求背景的對稱。

3.底座

來個線性漸變,同樣上亮下暗,色差值不要太大。

參考色值:

background: linear-gradient(180deg, rgb(244, 244, 244), rgb(234, 234, 234));
複製程式碼

效果如下:

底座顏色
有點看不清楚了是吧,沒關係,先不管它,繼續。

4.凹槽和旋鈕

這兩個一起弄,對比著看,才看的準。 參考色值:

凹槽(由於物體結構這裡是凹陷的,光源被遮擋,自然比其他地方要暗)

background: linear-gradient(180deg, rgb(221, 221, 221), rgb(207, 207, 207));
複製程式碼

旋鈕(旋鈕的顏色和底座基本上是差不多的)

background: linear-gradient(180deg, rgb(250, 250, 250), rgb(234, 234, 234));
複製程式碼

效果如下:

凹槽和旋鈕顏色

5.紅色指示條

不要遇到紅色就想到那個"red"值,那種高飽和度高亮度的純紅在自然界中是不存在的,而且也不好看。我們挑一個柔和點的紅。

參考色值:

background: #ff5d5d;
複製程式碼

效果如下:

紅色指示條顏色

到目前為止,大體的顏色都調完了,但是沒有立體感。我們接下來通過調節投影、內陰影、高光等元素,使其立起來。

立體感

標題起為“立體感”是不負責任的,因為不能這麼分類,只是為了通俗易懂。

這一步驟只用了一個css3的屬性,就是box-shadow,它是非常強大的。無論是投影、高光、內陰影還是反光,都可以用它巧妙地調出來。

前方高能!

1.底座

box-shadow: 1px 4px 6px -3px rgba(0, 0, 0, 0.05), 3px 8px 20px -8px rgba(133, 133, 133, 0.9), 7px 16px 28px -8px rgb(188, 188, 188), 8px 33px 60px -12px rgb(200, 200, 200),
            1px 2px 4px 0 rgb(248, 248, 248) inset, 5px 10px 10px 0 rgba(255, 255, 255, 0.8) inset, 0px 20px 60px 0 rgba(255, 255, 255, 0.4) inset,
            -1px -2px 4px 0 #cccccc inset, -5px -10px 8px 0 rgba(144, 144, 144, 0.3) inset, 0 -20px 60px 0 #e0e0e0 inset;
複製程式碼

屬性雖然只有一個,但是需要設定非常多的值。因為太多,不具體細講了。

不過,這裡有幾個原則大家需要知道:

  1. 物體的投影也是有漸變的,離物體越近的地方,投影越暗、越實,離物體越遠,投影越淡、越虛。
  2. 亮部也是有層次的,越靠近光源的地方,越亮、越實。
  3. 底部有反光,因為牆面會反射一部分光給它。

具體每個值都是什麼效果,大家可以一個一個嘗試對照,就明白了。

來看看效果:

底座立體感
是不是很帶勁,物體一下子就跟牆面拉開了。請注意底座最低端那一層淡淡的反光(其實牆面也應該有物體給它的反光的,但由於css3沒法做出我想要的效果,就不做了,有點遺憾)。

2.凹槽

box-shadow: 2px 4px 6px 0 #c0c0c0 inset, -1px -1px 0px 0 rgba(255, 255, 255, 0.9) inset, -1px -1px 1px 0 rgba(0, 0, 0, 0.1), -8px -18px 40px 0 rgba(255, 255, 255, 0.8);
複製程式碼

這裡需要注意的是,這個結構出現了大角度的轉折,那麼在轉折處,顏色上應該突出一下。 效果如下:

凹槽立體感

3.旋鈕和紅色指示條

旋鈕

box-shadow: 1px 4px 6px -2px rgba(0, 0, 0, 0.05), 3px 10px 12px -8px rgba(0, 0, 0, 0.3), 6px 30px 30px -6px rgba(160, 160, 160, 0.5),
            1px 2px 0px 0 #fff inset, 0 -1px 1px 0 rgba(255, 255, 255, 0.4) inset;
複製程式碼

紅色指示條

box-shadow: 1px 2px 1px 0 #df3434 inset, 1px 1px 0 0 #fffdfd;
複製程式碼

在旋鈕的投影交界處,我故意將轉折處細細的邊緣線進行提亮,這是為了讓對比更加突出,增強立體感。紅條沒什麼可說的,試試就知道了。

到這,我們的擬物化圖示就完成了,再看一下最終效果:

最終效果

原始碼奉上,朋友們可以按照自己的想法進行微調,看看誰做出來的最美觀最自然。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .wall {
            position: relative;
            width: 1000px;
            height: 750px;
            background: radial-gradient(circle at 50% 20%, rgb(241, 241, 241) 10%, rgb(221, 221, 221));
        }

        .base {
            position: absolute;
            top: 50%;
            left: 50%;
            margin-left: -170px;
            margin-top: -170px;
            width: 340px;
            height: 340px;
            border-radius: 60px 60px;
            background: linear-gradient(180deg, rgb(244, 244, 244), rgb(234, 234, 234));
            box-shadow: 1px 4px 6px -3px rgba(0, 0, 0, 0.05), 3px 8px 20px -8px rgba(133, 133, 133, 0.9), 7px 16px 28px -8px rgb(188, 188, 188), 8px 33px 60px -12px rgb(200, 200, 200),
            1px 2px 4px 0 rgb(248, 248, 248) inset, 5px 10px 10px 0 rgba(255, 255, 255, 0.8) inset, 0px 20px 60px 0 rgba(255, 255, 255, 0.4) inset,
            -1px -2px 4px 0 #cccccc inset, -5px -10px 8px 0 rgba(144, 144, 144, 0.3) inset, 0 -20px 60px 0 #e0e0e0 inset;
        }

        .groove {
            position: absolute;
            top: 50%;
            left: 50%;
            margin-left: -113px;
            margin-top: -113px;
            width: 226px;
            height: 226px;
            border-radius: 50%;
            background: linear-gradient(180deg, rgb(221, 221, 221), rgb(207, 207, 207));
            box-shadow: 2px 4px 6px 0 #c0c0c0 inset, -1px -1px 0px 0 rgba(255, 255, 255, 0.9) inset, -1px -1px 1px 0 rgba(0, 0, 0, 0.1), -8px -18px 40px 0 rgba(255, 255, 255, 0.8);
            z-index: 50;
        }

        .knob {
            position: absolute;
            top: 50%;
            left: 50%;
            margin-left: -100px;
            margin-top: -100px;
            width: 200px;
            height: 200px;
            border-radius: 50%;
            background: linear-gradient(180deg, rgb(250, 250, 250), rgb(234, 234, 234));
            box-shadow: 1px 4px 6px -2px rgba(0, 0, 0, 0.05), 3px 10px 12px -8px rgba(0, 0, 0, 0.3), 6px 30px 30px -6px rgba(160, 160, 160, 0.5),
            1px 2px 0px 0 #fff inset, 0 -1px 1px 0 rgba(255, 255, 255, 0.4) inset;
            z-index: 100;
        }

        .spot {
            position: absolute;
            top: 50%;
            left: 50%;
            margin-left: -4px;
            margin-top: -74px;
            width: 8px;
            height: 30px;
            border-radius: 10px;
            background: #ff5d5d;
            box-shadow: 1px 2px 1px 0 #df3434 inset, 1px 1px 0 0 #fffdfd;
            z-index: 150;
        }
    </style>
</head>

<body>
    <div class="wall"><!--牆面-->
        <div class="base"></div><!--底座-->
        <div class="groove"></div><!--凹槽-->
        <div class="knob"></div><!--旋鈕-->
        <div class="spot"></div><!--紅色指示條-->
    </div>


</body>

</html>
複製程式碼

以上,教程部分結束,我再談談我對擬物化風格的一些看法。

擬物化設計風格在光影、材質、透視、紋理等因素上都極為講究,創作靈感通常來源於生活中的物件。一個好的擬物化設計,完美的細節會讓人吃驚。這需要考查設計師深厚的設計功底,對光影材質的理解與把握能力,對圖形的精準的構造能力,對軟體工具的熟練運用能力等。

如今,擬物化的設計風格已很少出現在大眾視野,從微軟的Metro,到蘋果的iOS7風格,再到Google的Material Design(不屬於純粹的扁平化,本文不談,感興趣的請自行搜尋),扁平化(flat)設計風格已成為數字世界的主流(當然扁平化的風格很早就有,它只是印刷出版美學在當今數字世界的一次重現而已)。在電子產品的使用者介面中,扁平化設計風格更為高效、直接,使使用者得以沉浸體驗,儘量不被眼花繚亂的其他視覺元素所干擾。但是,視覺風格是流變的,擬物化永遠不可能被淘汰,它不僅僅是一個設計趨勢,它還包括一個設計理念,即把現實生活中的物件用作視覺隱喻,使產品更便於使用。

談論擬物化和扁平化的優與劣,這個話題沒有意義,任何人都有偏好,兩者本身也各有優劣。兩種設計風格從來就不是對立面,我們可以很清楚地在扁平化設計中看到擬物化設計的精神核心所在。

最後,感謝閱讀,希望喜歡,期待你的反饋。

相關文章