響應式網頁設計基礎:靈活性
在過去的一年里,如果你不是住在深山里,就一定知道響應式網頁設計,它已經成為當今的主流。響應式設計是Ethan Marcotte提出的,概念很簡單:使網站的頁面布局能夠根據不同設備和分辨率進行自動調整。
當我第一次了解到它時,我就立即被迷住了--特別是media queries,我馬上就用到我自己的個人兼職網站上。我甚至寫了一篇文章介紹《如何使用CSS3 Media Queries響應不同設備》(強烈建議在讀這篇文章之前讀一下)。
在第一次嘗試使用media queries后,我很快意識到我忽略了一個響應式設計的重點: 靈活性。
挑戰固定寬度
我的個人兼職網站使用了固定寬度的設計,所有的width, margin和padding都使用了固定的像素值。 我一般都會這樣寫網站,因為對我來說它更簡單,更快速。
但當我試圖在我的固定寬度的網站上應用media queries的時候,那些簡單和快速的優勢全部都消失了。為什么?因為對于固定寬度的設計,我需要非常細致的定義media queries并在CSS文件中調整每個單獨的像素值,基本上,我需要為每一種可能的分辨率都設計一個全新的布局,繁瑣!慢!!還不好玩!?。?nbsp;
我有幸聽了Marcotte先生在《In Control 2011》的演講,他討論了響應式設計的理論和最佳實踐,諸如fluid grid(流體網格)實現方式。
流動且靈活的公式
流動式布局是靈活的。由于width,margin和padding(甚至字體和圖像)使用了百分比和em(相對長度單位),因此頁面布局會隨著瀏覽器的窗口變化而變化。隨著分辨率的改變,布局會成比例地進行調整,實現過程中不需要用到任何media query。
這對于實現響應式網頁設計來說簡直太美妙了。如果我有一個基于比例值的布局,流動式的網格將替我完成大部分繁重的工作。我的media query將不再需要包含那些覆蓋其他分辨率的所有width, margin和padding的樣式定義。
但是也有一點讓我感到頭疼,計算流動式網格的比例寬度需要用到一些數學知識,我數學不太好…
幸運的是, Ethan 提供了一個很簡單(即便對我來說)的公式來計算比例寬度:
目標寬度÷上下文寬度=結果(比例寬度)
這個公式用子元素的像素寬度(目標寬度)除以它父元素的像素寬度(上下文寬度),得到的結果就是這個子元素的比例寬度。
圖1 實例:目標寬度(300px)和上下文寬度(960)像素
在圖1中,例如,深灰色區域寬度為300px,包含在寬度為960px的淺灰色區域中.這里,960像素區域是上下文元素,300像素區域是目標元素,所以我們的數學公式是: 300 ÷ 960 = 0.3125
0.3125這個結果需要變成瀏覽器可識別的數值, 因此需要轉化成一個比例值, 將小數點右移兩位,變成31.25% 即可。然后在CSS中,將元素的寬度設定為這個比例值:
- aside{
- background-color:#ccc;
- float:left;
- width:31.25%;
- }
測試一下
公式雖然看起來很簡單,但我知道必須在實際的網站中檢驗一下才行。幸運的是,我最近加入了EE播客,正在重新設計那個網站。當我的搭檔給我她的 PS 設計文件時,我就決定將它打造成靈活布局的網站。
比例寬度
我首先記錄下所有元素的像素寬度。(在排版設計事,我們沒有嚴格遵循網格布局,這也是我建議的做法)正如你在圖2中看到的。整體寬度為940像素,Logo,主持人介紹和分享鏈接都有它們各自的像素寬度。
圖2 主頁和頂部導航元素的像素寬度
按照 Ethan 的公式,整體寬度940px就是我的上下文寬度,根據它就可以確定所有元素的比例寬度.
Logo: 240 ÷ 940 = .255319148
主持人介紹: 436 ÷ 940 = .463829787
分享鏈接: 90 ÷ 940 = .09574468
隨后我將這些浮點值轉換成百分比值,運用到我的CSS中:
- #logo a{
- width:25.5319148%;/*240px/940px*/
- }
- #hosts{
- width:46.3829787%;/*436px/940px*/
- }
- #push{
- width:9.574468%;/*90px/940px*/
- }
我沒有對這些百分比值進行四舍五入,而是直接運用在CSS中。我也從來沒有遇到過任何瀏覽器對這樣精度的百分比值識別錯誤的情況(包括IE)。
同時,我為每一個百分比值都注釋了計算它所用到的目標寬度和上下文寬度,這對于今后的開發來說是非常重要的參考。
確保你的上下文寬度是正確的
只要你的數學計算是正確的,那么將寬度值轉化為比例值的過程就是很簡單的,或者,更具體地說,只要你的上下文寬度是對的,那么你得到的比例值也就是正確的.
實戰中, 我通過計算得到的比例值很少會出錯,除非我將上下文寬度搞錯了。
像圖3中標示,主持人信息是一個包含<dt>, <dd>, <a>等元素的定義列表<dl>,這些元素的寬度值各不相同.
圖3 <dl>的寬度
剛開始計算的時候,我先用960像素作為我的上下文寬度,因此<dt>的寬度比例為: 116 ÷ 960 = .120833333
但是這個比例值(12.0833333%)不是我要的正確尺寸.直到我意識到我的上下文寬度是不同的,我才得到了正確的比例值.
對于<dt>來說,它的上下文元素實際是它的父元素<dl>,寬度為436像素。因此我改變了一下參數,并計算出了我需要的百分比: 116 ÷ 436 = .266055045
如果你計算的比例寬度有任何問題,請先檢查一下選定的上下文寬度是否正確,這會幫你省不少事。
成比例的字號
我將ee-podcast.com變得更加“靈活”的第二步是使用比例字號,它和比例寬度的道理是相同的:將固定的像素值變成比例值,字體的比例值使用em進行計算.
要計算比例em,使用相同的公式(目標寬度 ÷上下文寬度 = 結果)即可,字體的上下文寬度就是它基本字號,通常在body元素中定義:
- body {
- font: 100%/1.5 "Open Sans",Arial,Helvetica,sans-serif;
- }
大多現代瀏覽器的基本字號是16px,如果你設定的比例字號是100%,字號同樣也是16px.
現在,我們來考慮一下主持人名字的字號,在版式設計時設定的是12px,使用公式12÷16=.75就得到了它的em值。這個浮點數不用轉換成百分比值就能直接在CSS中使用:
- #hosts dd{
- font-size:.75em;/*12px/16px*/
- }
成比例的padding和margin
對于padding和margin來說,那個神奇公式同樣有效. 讓我們考慮一下主持人信息當中,右margin被設定為20像素的<dt>元素(圖3).為了得到這個margin的比例值,我使用了和計算比例寬度相同的公式: 20 ÷ 436 = .04587159
將小數點右移兩位,得到的百分比值可用到CSS中:
- #hosts dt{
- margin-right:4.5871559%;/*20px/436px*/
- width:26.6055045%;/*116px/436px*/
- }
對于padding的計算來說也是一樣。
圖4 主區域的橫向padding
ee-podcast.com的主區域(如圖4所示)的寬度為940px,同時左右各有40px的橫向padding。我使用目標寬度(40px)除以上下文寬度(940px)得到它們的比例寬度:
- header,footer,.wrap {
- padding-right:4.25531%;/*40px/940px*/
- padding-left:4.25531%;/*40px/940px*/
- width:79.3%;
- }
#p#
特例
這個公式對于橫向padding比例寬度的計算有一個特例:對于padding而言,上下文元素永遠都是這個元素本身,無論父元素的寬度是多少。
例如圖5所示的分享鏈接,文字左側均有25像素的橫向padding來放圖標.
圖5 padding的上下文寬度
計算此padding的比例值時,應將這個元素本身的寬度(90px)作為上下文寬度,而不是父元素的寬度940px.(圖2)
25 ÷ 90 = .277777777
因此padding的百分比值設定為:
- #push li a {
- padding-left: 27.7777777%; /* 25px / 90px */
- }
縱向值
到目前為止,我們已經嚴謹地計算了左右的水平值,但是我們在x軸和y軸方向都會設定padding和margin,這就意味著,上下文寬度應該依據水平或垂直方向而變化。
正如你之前看到的那計算,水平方向的百分比值,都是以父元素的寬度作為上下文寬度的(padding是除外)。與此同時,縱向em值是以基本字體大小作為上下文值的。
如果你還記得成比例的字號的計算那一部分內容,我們為EE-podcast.com設定的基本字體大小是16px. 所以,如果我想指定縱向的margin和padding,上下文高度值就是16px. 此外,縱向值應該用em表示,不是百分比 –和成比例的字號的單位一樣。
這個網站的<header>和<footer>都有縱向的padding:<header>有20px的頂部padding,<footer>有20px的底部padding。(見圖4)
要確定這些padding比例值,我將16px作為上下文高度值(也就是基本字體的大小),并使用相同的公式進行計算: 20 ÷ 16 = 1.25
請記住,垂直方向上的比例值應該以em為單位。也就是說可以在CSS中直接使用浮點值,不用轉換成百分比:
- header,footer, .wrap{
- padding:1.25em 4.25531%;/*TB-20px/16px|RL-40px/940px*/
- width:79.3%;
- }
這里,我將橫向和縱向的padding值都簡寫了,修改了一些注釋的內容,以便為今后的開發提供能多參考。
- padding:1.25em 4.25531%;/*TB-20px/16px|RL-40px/940px*/
在這些注釋中,我將頂部和底部的值都用TB- 前綴進行標識,左右的值用RL-前綴。這僅僅試是幫我記錄這些比例值是如何計算的。你同樣可以使用自己熟悉的格式或者語法,強烈建議你花些時間去記錄他們。
成比例的高度
在開發當中,我通常不會指定高度值。但是在EE Podcast網站中需要做很多高度的設定,比如,<header>的高度設定為148像素。
為了得到一個成比例的高度值,我用和計算水平值一樣的方法:上下文高度是基本字體的字號,因此<header>的高度為:
148 ÷ 16 = 9.25
我把結果用em做單位加到CSS中:
- header{
- height: 9.25em;/*148px/16px*/
- padding:.4375em 4.25531% 0; /*T-7px/16px|RL-40px/940px*/
- }
靈活的圖片
EE Podcast網站沒有太多的內置圖片,只有一些背景圖片。目前我還沒決定對這些圖片做什么設置,因此也沒有什么可以向你展示的技術流程。
我唯一能做的就是向你分享一些我正在參考的網站,它們幫我決定是否有必要在我們的網站上使用靈活的圖片布局。
·對于背景圖片來說,我更關注background-size property是否會派上用場。對內置圖片來說,
·max-width approach有著不錯的瀏覽器支持,可以用在溢出旁邊。
獨立工作流
我們已經討論了如何使ee-podcast.com的頁面布局變得更加“靈活”。我應該說明一下這是個個人項目,因此會在時間允許的情況下來完成它。因此,我實現網站靈活布局的過程是一個迭代的過程。從轉換固定寬度開始,慢慢使他能夠響應不同的分辨率,整個過程花費了4個月的時間(包括那些和數學作斗爭的煩躁不安的時間)。
最終我完成了一個獨立的工作流
1.我首先直接利用PS設計稿完成了一個固定寬度的站點
2.把所有寬度變為百分比,除了主容器的寬度,設置為固定的940像素
3.把所有字體單位變成比例字號em
4.把所有的margin和padding變成百分比,然后把水平margin和padding變成單位為em的值
5.最終我將940像素變成一個百分比
為什么用這個流程?主要是因為,作為一個應用靈活布局的新手,我希望首先確保自己有一個使用指定像素值的核心的布局(并且在所有瀏覽器上都能很好地顯示)。我的邏輯是,我可以一邊測試,一邊慢慢地使設計百分比化,但是總能知道基本版式(固定寬度版本)的樣子。
另外,這個網站會在我完成這個流程之前上線。因此,我將它拆分成可管理的模塊,以便在不影響基本功能的前提下在本地測試新功能,在確保這些功能達到預期之后發布它們。
我不打算繼續使用這樣的工作流了,因為它太費時間,在下一次靈活布局的嘗試中,我決定在開始的時候就使用百分比。
但是這種工作流的確給我教會了我很多東西:你可以在同一個布局中同時使用固定尺寸和百分比尺寸而不會引發任何問題(前提是你的數學公式是正確的)。如果你覺得使用百分比值有點兒困難,可以使用我嘗試的這種方法:從固定的像素值開始,慢慢替換成百分比值。
接下來要做什么?.
即使靈活式的布局解決了大量不同分辨率的自適應問題,ee-podcast.com仍然需要media queries。也就是說,靈活和流動的布局只是響應式網頁設計的一部分。
以圖6為例,這張圖展示了ee-podcast.com在一個24英寸桌面(1910 x 1200的分辨率)的靈活布局。這里,每個元素都是成比例的,但是仍然可以調整一些細節使得瀏覽體驗變得更好,比如使Logo和主持人信息之間的距離變得小一點。
圖6 1910 x 1200 分辨率
同樣,圖7中的行文字長度在這個分辨率下變得不適于閱讀。
圖7 1910 x 1200分辨率下的行長度
在稍小的分辨率下,會出現其他的問題.圖8是網站在iPad上(水平方向)1024 x 768分辨率下的樣式。比例縮放對自適應起到了一定作用,但是出現了浮動內容的顯示錯誤和需要重新對齊的問題,以及其他的小問題。正如你所看到的,主持人信息跑到到了Logo下面,谷歌日歷和.ics下載鏈接也出現了相似的問題。
圖8 1024 x 768 垂直方向
在iPhone(垂直方向,320 × 480分辨率下)上,正如你在圖9中看到的,比例縮放呈現出了極其糟糕的閱讀體驗。
圖9 320 x 480分辨率
這些問題可以通過media queries來解決,media queries允許你為不同的設備和分辨率提供不同的樣式。(要是你沒留意我之前的建議,可以去讀 《如何使用CSS3 Media Queries 應對不同設備》)。同時,我也為我的main container設定了最大寬度和最小寬度值,這能讓網站在那些我沒空去定義media query樣式的屏幕分辨率下保持適于閱讀的樣式。
- header,footer,.wrap{
- …
- min-width:940px;
- max-width:940px;
- }
Media Queries資源
到了介紹media queries的時候了,比起寫關于Script Junkie文章的那個時候,我現在感覺自如多了,這多虧了很多(對我來說)新的工具和資源:
·想要在不同設備和分辨率下測試media query 效果?你可以看看Screenfly, 這并不完美,但我發現很實用
·Zoe Gillenwater (我至今見過的最好的CSS3資源的作者) 最近整合了“Essential Considerations for Crafting Quality Media Queries.”
·Respond.js:支持IE6到IE8的CSS3 media query, 通過使用Rock solid, lightweight polyfill增加最大和最小寬度
端正心態
對于我來說,將EE播客網站變成靈活式布局的目的是實現響應式網頁設計,為我的個人兼職網站加入media queries的目的也是實現響應式網頁設計。但是最后,這兩個網站呈現的效果都沒有完全達到我的目標,但是多虧了這兩個經驗,我明白了,不可能只通過其中一種方式就實現響應式設計。
響應式設計不只是流動式的網格布局,也不只是media queries。響應式設計是一種心態,一種工作流,一個不能夠(也不應該)被分隔理解的大的概念。特別是當“移動為先的設計”,以及“新設計過程”這些概念隨之出現的時候。






















