向程序學習 UI 設計

I think everybody in this country should learn how to program a computer, because it teaches you how to think.

喬布斯在《遺失的訪談》中說過「每個人都應該學習編程,因為它教會你如何思考」

前言

在上一家公司,由于 UI 妹子離職和招聘問題荤牍,不得以兼任了 UI 視覺工作。雖然之前的產(chǎn)品/交互工作和 UI 有很多交集庆冕、自己的個人項目中也會有一些 UI 設計康吵,但卻不曾獨自去設計一個完整產(chǎn)品的 UI。這一回访递,算是從「動口」到「動手」了晦嵌,好在是 B 端產(chǎn)品,對視覺美觀性要求沒那么高拷姿,相對而言統(tǒng)一性更為重要惭载。

之前作為 UI 上游環(huán)節(jié)時,我總是會給 UI 提意見跌前,要求盡量統(tǒng)一棕兼、要求考慮實現(xiàn)成本……現(xiàn)在自己做 UI 后陡舅,才發(fā)現(xiàn)滿足自己的要求挺困難的抵乓。雖然最終并沒有達到我自己滿意的程度,但這段實戰(zhàn)經(jīng)歷,確實使我對 UI 設計的統(tǒng)一性有了一些更深入的理解灾炭,尤其是將「視覺設計的感性思維」和「程序實現(xiàn)的邏輯思維」融合后茎芋,有了一個全新的視角。

我的這些理解蜈出,對于很多前端工程師來說田弥,可能屬于「常識」;但對于沒有前端經(jīng)驗的產(chǎn)品/交互/UI 設計師而言铡原,我相信是有一定幫助的偷厦。如果我自己能早幾年想明白,至少前幾個項目在 UI 的統(tǒng)一性上可以提升不少燕刻。

P.S. 本文出現(xiàn)的代碼都是 CSS 樣式代碼只泼、沒有任何復雜的邏輯。沒有代碼基礎的同學卵洗,請不要抗拒请唱,當成英文來讀就行。

如何繪制一個界面过蹂?

從設計視角來看

  • 在各類設計工具(如 Sketch)中十绑,是圖層的組合


    Sketch 圖層

從工程視角來看

  • 在 CSS 中,是各種「盒子」之間的組合
  • QT 中酷勺,是各種 Widgets 的組合

無論從哪個角度本橙,界面都是通過各種元素之間的各種組合、疊加脆诉,拼接而成勋功。

如何使繪制出的界面統(tǒng)一?

既然界面是由各種元素拼出來的库说,那要達到整體界面統(tǒng)一狂鞋,這些構成元素自然需要先統(tǒng)一。統(tǒng)一的方式潜的,就包括建立一套「控件庫」(或者說 Symbol骚揍、模板、Library啰挪、UI Kit……有許多不同的稱呼)信不,總之就是預定義一些「元素」及「元素組」,通過對有限的「元素」及「元素組」做統(tǒng)一亡呵,使得最終組合而成的界面也能在某種程度上實現(xiàn)統(tǒng)一抽活。

如果你從事過 UI 相關工作,一定或多或少了解過諸如此類的「控件庫」锰什、或是 Atomic Design 之類的設計思想下硕。

如何設計一套統(tǒng)一的「控件庫」丁逝?

前面的都是概念,這才是實際要做的事情梭姓。為了省篇幅霜幼,我僅以「按鈕」為例,講述一下我對于「統(tǒng)一控件」的理解誉尖。

階段一

這其實是我剛接觸 CSS 時的理解罪既,現(xiàn)在只是回顧一下最初那種淺顯的想法。
雖然這種理解非常淺顯铡恕,但不少軟件連這一步都沒做到琢感。
最初我以為,統(tǒng)一是:

所有的中號按鈕探熔,高度都是 24px
所有的藍色按鈕猩谊,色值都是 #0000FF
……
總之,只要最終看效果上去統(tǒng)一就行祭刚,沒有考慮其背后的實現(xiàn)牌捷,沒有「控件庫」的概念。

寫成代碼涡驮,可能會是這樣:

  • 假設有 99 個按鈕暗甥,每個按鈕都有自己的樣式,只是這 99 種樣式被強行設成了相同捉捅。
.button-1 {
  height: 24px;
  background-color: #0000FF;}
.button-2 {
  height: 24px;
  background-color: #0000FF;}
...
.button-99 {
  height: 24px;
  background-color: #0000FF;}
階段二

這是我自己動手做 UI 之前的想法撤防,要求 UI 設計師預先規(guī)劃好所有可能會出現(xiàn)按鈕(3 種尺寸、每種尺寸又有 3 種不同顏色棒口,共計 9 種按鈕)寄月。


枚舉出 9 種按鈕

這時候,我以為統(tǒng)一是:

預先枚舉出所有可能用到的標準控件无牵,加入控件庫漾肮。
程序實現(xiàn)時,統(tǒng)一使用控件庫中的標準控件茎毁。
……
雖然有了「控件庫」的概念克懊,但實現(xiàn)手段是非常粗暴的「枚舉法」

寫成代碼,可能會是這樣:

  • 假設有 99 個按鈕七蜘,所有按鈕都是只從這 9 種預設樣式中選一種
.button-normal-small {
  height: 20px;
  background-color: #FFFFFF;}
.button-normal-middle{
  height: 24px;
  background-color: #FFFFFF;}
.button-normal-large {
  height: 32px;
  background-color: #FFFFFF;}

.button-blue-small {
  height: 20px;
  background-color: #0000FF;}
.button-blue-middle{
  height: 24px;
  background-color: #0000FF;}
.button-blue-large {
  height: 32px;
  background-color: #0000FF;}

.button-red-small {
  height: 20px;
  background-color: #FF0000;}
.button-red-middle{
  height: 24px;
  background-color: #FF0000;}
.button-red-large {
  height: 32px;
  background-color: #FF0000;}

階段三

這時谭溉,我需要自己去制作控件庫了。作為一個懶人橡卤、我可不想枚舉出所有的按鈕扮念。所謂懶惰使人進步,我?guī)е鴨栴}去看了一下各大網(wǎng)站的網(wǎng)頁代碼碧库。很容易就能發(fā)現(xiàn)了規(guī)律柜与,人家是用多個 css 類疊加出來的巧勤。
對嘛!設計的時候是 3 種尺寸旅挤、3 種顏色踢关,也就是分「尺寸」和「顏色」這 2 個維度伞鲫,那實現(xiàn)的時候也應該是用維度疊加粘茄,而不是枚舉。
原來需要畫 3 × 3 = 9 個按鈕秕脓,現(xiàn)在只需要畫 3 +3 = 6 個了柒瓣!


分成 Color 和 Size 兩個維度

這時候,我以為統(tǒng)一是:

將一個控件抽象成「特定維度的疊加組合」
實現(xiàn)時吠架,通過限定這些維度來實現(xiàn)統(tǒng)一

寫成代碼芙贫,可能會是這樣:

  • 分別設「color、size」這 2 個維度的樣式傍药,使用按鈕時磺平,用這 2 個維度的疊加效果。
.button.color-normal {
  background-color: #FFFFFF;}
.button.color-blue {
  background-color: #0000FF;}
.button.color-red {
  background-color: #FF0000;}

.button.size-small{
  height: 20px;}
.button.size-middle{
  height: 24px;}
.button.size-large{
  height: 32px;}

階段四

其實對于「設計指南」而言拐辽,通常就是只到「階段三」的層次拣挪。強如 Google 的 Material Design,雖然標注很細致俱诸,但依然是屬于「階段三」這個層次菠劝。


Material Design

基于 Material Design 的這種標注,你可以嘗試解釋一下這 2 個問題:

  1. 為什么按鈕的高度是 36dp睁搭?
  2. 為什么這個按鈕的最小寬度(min-width)是 64dp赶诊?

怎么樣?這些具體的 dp 值是怎么得到的园骆,能解釋清楚嗎舔痪?至少我做不到。

之前作為 UI 的上游環(huán)節(jié)锌唾,我沒有深入去思考辙喂、停留在了這些表面的標注上。現(xiàn)在真正自己去設計一套控件庫時鸠珠,才發(fā)現(xiàn)巍耗,如果只看這些表面的細節(jié),再詳細都不夠渐排,還應當更進一步去思考得到這些結果的「推導過程」炬太,否則只是在依葫蘆畫瓢、不是真正的理解驯耻。
回想到曾經(jīng)看過的一個印象深刻的觀點「優(yōu)秀的設計亲族,每一個像素都是有據(jù)可循的」

那么炒考,什么叫做「有據(jù)可循」?

  • 按我個人的理解霎迫,就是可以用準確的邏輯規(guī)則表述斋枢、而不是憑感覺
    (其實感覺也是一種基于經(jīng)驗的規(guī)則,又名「神經(jīng)網(wǎng)絡算法」知给,只是我們自己無法理解瓤帚、表述)

什么又是準確的邏輯規(guī)則?

  • 代碼I(偽代碼也行)

順著「用準確的代碼解釋每一個像素」這個思路戈次,我又重新審視了一遍控件庫。聯(lián)想到之前做網(wǎng)站時掃過一眼的 scss(用變量定義 css 的一種語言)筒扒,終于領悟到了「階段四」:

控件的每一個屬性都應該是有推導過程的「相對值」怯邪,而不是一個憑感覺直接得到具體結果的「絕對值」。

寫成代碼花墩,可能會是這樣:

  • 所有「色值」悬秉、「像素值」都用「變量」表示。當然了冰蘑,這不是真實的例子和泌,只是為了做簡單的示例
    (關于「變量」的詳細說明,請看下一節(jié) Variables)
.button.color-normal {
  background-color: $color-normal;}
.button.color-blue {
  background-color: $color-blue;}
.button.color-red {
  background-color: $color-red;}

.button.size-small{
  height: $small;}
.button.size-middle{
  height: $middle;}
.button.size-large{
  height: $large;}

Variables(變量)

Variables懂缕,僅指 CSS 樣式層面的變量允跑。(這里我參考了 Blueprint 的命名,用了 Variables 一詞搪柑,在其他很多設計系統(tǒng)(Design System)中聋丝,也都有類似概念。比如在 Saleforce Lightning 中工碾,它被稱之為 Tokens弱睦。)

等等,之前不是說「設計指南只到階段三的層次」么渊额?怎么突然很多設計系統(tǒng)中又有類似概念了况木?

還是因為代碼。

  • 在成熟的 Design System 中旬迹,除了設計指南部分火惊,通常還有完整的開源代碼
  • 只是我之前看這些 Design System 時,未曾想到去看源代碼部分

以我們自己的按鈕舉例奔垦,一層層拆解它的「變量」吧屹耐。(為了簡化,暫不考慮按鈕的 hover椿猎、down惶岭、disable寿弱、loading 等狀態(tài))。

先來看一下絕對值

這是我參照 Material Design 做的標注(單位都是 px)


尺寸標注

對著這個按鈕按灶,再來看一下這 2 個問題:

  1. 為什么按鈕的高度是 24px症革?
  2. 為什么這個按鈕的最小寬度(min-width)是 54px?

回答這 2 個問題之前鸯旁,還需要先進一步拆解一下「按鈕」

按鈕是什么噪矛?
  • 在 Sketch 中,是「背景」上疊加「文字」
  • 在 HTML&CSS 中羡亩,是「背景容器」內塞入「文字」摩疑。

既然是要「用準確的代碼解釋每一個像素」危融,我們得用代碼的邏輯來看畏铆。CSS 盒模型 了解一下?

盒模型簡單的說就是:
按鈕的尺寸 = 容器外邊距(margin) + 容器邊框(border) + 容器內邊距(padding) + 內部文字的尺寸

我們這個按鈕對應的實際盒模型如下:


CSS 盒模型
拆解問題一

參照上圖的盒模型吉殃,可以先開始回答第一個問題

  1. 為什么按鈕的高度是 24px辞居?

解:

因為

  • 外邊距為 0;
  • 邊框為 1px蛋勺,但有上下兩條邊瓦灶,因此還要 ×2;
  • 垂直方向的內邊距為 2px,同樣有上下兩個邊距抱完,也要 ×2;
  • 文字高度為 18px;

所以贼陶,將上述值相加即可得到

  • 0 + (1px * 2) + (2px * 2) + 18px = 24px

繼續(xù)追問……

文字的高度為什么是 18px?

解:

因為

  • 使用了標準字號 12px
  • 文字行高是字號的 1.5 倍巧娱,這點應該屬于 UI 設計的常識吧碉怔?

所以,可以得到

  • 12px * 1.5 = 18px

將標準字號命名為 $font-size-m禁添,其對應的標準行高即為

  • $line-height-m = $font-size-m * 1.5

繼續(xù)追問……

為什么 border 是 1px撮胧? 垂直 padding 又是 2px?

解:

這 2 個問題老翘,如果只看按鈕本身芹啥,確實很難再解釋為什么了
但它們也不是一個孤立存在的絕對值,背后也是有特定含義的變量

1px 的 border铺峭,可以稱之為「細邊框」墓怀,即 $border-width-thin: 1px;
所有需要「細邊框」的地方都用 $border-width-thin
類似的,2px 的 padding卫键,可以稱之為「超小間距」傀履,即 $spacing-xs: 2px;
所有需要「超小間距」的情況都用 $spacing-xs

最終用「代碼公式」來回答這問題,就是

24px = ($border-width-thin * 2) + ($spacing-xs * 2) + $line-height-m

拆解問題二

再來看一下問題二

為什么這個按鈕的最小寬度(min-width)是 54px永罚?

解題思路和「問題一」類似啤呼,這里只解釋一下關鍵點:

因為我是按照最少 3 個漢字的寬度來設計的最小尺寸

  • 之前提到過卧秘,標準字號命名為 $font-size-m,是 12px
  • 換算一下官扣,12px * 3 = 36px

另外水平方向的 padding 設了 8px翅敌,再加上兩邊各 1px 的邊框

  • 36px + 8px * 2 + 1px * 2 = 54px

所以,最終用「代碼公式」來回答這問題惕蹄,就是

  • 54px = $font-size-m * 3 + ($spacing-xs * 2) + ($border-width-thin * 2)
「尺寸」總結

回顧一下幾個涉及「尺寸」的屬性蚯涮,及其對應的變量值,在代碼中如下:
(還有 border-radius 也是尺寸相關的屬性卖陵,只是不影響寬/高計算遭顶,因此未曾提及。)

min-width: $font-size-m * 3; //最小寬度
padding: $spacing-xs $spacing-m; //內邊距(前者為垂直方向泪蔫、后者為水平方向)
font-size: $font-size-m; //字號
line-height: $line-height-m;  //行高
border-width: $border-width-thin; //邊框粗細

至于 $spacing-xs棒旗、$spacing-m、$font-size-m撩荣、等等铣揉,這些「變量」的值具體應該設多少,這里暫不深入餐曹。本文的主要還想表達「所有值都用有據(jù)可循的變量表示」這種思路逛拱,至于每一個變量的具體值設定,那是另一個龐大的話題了台猴。

以下鏈接是我自己的設定方式朽合,如有興趣可供參考
https://github.com/UXplayer/GS_Guideline/blob/master/_sass/variables.scss

回到「階段四」的例子

還記得之前「階段四」的示例代碼嗎?是類似這樣不真實的饱狂、極其簡單的例子

.button.size-small{
  height: $small;}

如果按照我們實際用的按鈕來看曹步,按鈕「尺寸」維度應該如下:

  • 對于不同尺寸的按鈕,其「最小寬度嗡官、內邊距箭窜、字號、行高」都一同變化
.size-small{
    min-width: $font-size-s * 3;
    padding: 0 $spacing-s; 
    font-size: $font-size-s;
    line-height: $line-height-s;
}
.size-normal{
    min-width: $font-size-m * 3;
    padding: $spacing-xs $spacing-m;
    font-size: $font-size-m;
    line-height: $line-height-m;
}
.size-large{
    min-width: $font-size-l * 3;
    padding: $spacing-s $spacing-l;    
    font-size: $font-size-l;
    line-height: $line-height-l;
}
顏色

對于「顏色」維度衍腥,就是背景色磺樱、文字色、邊框色婆咸,這些包含色值的屬性竹捉。
在顏色的使用上,UI 設計師通常都還是會預定義好色板的尚骄。即便沒有用精確的代碼來解釋块差,如果有用 Sketch 的 Symbol,也已足夠保證統(tǒng)一性。此外憨闰,顏色在代碼實現(xiàn)上状蜗,通常也還是會枚舉出色板中的顏色作為「變量」,除非你是做開源庫鹉动,需要有一些色板的生成算法轧坎,否則不會尺寸那樣包含各種計算規(guī)則。
因此「顏色」部分就不再贅述了泽示,思路和「尺寸」部分是一樣的缸血,甚至更簡單一些。

總結

啰里啰嗦地寫了那么多械筛,其實主旨還是那一點:

控件的每一個屬性都應該是有推導過程的「相對值」捎泻,而不是一個憑感覺直接得到具體結果的「絕對值」。

一個完整的控件庫埋哟,要比按鈕復雜的多笆豁,但萬變不離其宗,無非是「推導過程」更長一些罷了定欧。
像程序學習渔呵,用工程思維怒竿、邏輯思維去重新審視你自以為熟悉的 UI 設計砍鸠,也許還會發(fā)現(xiàn)更多的新大陸。

最后

我們的項目是用 QT 開發(fā)的 PC 端產(chǎn)品耕驰,我在給開發(fā)提需求的同時爷辱,用 HTML&CSS 寫了一部分控件,可以點此查看 在線演示項目 (做了一些調整朦肘,和實際項目并不完全相同)
該演示項目的源代碼可以在 GitHub 查看饭弓。因為我這個只是簡單的 Demo 演示,比起大型開源項目的源碼媒抠,讀起來應該容易不少弟断。
我為什么要自己用代碼寫一遍?
首先趴生,批量調整樣式時阀趴,代碼比 Sketch 快得多;
其次苍匆,便于和開發(fā)溝通(給開發(fā)直接看代碼刘急,要比用自然語言解釋規(guī)則輕松多了)


參考資料
Palantir Blueprint
Saleforce Lightning
Ant Design

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市浸踩,隨后出現(xiàn)的幾起案子叔汁,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件据块,死亡現(xiàn)場離奇詭異码邻,居然都是意外死亡,警方通過查閱死者的電腦和手機另假,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門冒滩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人浪谴,你說我怎么就攤上這事开睡。” “怎么了苟耻?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵篇恒,是天一觀的道長。 經(jīng)常有香客問我凶杖,道長胁艰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任智蝠,我火速辦了婚禮靶擦,結果婚禮上存和,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好福也,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布液样。 她就那樣靜靜地躺著祟剔,像睡著了一般挚歧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上浮驳,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天悍汛,我揣著相機與錄音,去河邊找鬼至会。 笑死离咐,一個胖子當著我的面吹牛,可吹牛的內容都是我干的奉件。 我是一名探鬼主播宵蛀,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼瓶蚂!你這毒婦竟也來了糖埋?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤窃这,失蹤者是張志新(化名)和其女友劉穎瞳别,沒想到半個月后征候,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡祟敛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年疤坝,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馆铁。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡跑揉,死狀恐怖,靈堂內的尸體忽然破棺而出埠巨,到底是詐尸還是另有隱情历谍,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布辣垒,位于F島的核電站望侈,受9級特大地震影響,放射性物質發(fā)生泄漏勋桶。R本人自食惡果不足惜脱衙,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望例驹。 院中可真熱鬧捐韩,春花似錦、人聲如沸鹃锈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽仪召。三九已至寨蹋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間扔茅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工秸苗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留召娜,地道東北人。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓惊楼,卻偏偏與公主長得像玖瘸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子檀咙,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內容