by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=1463
一、簡短的前言
之前曾作有“頁面重構鑫三無准則之無寬度准則”一文,屬於流體布局系列中的偏理論性的文章,本文也是這種性質的,可謂是“無寬度准則”一文的延續。
“無寬度准則”是說內部元素不要定寬,但是,除非你的頁面是像google的產品頁面一樣都是100%自適應的,那么頁面的終歸會有一個固定的寬度值,一般出現在頁面的結構部分(主寬度,側欄,中欄)、以及等寬列表部分,而這些就是本文要討論的對象。
跳出圍牆,enjoy it!
二、何為寬度分離?
所謂“寬度分離”,就是CSS中的width
屬性不與影響寬度的border
/padding
(有時候包括margin
)屬性共存。
即不能出現以下的些組合:
{width:200px; border:1px solid #ccc;}
或者是:
{width:200px; padding:20px;}
三、為何要寬度分離
“寬度分離”可以讓你延年益壽,家庭和睦!您可能會覺得我馬屁的好處比腦白金還要響亮,不急,看完我下面的分析您再下定論。
首先為什么會長壽?因為在“寬度分離原則”下,您不需要1像素1像素的去計算寬度,不必去勞心勞神地去估量這里的padding值應該多少像素才不會撐開布局,不必去琢磨這里的margin值為多少列表才可以正好一行顯示5個。不就是寫個頁面嘛,最后搞得像做果蠅DNA提取實驗一樣,目不轉睛,全神貫注,腦細胞猶如剛領的薪水,迅速消耗。折騰到最后,發現唯獨該死的IE6下居然布局錯位,一顆滿心期待的心頓時冷卻到了冰點。唉,要知道心累才是真的累,小說以及電視劇里面的悲情角色多半都是心力交瘁而死的。在“寬度分離原則”下,相比前面的些折騰,寫頁面的感覺就像是躺在綠油油的草地上享受柔和的春風;又像是在悠遠質朴的街頭與孩童們一起嬉鬧玩耍。我不說也應該看出來了,一個是不停地折騰,一個是愜意的享受。要知道,我們一生中大概有8~9年的時間是在工作的(24小時不停),要是工作的時候總是勞心勞神地折騰,估計早死個個把月是不成問題的。
再說家庭和睦。在“寬度分離原則”下(結合“無寬度原則”),像錯位這種性質的bug是不可能會出現的。沒有了在寬度上的糾纏不清,沒有了修改樣式bug這類雜碎的活兒,於是,我們工作就會變得很輕松。頁面刷刷地寫完,沒有錯位,沒有bug,而且以后無論怎么折騰也不會出類似的bug,關鍵布局重用性高(寬度分離可重用,內部自適應——也是任意重用)。然后剩下的就是端上一杯咖啡,邊慢慢品味咖啡的濃香,邊悠然自得得看看微博,這工作,多輕松愜意。
但是,如果你是一根筋地像砌磚頭式的寫頁面,寬度相關屬性不分離,啊哦,你有得忙了:寫頁面的時候寬度要去計算,還要去反復調試,還要兼顧瀏覽器的兼容性問題,我想想都覺得麻煩,耗時間;后來又出來了個類似的功能,就是寬度不一樣,不得已,新功能頁面寬度重新計算,樣式重寫,得,又是折騰;頁面好不容易出來了,但是,后來需求要改,即使很小的改動,寬度啊什么的也要重新計算;好不容易改好了,結果上線后發現某些地方的布局有bug。辛辛苦苦加班加點寫頁面趕工期上線,誰知最后還因些小bug還被經理批:就這幾個破頁面,折騰這么久,還有問題。首先,這每天加班,人體力上肯定折損很大,你說這晚上回家,老婆大人想尋求安慰,你卻提不起勁,嘖嘖,我只能說“遺憾”兒子;其次,這辛苦工作最后還是被訓的份,這心里頭肯定不是滋味,回家說不定就因為女友大人的不斷的嘮嘮叨叨給惱火,然后吵架什么的就來了。所以說“寬度分離”可以讓家庭和睦。
四、繼續為何要寬度分離
上面的解釋可能由於自己的思維一下子沒剎住車,略誇張並帶了點玩笑的性質,其實,意思就是說:“寬度分離”無計算,擴展性強,容錯性強,可以讓寫頁面更輕松。
這里,我要好好解析下為什么“寬度分離”擴展性強同時可以讓寫頁面更輕松。
Part1: 我們應該都知道:當一件事情很多人可以作決定,恰恰這些人又同時做決定的時候,這件事情最后往往是做不好,一團亂的。舉個例子:
某籃球隊沒有教練,場上的5個人都有說話權,結果到關鍵時候,暫停處理關鍵球的時候,后衛說這球應打到外線博三分,而小前鋒卻說這球要求穩,突破先取兩分……此時該聽誰的?於是暫停時間結束,大家腦中還是混亂一篇,不知究竟該怎么做。於是,最后的結果往往是:被人家緊逼——發球失誤——直接被搶斷。如果此時只有一人能說話,無論是部署配合,還是確定2分還是3分策略,效果都要比現在好很多。
在舉個更貼近我們工作的例子。舉例對象就是可親可敬的設計師們,我之前在微博上看過一個關於平面設計師的連環漫畫,如果是針對網頁設計師,我想故事應該這樣發展:設計師加班加點設計出了一個頁面,結果產品經理一看,覺得這里不行得改一改。好吧,本着敬業精神,於是又加班加點改好了。回頭給前端老大看了下,覺得那里不行,實現成本太高,要改,於是任勞任怨的設計師又去加班加點改好了。后市場總監也來看了下設計圖,覺得這廣告位設計不行,得改……於是,繁華都市夜空下的辦公樓里又出現了那個熟悉的孤獨的背影。
設計師之所以會有如此的悲哀就是因為:很多人可以決定設計師的設計內容,恰恰這些人又同時對設計師的設計指手畫腳。於是,出現了不斷折騰的局面。
OK,現在來看看CSS中的width屬性。我們都知道,CSS中影響寬度屬性的不只是width屬性,還有border屬性,以及padding屬性。例如:
.test { width: 200px; border: 2px solid #ccc; padding: 20px; }
則此.test
下的div實際寬度是200 + 2 * 2 + 20 * 2
即244
像素。
這里的width屬性就像是設計師,border屬性就是產品經理,padding就是技術經理。當這些屬性都是混在一起,就像是所有人都對設計師指手畫腳一樣,最后的結果就是折騰、混亂,公公背媳婦過河——吃力不討好。
Part2: 我們也應該都知道:很多事情關注的重點應該是在結果上,而不是過程,這樣我們會變得非常輕松。
就像中醫治病一樣,不必管到底是什么物質在體內與疾病作斗爭,病好了才是王道。我再舉兩個例子:
第一個是稱重量。在還沒有電子稱的時候,我們要使用單標尺機械稱稱100斤的小麥該怎么稱?
顯然,這里,我們應該關注的是最終的結果——100斤。所以,我們先把稱(坨+標尺)調到50公斤的位置,然后不斷地加小麥,直到標尺開始懸空,此時就是100斤了。
當然,我們還有一種關注過程的做法,我稱之為“稱體重”做法,具體如下:機械稱上放入一定量的小麥,然后稱一下質量,發現是86斤;於是又向里面添加了點,再稱,96斤;於是,又放入一定量的小麥,再次去移動標尺測重量,結果102斤,過了;然后,又去掉一點,再稱,這次終於100斤了。
前者就近似於本文所說的“寬度分離”做法,無需計算,只關心結果;而后者就是需要計算的做法了。
第二個例子就比較貼近我們的工作了,就是工作任務制。這是很多公司對於技術人員的一種管理制度,也就是“你只要在規定的時間內完成規定的任務,期間隨便你做什么我都不管”。這就是典型的只關心結果,這種做法的好處是:開發人員可以享受到很大的自由,對於做技術的人來講,這是種莫大的恩賜,至少對於我來講是這樣子的,於是工作更開心更高效;對於管理人員講,工作就相對輕松了很多,不必每天去監督關注下屬工作進度如何如何,只要在期限結束的時候驗收就可以了。工作輕松了,自然也有更多的精力在其他方面折騰了,。
例如,前端老大要求你5個頁面2天時間給我整好了。於是老大只要關心2天后你頁面是否出來,至於期間你是不停地和美女前台打情罵俏還是玩《憤怒的小鳥》一個通宵還是加班加點連澡都來不及洗都不管boss的事情,boss只關心結果。這與“寬度分離”原則是一致的,我們放眼的是最終的寬度,至於內部怎么折騰屁事都不相干,由於我們只關心一個東西——最終寬度,所以我們會非常輕松。
Part3: 我們也應該知道水是流動的,其會自動填滿放置它的容器。
在頁面制作與CSS中,所以的div標簽默認都是流動的,如水流般會自動填滿整個容器。然而,很多屬性會阻斷這種流動性,例如浮動,絕對定位以及寬度(width)屬性。所以,流體布局中應該盡可能的避免浮動,絕對定位以及寬度。然而,本文的前提就是針對有些必不可少的寬度,這些width
屬性就像是一個限定了尺寸的盒子。雖然width
屬性會阻斷流動,但是會影響寬度的border
屬性以及padding
屬性卻不會阻斷div標簽的流動性。試想下,一個盒子里如果只有流動的水流,這個盒子永遠不要擔心會被撐爆,因為水流只會受限於盒子,反過來則是不行的。也就是說將width
屬性與border
/padding
屬性分離的話,就不用擔心里面的內容(里面的內容需遵循“無寬度准則”)會因為寬度溢出撐開布局而造成錯位了。這讓我們只關心“最終寬度”沒有了后顧之憂。//zxx:容錯性強
同時,由於水流可以盛放與任何容器中,所以,一旦“水流”形成,幾乎就可以無限制重用。同時,這個尺寸的容器也是可以放置其他的水流的。//zxx:重用性強
按照這里的分析,“寬度分離”實際上類似於化學上的“固液分離”。
五、如何寬度分離
舉個以前曾列舉過的例子,如下圖:
要實現上圖所示的效果,您會怎么做?我大膽估計了下,考慮到最少的HTML代碼,您可那會有如下的樣式:
.box{width:430px; padding:20px; border:1px solid #ddd;}
HTML如下:
<div class="box"> <strong>溫馨提示</strong><br /> 團購成功后,消費憑證將發送到手機:<strong class="cr">132 0803 3621</strong>,憑短信去商家消費。 </div>
顯然上面的做法是不符合“寬度分離”原則的,如果寬度分離,則應該樣式如下:
.box{width:470px;} .box_in{padding:20px; border:1px solid #ddd;}
HTML如下:
<div class="box"> <div class="box_in"> <strong>溫馨提示</strong><br /> 團購成功后,消費憑證將發送到手機:<strong class="cr">132 0803 3621</strong>,憑短信去商家消費。 </div> </div>
對比前后就可以看出“寬度分離”的實現其實就是以犧牲一層標簽為代價,將width
屬性放在外層標簽上,其余的放在內層標簽上。這里看似多了層標簽,實際上權衡下來,裨益相對於損耗要大很多很多。
說到這里,我忍不住要岔點別的話題,關於寫意與寫實。
我之前就提過,寫頁面就是一種創作,可以融入自身的藝術氣息,表達自己的情感、個性。說到藝術創作,就離不開“寫意”與“寫實”。比如繪畫,就有抽象派和寫實派。
又比如詩詞,亦有寫意與寫實,拿李白的《靜夜思》舉例,如果是“床前明月光,李白睡得香”,那么就是寫實;如果是“床前明月光,疑是地上霜”那就是寫意。
就連武俠中也有“無招勝有招”這種類似的概念。
如果只是照着設計圖一個框子一個框子的套,那只能說是“寫實”。“寫實”的最高境界就是寫出的的頁面與設計圖1像素都不差,各個瀏覽器下都1像素不差,如果你是這樣的,那去騰訊吧,那里適合你。而我個人更強調“寫意”,細節上的極致,結構上的灑脫,簡單輕松自由無限的感覺。流體布局顯然更強調“寫意”,其自適應特性本身就帶有種灑脫的氣質,寫流體布局頁面猶如寫詩般,寥寥數語,情境頓生,不刻板,不拘泥。具有詩人情懷的人才能寫出真正詩意的頁面;刻板的人只能寫刻板的頁面,這類人更適合去折騰C++。
我突然想到了一個東西,幾年前貌似討論很熱的“柵格化布局”,說實話,我對這玩意真是一點都不感冒,甚至有些嗤之以鼻。我這人天生就不是個循規蹈矩的人,對需要套用(40×n)- 10 = W
這類公式的東西是很不喜歡的。公式的好處在於統一與規范,這在定寬布局(如950像素寬度)上的還是頗有裨益的。然而,公式的本身就意味着限制,你不可能跳出這個圈圈的。網頁設計不同於平面,上百年下來都是一個尺寸的紙張。在寬屏日益普及的今天,950~980像素見尺寸的頁面還能堅挺多久?如果要改動,是否還要遵循“格柵化布局”?還去套用(40×n)- 10 = W
的寬度公式?所謂無為而治、無欲則剛。《海賊王》中路飛桑曾說過:“我才不要成為最強的人呢,我要成為大海上可以自由馳騁的人!”可見自由才是最強大的。
我平身最討厭的就是被限制,所以我成為一個個流體布局控也就不奇怪了,不鳥“柵格化布局”也就容易理解了。
六、寬度分離的簡單例子
首先看一個分離的例子,京東商城的首頁底部區域,有一個灰邊框圈住的服務相關的內容,如下圖所示:
//zxx:雖然京東商城的頁面在寬屏下有1200像素的寬度,但是其並不是自適應布局,而是普屏和寬屏下的兩套不同的結構寬度樣式而已。相比較自適應布局,此技術難度和要考慮的因素要小很多。
我們用小bug(我對firebug的昵稱)看下此處的CSS代碼,可以看到寬度分離了,即最外層標簽僅僅只有width
屬性:
而影響寬度的border
屬性以及padding
屬性全部寫在了內部的標簽上:
如果從精簡HTML,較少DOM層級的角度考慮,我們其實一層標簽就可以搞定了,如下:
#service{width:1158px; padding:20px 20px 10px;border:1px solid #E6E6E6;overflow:hidden;zoom:1;margin-bottom:10px;}
但是為什么京東的做法卻不是如此呢,而是要將其分離出來呢?
好吧,我可能明知故問了,上面我已經浪費了很多口水,哦,不對,是浪費了很多次的打鍵盤來講原因:
其一,不要去計算了。多省心啊,直接1200像素,否則還要1200 - 20 * 2 - 1 * 2 = 1158
去計算,誒呦呦呦,這多鬧心啊!
其二,重用性高了。你瞧,這.w{width:1200px}
很多地方都可以使用,如果不分離出來,oh, my lady gaga, 一個模塊一段寬度相關樣式,這純粹屬於閑得蛋疼沒事找事。
其三,維護方便了。你說要是以后這padding
值要改成左右15像素的,如果是寬度分離的寫法,只要修改padding
屬性就可以了。分離的思想就是:我只關注最最外面的寬度,里面你隨便怎么折騰都不干我屁事。要是以后要修改最外框的寬度為1260像素,就直接修改width:1200px
為width:1260px
就可以了,因為自適應部分已經分離出來了,如流水般自適應外部的容器。但是,倘若是使用一層標簽,CSS是width+border+padding
這種曖昧不清的寫法,當我們修改padding
的時候,不僅要改padding
屬性,同時width
屬性的值還要重新計算與修改,屬性相互關聯,牽一發而動全身。
下面再看一個沒有分離的例子。對於頁面的主div結構而言,不知是有意還是無意,國內領先的網站都會將寬度與邊框和內邊距屬性剝離出來,然而,在內部結構元素,或是列表布局的時候,情況就不一樣了。京東商城有這樣子的問題(不多),淘寶網也有(較多較嚴重,正好當教材使用),這里就拿淘寶網舉例。
先說一個我百思不得其解的問題,見下面的截圖:
還有下面的類似的問題:
上面兩張圖高亮的寬度屬性真是讓我無言以對,我試着從各個角度找理由,haslayout?模塊化開發副產物?但是最后我只能得到的結論是:寫category.css的應該是個剛畢業的新手。請原諒我有意的冒犯,只因自己太糾結,為什么這里要添加一個毫無意義,反而帶來諸多糟粕的width屬性呢?誰能給我個答案?……
罷了,這不是這里討論的重點。我們來看看列表布局中有關“寬度分離”的例子,首先見下截圖:
顯然,這里的列表CSS有悖本文的主題“寬度分離原則”,width
屬性與含有水平padding
值的屬性寫在了一起,首先不說別的,估計這里的寬度計算與調試估計折騰了不少時間。您可能會想,是不是使用:
.category-item li{ float:left; width:228px; /*修改寬度*/ height:21px; margin-bottom:5px; overflow:hidden; }
嘿嘿,不是的!對於等寬列表而言,雖然寬度分離可以較少一些后期維護的工作量,但是,如果還是定值的話計算還是不可避免的,因為你需要做“總寬/3”的計算,例如684 / 3 = ?
。所以,如果是我,不僅會寬度分離,而且寬度會使用百分比而不是定值,因為不需要計算啦。如下CSS:
.category-item li{ float:left; width:33.3%; /*修改寬度*/ height:21px; margin-bottom:5px; overflow:hidden; }
還是那句話,我只關心結果,你父標簽寬度多少與我沒有任何關系,我只知道我是等寬列表,而且一行三個,所以,我的寬度百分比就是100 / 3 = 33.3%
,至於里面怎么內訌,外面怎么凌亂都不管我的事,我只關心結果,與我相關的結果,我最終的寬度。
本實例中,實際上是里面是不需要再包裹一層標簽的,因為里面已經有h4
標簽和span
標簽供使用了,按照“精簡高效的CSS命名准則/方法”的觀點是不推薦直接使用.category-item h5
這樣的選擇器,但是,這是淘寶網,人家已經用了,不用白不用,所以,我們可以把padding-left
的10像素可以margin-left:10px;
以寫在.category-item h5
上,而padding-right的26像素可以以margin-right:26px;
的形式(或省略)寫在.category-item li span
上,這樣既實現了寬度分離(自適應於父標簽,同時內部元素又自適應於自身,而且沒有了計算,后期維護也更容易了),又沒有多余的層級。
實際上,考慮到更高的重用性,屬性:
{ float:left; width:33.3%; }
應該獨立分離出來,命名應采用面向屬性的命名方式。但是,淘寶網首頁就是個獨立的頁面,與其他頁面老死不相往來,所以,這樣子的樣式分離就沒有必要了。
七、最后點總結
你想頁面刷刷地以迅雷不及掩耳的速度寫完嗎?你想寫的頁面無需調試鮮有兼容性問題嗎?你想讓你的頁面再怎么折騰布局都不會亂嗎?你想讓你的頁面以后改動起來就像在無人的電梯里放屁那樣輕松嗎?你想讓的頁面加載起來閃都不閃一下嗎?你想每天有大把的時間喝咖啡、上微博同時還工資不斷漲嗎?
跟你講,聽我的,遵循寬度分離原則,以上都可以實現,准錯不了。但是,注意這里的但是,您需要認認真真去看看我之前寫的關於流體布局思想的些東西,去體會CSS分離的思想,CSS合並的思想,理解關於CSS命名的思想,尤其要明白“無寬度准則”說的什么意思,然后再來使用這里的無寬度准則,再加上你一定的寫頁面的經驗(1千張應該差不多了,)。否則,就單單這里一篇文章,只能一定程度上提高你寫頁面的速度和頁面的質量,僅僅是一點點的量變而已。
有必要說下,我所寫的CSS偏理論方面的一系列文章相互間都是關聯的,用一個不太恰當的此代替的話,可以說是一個體系,一個自己摸索總結形成的CSS理論體系。單獨一篇文章或許是偏執,但是所有文章結合在一起你將會看到另外一個完整的世界,猶如《阿凡達》的潘多拉世界一樣。我的這類文章具有極強的個人特質,具有一定的反叛與嘲諷,與主流的CSS做法總是有出入的,所以難免會刺痛一些固步於自己CSS世界里的一些人的自尊心。
我是非常非常歡迎也非常非常期望任何人以任何形式(例如評論)進行真誠的交流。海納百川,有容乃大,您的看法與見解可以讓我看到自己的不足和需要提高的地方,這對於我來講是最最需要的。但是,如果您只是粗略的掃視文章內容,然后過來指手畫腳,反而只會暗自被我嘲笑而已。
本文的“寬度分離”原則其實不單單針對流體布局的,固定寬度的布局依舊適用,但是,習慣於固定布局的人往往缺少流體布局的意識,“寬度分離”的潛力發揮有限,因而才以“流體布局”為題。
最后,感謝您的閱讀,希望本文的內容能夠對您的學習有所幫助。
本文為原創文章,轉載請注明來自張鑫旭-鑫空間-鑫生活[http://www.zhangxinxu.com]
本文地址:http://www.zhangxinxu.com/wordpress/?p=1463