SpringSide開發實戰(三):漫談CSS和頁面布局
Posted on 2006-12-26 15:13 京山游俠 閱讀(8524) 評論(23) 編輯 收藏 所屬分類: SpringSide開發實戰還記得胡戈調侃《無極》中的王城布局為“圈圈套圈圈”娛樂城,也還記得我剛開始做Web開發時“表格套表格”的頁面布局。在大部分的程序員中,可能還在使用表格進行布局,使用表格進行布局的巨大缺點就是當頁面進行一點點修改的時候,都有可能完全打亂頁面的外觀,而且非常不利于和美工的配合。當然了,很多美工人員也在使用表格進行布局,他們在圖形軟件中設計好頁面,然后使用切片工具一切就完事,卻給我們需要在網頁網頁中動態增加內容的程序員帶來了麻煩。在CSS盛行的今天,我們早就該讓表格只做它的本分工作了。
網上也有不少使用div + css進行布局的教程,卻存在很多缺陷,一是對css的布局模型講解不清楚,讓人很難理解相對定位、浮動等概念;二是雖然避免了“表格套表格”的缺點,卻帶來了“div 套 div”的缺點,過量使用div標簽;三是class過多,造成class災難。
要正確使用css,對css的基本只是就不能夠不了解。既然是漫談,我這里就只講四個方面,最后給出xkland項目作為實例。
一、CSS中的塊模型
在CSS的定義中,有的html標簽被瀏覽器當成一個塊來顯示,比如div、table、p、ul等等,我們稱之為塊元素;有的html標簽被瀏覽器顯示在文本行之類,如a、span、font等等,我們稱之為行內元素。行內元素我這里就不講了,只講講塊元素的模型。
每一個塊元素都可以分為context、padding、boder和margin幾個部分,我們常說的寬和高,指的只是context的寬和高,padding代表內容和邊框之間的填充,margin代表邊框之外的空白,如下圖:
這幾個部分都是可以通過CSS進行指定的,當然,CSS還可以控制背景,因此,我們可以通過CSS來靈活控制我們頁面的外觀。
二、CSS中的文檔流模型
所有的塊元素在html文檔中是按照它們出現在文檔中的先后順序排列的(當然,嵌套不在此列),每一個塊都會另起一行。如下圖:
他們對應的html如下:



為了定義他們的寬度、高度還有邊框,我們定義如下的CSS:
























三、CSS中的相對定位和絕對定位模型
在文檔流中,每個塊元素都會被安排到流中的一個位置,我們可以通過CSS中的定位屬性來重新安排它的位置。定位分為相對定位和絕對定位,相對定位是相對于該塊元素在文檔流中的位置的,比如,我們可以使用相對定位把div2放到div1的右側,CSS代碼如下:



























下面是效果:
可以看到一個有趣的現象,那就是雖然我們把div2移走了,但是div1和div3中間還是有一個空間,說明相對定位的元素是會占據文檔流空間的,這里的div2就是典型的“站著茅坑不拉屎”。
使用絕對定位也是可以把div2擺到div1的右邊的,而且絕對定位是不會占據文檔流空間的,如下圖,div1和div3之間沒有空白:
div2的CSS代碼:











絕對定位是個好東西,可以把內容顯示到頁面上的任何位置,但是對于我們程序員來說,卻不能使用太多的絕對定位,因為使用程序動態向div中添加內容,div的大小是不可知的,無法將每一個div的位置都定死。
四、CSS中的浮動和清除模型
在CSS中,最讓人不好理解的應該算是float和clear意義了。float可以達到這樣一個效果,就是本來應該一行一個的塊元素,如果定義了float屬性,則只要行的空間足夠,它會跑別的float元素的屁股后面,而不再會單獨占用一行,如下圖:
這里把div2和div3都定義了為浮動,代碼如下:


















那什么情況下需要clear呢?這是因為float的元素和絕對定位的元素一樣,也是不占用文檔空間的,因此,如果我們把div2和div3都嵌套在div1中,并且把div2和div3都定義為浮動,那么由于它們不占用文檔空間,所以作為父元素的div1不知道自動擴展大小,以至于顯示出來div2和div3會跑到div1的外面,如下圖:
下面是它們的html代碼:




下面是它們的css代碼:


























因為float的元素不占用文檔流空間,有時候被的元素還會重疊到float元素上,這里我就不舉例了。
為了解決上面的問題,就需要在float之后的元素上面使用clear,在此例中,我們在div3后面加入一個空段落,并設置其為clear,如下:





下面是新增加的空段落的CSS代碼:





效果圖:
還是以我的xkland項目為例,來設計一個完整的頁面吧。下面是我的welcome.jsp頁面的布局圖:
在這個頁面中,我完全擺脫了“表格套表格”的模式,而且除了最上面一行在一個div里面顯示logo、advertisment和appendix的div外,其它的地方沒有div嵌套。盡量減少div嵌套的有力武器是理解div的意義,div代表division,是部分的意思,也就是說只有在確實沒有標簽能夠作為一個部分的根元素的時候才需要div。在上面的例子中,菜單條就沒有使用div。菜單條是使用列表實現的,因為列表的都包含在ul標簽中,因此沒有必要使用div。下面是上圖的html代碼:























是不是很簡潔?
而關于頁面美化和布局的內容,全部轉移到了CSS中。先來說說菜單項,菜單項是使用列表實現的,而列表常規的顯示樣式是下面這樣的:
怎么樣才能讓它們顯示到一行呢?那就是我前面講到的float屬性。我們給id為menu的ul定義如下樣式,來顯示邊框:










為了避免前面講到的float元素跑到邊框之外,我這里沒有使用clear,而是將menu的height屬性定義為12px,和頁面上的字體等高,而菜單只有一行,因此不會跑到邊框之外。menu中的每一個菜單項都是一個li,我們可以通過#menu li { }來定義它的樣式,這種方式叫做后代選擇器,充分使用這種選擇器,是避免使用過多的類的有力武器,從前面的html代碼中可以看出,我只對最后一個菜單項定義了類,因為我不想最后一個菜單后面還跟一個小豎線,菜單項之間的小豎線是通過定義li的右邊框樣式做到的,其css代碼如下:















對于下面那么多的框框,除了#netTopics我使用絕對定位把它擺到了右邊作為主要內容區之外,其它的都是順著文檔流擺下來的,只定義了寬度,而不需要定義位置。
如果我們要美化頁面,比如添加網站特有的圖片,我們可以修改#logo、#advertisment、#appendix的css代碼,甚至當以后別人美化我的網站時,可以把這三個div的visible設置為false,而直接定義#header的樣式。在這里,我們只簡單的把#logo的背景設置為logo圖片,并去掉邊框。下面是css代碼:








對于其他的div,我們還需要為它們添加內容,#loginView這個稍微特殊一點,需要添加標題和表單,而其他的div就簡單得多,只需要標題和列表就夠了。這里我們以#loginView為例,下面是添加內容之后的效果:
別看這里面布局也挺復雜的,我也完全沒有使用表格。下面是html代碼:



















可以看到,我使用的h3標簽來作為標題,這樣避免了為標題另外嵌套一個div,對輸入文本框定義了類textInput來定義它們的樣式,而其他的文本內容,我都是使用了p標簽和ul、li標簽,從上面的效果圖就可以看出CSS的強大。下面是它們的css代碼:























































總之,使用CSS將程序和美工分離是絕對的真理,我們程序員只要能夠在框框內輸出正確的數據就夠了,這樣能夠盡量減少程序的bug,美化頁面的事就讓界面設計師去做吧。當然,我們程序員還是要能夠在html中設計正確的division劃分和嵌套,讓界面設計師在設計界面的時候能夠找到定義CSS的錨點。
最后提一下,如果你的公司附近有幾所大學的話,那么恭喜你,你只需要設置少量的獎金舉辦一個什么CSS設計大賽,那么你的網站就有成十上百的界面可用,何樂而不為呢?