Responsive Web Design

八月 15 2012 Published by under Design, Engineering

responsive layout

自從上次在 WebDev Party閃光洽分享 responsive web design 的一些技巧,我就對 responsive layout 這個主題蠻有興趣的。剛好上禮拜 EZTABLE 讀書會,主題是 responsive layout. 趁著計憶猶新,把幾個重點整理一下。

不同 mobile Strategy 的比較

如果要提供 mobile user 更好的體驗,通常大家會採取的 strategy 包括:

  • responsive web design主要是透過設計師在 CSS 上面下一些功夫,使用包括 fluid grid, media query, flexible image 等工具,讓同一份 HTML 在不同尺寸的 browser 上面,都有適合瀏覽的介面
  • separate mobile site提供不一樣的網址 (e.g. http://www.facebook.com v.s. http://m.facebook.com) 和 HTML
  • native app直接使用 device 原生的語言 (e.g. Object-C for iPhone) 開發原生的應用程式

Responsive web design 的優點:

  • 開發成本較低

    設計師可以針對既有的網頁 & CSS 做一些調整,很快就可以有一個 for mobile 的 version。當然若要調整到有很好的體驗,還是要花一些功夫,不過比起 native app 的開發成本而言,responsive web design 算是一個相對成本較低的 strategy.

  • maintain 成本較低

    雖然看到的介面不同,但在不同 device 上看到的網頁跟一般 PC desktop 上所看到的網頁,其實都是同一份 HTML. 因為只有一份 HTML,所以在 maintain 上會比有二份 HTML 的 seperate mobiel website,或是使用 device 特定語言 (e.g. Object-C, Java) 的 native app 相對容易一些

  • 可同時針對不同尺寸的 device 做處理

    responsive layout 透過使用 CSS3 media query ,可以針對不同尺寸的 device 做一些調整,不管是超寬的螢幕, tablet, smart phone 都可以 support 。

Responsive web design 的缺點:

  • performance

    因為用的是同一份 HTML,所以若是在 mobile 的情境,還是會 download 一些不需要的 resource (HTML, Image, etc) ,這對於原本網路速度就不快的 mobile device 而言是一個多餘的 overhead.

  • 未針對 mobile device 需要的流程做最佳化

    上面有提到 responsive web design 可以同時針對不同尺寸的 device,但 “可以" 不代表是 “最好" 的策略,因為在 mobile device 需要的 content 與流程可能會跟 desktop device 有所不同.

Separate mobile site v.s. Responsive web design

Google 針對 separate mobile site v.s. responsive design 整理了一張很好的比較表

(image via Mobile Websites vs Responsive Design: What’s the right solution for your business? – Google Analytics

整體而言,雖然 responsive layout 的瀏覽經驗可能會比其他 solution 差一些,就投資報酬率來說, responsive layout 其實算是一個相對投入較低,又可以很快有一個初步成果的策略。
所以這邊沒有哪一個一定比哪一個好,若是網站 mobile 的使用人數較多,或對 mobile 體驗的要求較高,可能 native app 或 separate website 會比較適合,但相對的 mobile 使用的人數並不多或要求並不高, responsive web design 就是一個值得考慮的做法。

Responsive web design 所使用的工具

Fluid grid

fluid grid 的概念主要是在 CSS 裡使用 percentage 去做設比較的設定(e.g. width: 60%;),而不使用絕對的像素 (e.g. width: 600px).
像是下面這一小段節自 twitter bootstrap 的 css

[css]
.row-fluid .span6 {
width: 48.93617020799999%; *width: 48.88297871863829%;
}
[/css]

使用 fluid grid, 可以讓頁面在放大或縮小的時候,頁面會做等比例的調整,而不會出現 scroll bar,像是下面這一張 Kayla Knight 在 smash magazine 上的 respponsive layout 教學文章 的示意圖

flexible grid
(image via Responsive Web Design: What It Is and How To Use It)

Flexible image

頁面使用了 fluid grid 之後,頁面的 layout 已經不會有固定的大小,但網頁上使用的圖片若是太大,還是有可能會讓整個 layout 爆掉。
flexible image 的概念是在 image 外面再包一層 div ,這個 div 本身是使用 percentage 去控制大小,並規定 image 的寬度最多不能超過 parent div

[css]
img { max-width: 100%; }
[/css]

不過這個做法基本上還是使用同一張圖,若 size 很大對 mobile 來說還是要 load 很久。所以網路上也有人使用 javascript 的 solution。使用 flexible image 的效果如下圖:

flexible image
(image via Responsive Web Design: What It Is and How To Use It)

Stop auto scaling

通常在 mobile phone 上面的 browser, 為了讓使用者可以看到網頁的全貌,browser 會假裝自己的螢幕寬度比實際上的寬 (e.g. iPhone 會假裝自己的寬度有 980px,), 並且自動幫網頁做 scaling 到螢幕的寬度。但若你的網頁原本就有幫 mobile 做了調整,那你在 meta 加上一個簡單的設定,告訴手機不要不需要自動做這個 auto scaling 的動作. 例如,如果你針對的是 iPhone:

[html]
<meta name="viewport" content="width=device-width; initial-scale=1.0">
[/html]

更多相關的設定可以參考:iPhone 對 viewport 的說明Android 對 webview 的說明

Media query

media query 算是 responsive web design 裡面的重頭戲。在有支援 media query 的瀏覽器中,browser 可以考慮 device 或可視範圍的 size 來 load 不一樣的 CSS. 如下面這一般摘自 twitter bootstrap 的 CSS,只會在寬度 767 px 以下的環境適用:

[css]
@media (max-width: 767px) {
// Show
.visible-phone { display: inherit !important; } // Use inherit to
restore previous behavior
// Hide
.hidden-phone { display: none !important; } // Hide everything else
.hidden-desktop { display: inherit !important; } .visible-desktop { display: none !important; }
}
[/css]

media 除了針對寬度,也可以針對高度,color, aspect-ratio, orientation 去做判斷,詳情可以參考mozilla 的文件

對 media query 有興趣的人,也可以在 mediaqueri.es 這個網站 看到更多 media query 實際 run 起來的 sample.

Reference

Summary

Responsive web design 並不見得適用於所有的網站,但考慮其開發的成本較低、maintain 的成本較低、及適用於不同尺寸 device 的優點,對 mobile 體驗的要求並沒有那麼高的網站而言, responsive layout 仍不失為一個投資報酬率蠻划算的策略。事實上,就算是只有針對 desktop 的網站,因為現在螢幕解析度也有很多不同的 size ,responsive web design 仍然是一個值得一學的技能。

(image via Alvaro Rubioc, CC license)
brooky
EZTABLE Co-Founder & CTO
2012年 08月 14 日

No responses yet

好用的 CSS 工具:Less CSS framework 介紹

十一月 18 2011 Published by under Design, Engineering

Introduction to less

這個禮拜 EZTABLE 的讀書會,主題包括了 Twitter Bootstrap 的使用, Less – The dynamic stylesheet language, 以及 Google web font 的使用心得。趁著記憶猶新,把 Less 的重點整理一下 🙂

什麼是 Less

Less 簡介

簡單來說,Less 就是讓你在網頁設計的時候,可以更方便地寫 CSS 的工具。
這裡借用一下 Less 官網的說明:

LESS extends CSS with dynamic behavior such as variables, mixins, operations and functions. LESS runs on both the client-side (IE 6+, Webkit, Firefox) and server-side, with Node.js.

也就是說,你可以透過 Less 的語法使用 variable, mixins, operatons and functions 這些工具,再透過 compile 之後,less 就可以轉成一般的 CSS,於是讓設計 CSS 這件事可以更加地有彈性。

有必要搞得那麼複雜嗎?

「為什麼設計 CSS 需要更加有彈性呢?」你問,「CSS 不是一個純文字檔寫完就好了嗎?有必要搞得還需要 complie 那麼複雜嗎?」
是的,沒錯,CSS 原本就只是一個說明樣式的純文字檔,你可能覺得用 textmate 或 dreamwever 或 notepad 寫完就好了。但可惜的是,web design 常常不是一個用過一次就丟的東西,你可能三不五時需要去修改它。

此外,就算是在剛開始設計的階段,Less 可以提供你很多方便的工具,人家寫 5 行你只要寫 1 行;人家改一個色碼要改 9 個地方(搞不好還漏掉了一個),你只要改一個地方,而且全部沒有漏,這樣一來一回,撇開效率上的差別不談,光「奇檬子」的差別就差很大了 😛

less 提供的主要功能

Variable

我個人覺得,variable 是 Less 裡面最重要的功能。舉例來說,在設計的時候,我們常常會在很多個地方使用相同的色碼 (或是用很相近的顏色)來塑造整體的感覺,例如在 h1, h2, h3, button, link hover color, …. 。

在以往設計 CSS 的時候,我們可能需要在這些 tag 的樣式裡面做各自的設定。但現在透過 variable ,我們可以在最上面宣告一個 base color, 然後在其他地方反覆使用這個 base color。這樣網站在做設計上的調整時,就可以省下很多時間。

舉例來說,下面是 Less 的寫法:
[sourcecode language="css"]
// LESS
@color: #4D926F;

#header {
color: @color;
}
h2 {
color: @color;
}
[/sourcecode]

下面是 complie 出來的 CSS:
[sourcecode language="css"]
/* Compiled CSS */

#header {
color: #4D926F;
}
h2 {
color: #4D926F;
}
[/sourcecode]

Mixins

Mixins 讓你可以重覆利用某些樣式的宣告,你可以在 A 樣式裡面 include 另一個 B class, 所有被 B class 的樣式都會被 embed 進來 A 這個樣式設定。

這個最好用的地方就是在簡化一些比較不好寫的 css, 例如 CSS3 的圓角設定,目前因為 browser 的語法尚未統一,你可以需要寫:
[sourcecode language="css"]
#header {
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
}
#footer {
border-radius: 10px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
}
[/sourcecode]

但透過 Less, 你只要寫:
[sourcecode language="css"]
.border-radius (@radius) {
border-radius: @radius;
-moz-border-radius: @radius;
-webkit-border-radius: @radius;
}

header {
.border-radius(4px);
}

.button {
.border-radius(6px);
}
[/sourcecode]

是的,正如你所看到, mixins 不只可以把某個 class include 進來,甚至可以在 include 的時候指定一個參數!!猜猜看現在如果你又需要一個 10 px 的 border-radius, 你還需要寫幾行?

1 行!

Nested Rules

CSS selector 裡面有一個重要的用法,叫做後代選擇器 (Descendant selectors)
也就是說,你可以用下面這段樣式去設定你 ID=header 這個 container 中, h1, p, p 下面的 a, p 下面的 a 的 hover 樣式各要怎麼設定:

[sourcecode language="css"]
#header h1 {
font-size: 26px;
font-weight: bold;
}
#header p {
font-size: 12px;
}
#header p a {
text-decoration: none;
}
#header p a:hover {
border-width: 1px;
}
[/sourcecode]

這樣的寫法雖然很好理解,但要對於編寫的人或是要修改的時候,就不是那麼方便了,因為你要改一下 header ,相關的樣式可能散佈在 CSS 檔的好幾個地方。但在 Less 裡面,我們可以有更好的做法:

[sourcecode language="css"]
#header { color: black;
.navigation { font-size: 12px }
.logo { width: 300px;
&:hover { text-decoration: none }
}
}
[/sourcecode]

Functions & Operations

通常在設計 button 的時候或是 border 的樣式的時候,我們常常會需要一個跟原本差不多的顏色。可能是亮一點點、暗一點點、或是鮮艷一點點(例如:當做 button 一般的顏色、hover 上去的顏色, 點下去的顏色)。而這樣的東西,傳統上我們是用 RGB 在調色盤上設好再設到 CSS 裡,但如果你對 HSB (色相、明亮度、飽和度)有那麼一點直覺的話,Less 裡面也可以讓你直接用 function 來設定,而 output 出來的 css,就會自動幫你算好相對應的 RGB 。例如:

[sourcecode language="css"]
// LESS

@base-color: #111;
@red: #842210;

#footer {
color: @base-color + #003300;
border-color: desaturate(@red, 10%);
}
[/sourcecode]

下面是轉出來的 CSS:
[sourcecode language="css"]
/* Compiled CSS */

#footer {
color: #114411;
border-color: #7d2717;
}
[/sourcecode]

Less 裡面提供的 functions 還包括:

[sourcecode language="css"]
lighten(@color, 10%); // return a color which is 10% *lighter* than @color
darken(@color, 10%); // return a color which is 10% *darker* than @color

saturate(@color, 10%); // return a color 10% *more* saturated than @color
desaturate(@color, 10%); // return a color 10% *less* saturated than @color

fadein(@color, 10%); // return a color 10% *less* transparent than @color
fadeout(@color, 10%); // return a color 10% *more* transparent than @color

spin(@color, 10); // return a color with a 10 degree larger in hue than @color
spin(@color, -10); // return a color with a 10 degree smaller hue than @color
[/sourcecode]

Less 的 compile 方法

要把 Less complie 成 CSS 兩種方法,一種是直接在 HTML 裡面 inlcude 一個 less.js 檔,然後就可以直接把 less 檔 include 進來。另一種是在製作 HTML 的時候,就先把 .less 檔 pre-compile 成 css 檔。 個人是建議用 pre-compile 的方式,一方面可以讓沒有 js 的人也可以使用,另一方面效率上也會比較好。

Using Less.js

先在 HTML 裡面 include less 檔
[sourcecode language="html"]
<link rel="stylesheet/less" type="text/css" href="styles.less">
[/sourcecode]

再把下面這個 script 放在 <head>
[sourcecode language="html"]
<script src="less.js" type="text/javascript"></script>
[/sourcecode]

Pre-compile

如果您是 developer,您可以在 command line 直接安裝 node.js + less (請參考這篇安裝 node.js + less 的詳細教學),並在 command line 執行:
[sourcecode language="bash"]
lessc styles.less > styles.css
[/sourcecode]

如果您是 designer 或是對 command line 不是那麼熟,可以考慮使用下面這個工具:
LESS.app
LESS.app
這個工具相當地方便,可以設定:

  • 要去哪裡找 less 檔
  • 要將 compile 好的 css 放在哪裡,
  • 多久自動 compile 一次
  • 要不要自動幫 CSS 做壓縮 (minified CSS)
  • 檢視 compile 有沒有什麼問題

Summary: 我覺得 Less 好用的地方

  • Easy to learn, backward compatible to CSS
  • 很好學,尤其是你原本就跟 CSS 很熟的話,大概只要花個 20 分鐘,你就可以跟 Less 一樣熟了!

  • 設計時用來調色
  • 設計的時候,常常需要反覆 try 怎樣的顏色出來比較適合。雖然知道主色調要用緣色,你可能還是會聽到設計師在那邊喃喃自語:再深一點點?再淺一點點?再帶一點黃色?再帶一點棕色?如果每試一次都要改全套的( button, order list, h1, h2, …),那設計師就算再有三頭六臂,也會 hold 不住的。

  • 利用 variable 節省時間
  • 什麼?網站又要改版??沒關係,有了 Less + variable, 網站改版不再是設計師的悲哀

  • For CSS3
  • 很多 CSS3 目前的語法還搉需要為各家瀏覽器寫上特別的語法,例如:rounded corners, box shadow, transition 等等,如果把這幾個用 LESS 先包好,是不是就省事多了呢? 😉 (from Twitter Bootstrap)

    [sourcecode language="css"]
    /*Rounded Corners*/
    .roundedCorners (@radius: 12px) {
    -moz-border-radius: @radius;
    -webkit-border-radius: @radius;
    border-radius: @radius;
    }

    /*Box Shadow*/
    .boxShadow (@hor: 3px, @vert: 2px, @blur: 5px, @shadow: #757171) {
    -webkit-box-shadow: @hor @vert @blur @shadow;
    -moz-box-shadow: @hor @vert @blur @shadow;
    box-shadow: @hor @vert @blur @shadow;
    }

    /*Transition*/
    .transition (@range: all, @time: 1s, @ease: ease-in-out) {
    -moz-transition: @range @time @ease;
    -webkit-transition: @range @time @ease;
    -o-transition: @range @time @ease;
    transition: @range @time @ease;
    }
    [/sourcecode]

一些使用 Less 的 Q & A

有了 Less 我就不用學 CSS 了嗎?

還是要學 CSS! 你還是需要會寫 CSS,Less 只是幫你省下一些功夫,大部份的樣式你還是要知道 CSS 要怎麼設,不然如果 compile 出來的

如果 Less 轉出來的 CSS 不是我要的怎麼辦?

自己來! 所有的 CSS 語法都是合法的 Less 語法,所以你可以直接把你要的 CSS 放進 Less, 不要透過 Less 來轉

如果我去改寫 Less compile 出來的 css,會不會下次重新 compile 的時候都被 override 掉?

會! 同上,所有的 CSS 語法都是合法的 Less 語法,所以你可以直接把你要的 CSS 放進 Less, 這樣 compile 出來的 CSS 就會有你想要指定的樣式

Less 的參考網址

brooky
EZTABLE Co-Founder & CTO
2011年 11月 18 日

No responses yet