Chapter 12 CSS版面
本書到此為止,討論的主要是頁面內部元素,也就是內容,但是大結構怎麼辦?長久以來,設計者都依賴表格進行分欄佈局,常常在表格之內嵌套其
點這裡返回腳本之家 HTML教學 欄目.想瀏覽CSS教學請點這裡。
上文:標記語言-列印樣式。
Chapter 12 CSS版面
本書到此為止,討論的主要是頁面內部元素,也就是內容,但是大結構怎麼辦?長久以來,設計者都依賴表格進行分欄佈局,常常在表格之內嵌套其他表格以便達成恰巧正確的間隔,視覺效果.這些龐大的排版內容不僅下載很慢,維護起來也很費心力,更別提文字瀏覽器,屏幕閱讀器,小屏幕設備根本無法正確讀取了.
在這一章內,將使用四種常見的做法,結合CSS於結構化標記語法製作兩欄佈局.很快地就會發現,不用嵌套表格,間隔用的GIF也能做出分欄版面佈局.
稍後在"技巧延伸"中,將會討論Windows版Internet Explorer 5.0盒模型的問題,以及繞過它的方法.也將分享一個以CSS達成等寬欄位的簡單秘密.
#p#
要如何以CSS作出兩欄版面佈局?
答案是有好幾種方法,為了帶領你起步,同時幫助你了解兩種常見方法的差異(浮動與定位),因此先把焦點放在四種不同的方法上,在此每一種方法都能做出兩欄佈局,同時具備頁首和頁尾.
我的願望是:你能以本章作為指引開始建立一個網站,並發揮本書其他章節之內的方法製作內容.
我們將討論的四種方法都應用在文檔的
br/> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">CSS Layouts
...方法示範...
為了讓你可以了解要達成的版面配置,請看圖12-1:這就是我們想要完成的分欄版面佈局.
圖12-1 兩欄佈局的框線圖
讓我們開始吧!首先介紹第一種方法,它使用float屬性.
#p#
方法A:浮動側邊欄
p id="header">
...頁頭部分...
...主體部分...
p>
上面就是我們要以CSS的float屬性製作成分欄佈局的標記原始碼,使用
標籤把頁面元素分成幾個邏輯段落,每個都設定了唯一的id:
#header: 包含標題圖片,導覽列等
#sidebar: 包含額外的內容連結與相關資訊
#content: 包含主要的文字內容,也是頁面的焦點所在.
#footer: 包含著作權資訊,作者,輔助連結等
把這些頁面段落拆開,能讓我們能完全控製版面佈局,只要指定幾條CSS規則,就可以馬上完成兩欄佈局.
為頁首與頁尾指定樣式
要把內容結構轉化成分欄佈局的第一步,是為頁首,頁尾加上一點背景顏色以及一點內補丁,這樣能讓內容更容易凸顯出來.
為方法A的結構加上前面這段CSS會使它顯示成圖12-2這樣,我為各個段落加了一些假象的內容.
#header {
padding: 20px;
background: #ccc;
}
#footer {
🎜> }
圖12-2 為頁首,頁尾指定樣式當然,在#header與#footer裡,可以繼續為這些段落指定適當的樣式,像是font-family,color,鏈結色彩等等等.現在讓我們把兩欄版面製造出來.
浮動側邊欄
方法A的精華,在於它以float屬性把#sidebar放到主要內容
的任一邊去.以這個例子來說,將它放到內容的右側,但是放到另一側當然也行.
浮動#sidebar的關鍵在於,在標記源代碼中,必須出現在主內容
之前,這樣一來,側邊欄的頂部就會與主內容的頂部排齊.
接著,為#sidebar加上float屬性,同時把它的寬度設為30%,指定背景顏色:
padding: 20px;
background: #ccc;
}
#sidebar {
float: right;
width: 30%;
background: #999;
}
#footer { padding: 20px;
background: #eee; >
圖12-3是加上這段CSS之後的顯示效果,能看到側邊欄跑到右邊去了,而主要內容在側邊欄範圍之內流動.
圖12-3 把#sidebar浮動到主要內容的右側
真正的欄位
看看圖12-3,我們還沒有真正完成兩欄佈局,為了完成這個效果還必須取#content這個
,指定與憂側邊欄寬度相同的右外補丁,因此產生放置#sidebar的空間.
需要加上的CSS就是這麼簡單:
#header {
padding: 20px;
}}
#sidebar {
float: right;
width: 30%;
background: #999;
}
#content {
}
#content {
#content {
margin-right: 34%;
#footer {
clear: right;
; > background: #eee;
}
設定右外補丁,就能造出第二欄的假象.
...main content here...
圖12 -4 兩欄佈局
同時要留意的是對#footer所加上的clear:right規則,這個規則很重要,能確保頁尾一定會出現在側邊欄和內容區之後,而不受兩欄的長度變動影響,頁尾會避開任何先前出現的float內容.
現在有了能使用的兩欄佈局,可以繼續為現在的CSS聲明加上更多邊界,背景,邊框與其他元素,使外觀更吸引人.
至今為止我們都以百分比設定寬度,以便造出靈活的佈局(欄寬會自動隨著使用者的視窗寬度縮放).我們也能以像素單位造出定寬版面,但是以像素指定內外補丁大小時,必須注意IE for Windows錯誤解析CSS盒模型的問題,你能在本章的"盒模型問題"找到更多信息以及能用的解決方法.
#p# 方法B:雙重浮動
...header content here...
的前面,關閉CSS的瀏覽器,文字瀏覽器,螢幕閱讀器與其他不支援CSS的裝置將會在頁面主要內容之前顯示(或念出)側邊欄的內容.這樣實在不嚴謹.我們可以利用float做法,並避開這個問題,只要交換標記源代碼裡的主內容,側邊欄
的位置(如上所示),然後以CSS將兩者浮動到不同邊即可.
background: #eee;
#header {
padding: 20px;
background: #ccc;
}
#content {
float: left;
float: left;
width: 66%;
}#sidebar {
float: right;
width: 30%;
後 #999999999999997分>
}#footer {
clear: both;
padding: 20px;
}
後> >透過把兩個
浮動到不同方向,就能以最恰當的方式排列源代碼(主內容放在側邊欄前面),同時仍能得到圖12-4這樣的效果.
避開兩邊
同樣重要的是,你必須將#footerdeclear屬性設為both,如此一來不管兩欄的長度多長,頁尾總是顯示在最後,而標籤源代碼的內容順序也改善了.
...頁頭內容...
...主內容...
還有個值得一提的方法,只需要用一個float屬性,同時標記原始碼仍然可以將主內容的
放在側邊欄之前.
只要將主內容的
浮動到左側,並且為它設定小於100%的寬度,如此一來就能在右側留下足夠空間擺放側邊欄. CSS內容
方法C所需的CSS內容再簡單不過了,"一個float屬性",內容區希望使用的寬度,以及兩欄之間留下的小邊界.
# header {
padding: 20px;
background: #ccc;
}
#content {float: left;
float: left;
}
#sidebar {background: #999;
}
#footer {clear: left;
padding: 20px;
background: #eee;
}
請注意我們並不需要定義側邊欄的寬度,因為它會自動填滿主內容
用剩下的空間(在這個例子中是34%).
悲慘的背景
圖12-5就是以瀏覽器查看的成果,哦喔!在某些常用瀏覽器裡,側邊欄的背景顏色會出現在主內容區底下,由於側邊欄並未制定寬度,因此它想擴到與瀏覽器視窗一樣寬.
圖12-5 浮動內容,但是側邊欄的背景顏色透了出來
這個部分只要我們能在側邊欄左邊加上寬度與內容區相同的外邊界便可以避開這個問題.實際上我們會把外補丁設的稍微大一點,以便在兩欄之間留下一點空白.
或者是,如果涉及不需要用到背景色的話,那就不必設定邊界了,圖12 -6是去掉整個#sidebar聲明,在為主內容
#header {
padding: 20px;
background: #ccc;
}
#content {
float: left;
width: 66%;
#sidebar {
margin-left: 70%; background: #999;
}
#footer {
clear: left; padding: 20px;
background: #eee;
}
簡單樸素
加上一點右外補丁之後的結果.此時兩欄會共用頁面預設的背景色.
圖12 -6 不使用背景色的浮動內容CSS則能縮減成:
padding: 20px;除了加上左外補丁(或是省去背景色)之外,還有個使用背景圖片的替代做法能讓分欄具備背景色彩,我稍後會在本章的"技巧延伸"單元里提示這個小秘密.
background: #ccc;
}
#content {
float: left;
width: 66%;
margin-right: 6%;
}#footer {
arclear : left;
padding: 20px;
background: #eee;
}
除了使用float屬性之外,也能用定位製造出分欄位佈局,讓我們看看最後一個選擇,方法D.
#p#
方法D:定位
...頁首內容...
...主內容...
方法D是使用相同的標記原始碼結構,然後以最有效率的方式排列
:把主內容放在側邊欄之前,關閉樣式的瀏覽器,螢幕閱讀器會先收到主內容部分,再收到側邊欄,在定位時,標記原始碼內的順序與頁面元素出現的位置沒有關係.
能夠預測的高度
CSS內容與前三個方法有點類似,第一個差異是對頁首指定的像素高度,我們需要能夠預測的高度以便稍後為側邊欄定位.
在這裡隨機選了一個數字,而這需要根據頁首使用的內容調整,像是標誌,導航欄,搜尋表單等.
#header {
height: 40px;
background: #ccc;
}
#footer {
padding: 20px;
background: #eee;
}
background: #eee;
}
為各欄留出下空間}
接著,要為#content這個設定右外補丁,就像前幾個方法一樣,這能為右側邊欄留下空間,稍後會使用絕對定位法(不是浮動)把右側邊欄放進去.
#header {
height: 40px; background: #ccc; }
#contentcontent: #ccc; }
#content {
margin-right: 34%;
#footer {
background: #width: 30%;
padding: 20px; background: #eee; }
放進側邊欄最後,要使用絕對定位法把#sidebar這個放到#content的邊界裡,也必須去掉瀏覽器在頁面周圍加上的預設邊界,如此一來定位座標在所有瀏覽器之內就會一致了.
body {
margin: 0;
padding: 0;
}
#header { height: 40px; background: #ccc;
} } #content {
margin-right: 34%; }
#sidebar {
position: absolute;
position: absolute;
top:top
right: 0;
background: #999;
background: #999;
background: #999;;
}
放到距離瀏覽器視窗上邊緣40像素,右邊緣0像素的位置",除此之外,也能用bottom和left指定座標. 頁尾問題以先前的方法浮動分欄時,可以用clear屬性確保頁尾橫跨整個瀏覽器視窗的寬度,而不受主內容,側邊欄的長度影響.在定位時,側邊欄的文檔流獨立於整個頁面之外,所以只要側邊欄比內容還長,它就會蓋住頁尾部分.(圖12-8)圖12 -8 側邊欄與頁尾重疊面對這個問題我常用的解決方法之一,是為頁尾指定與主內容一樣的右外補丁,讓側邊欄能夠延伸超過頁尾.使用這個方法的話,CSS需要調整成這樣:
body {
margin: 0;
padding: 0;
}
#header {
height: 40px;
background: #ccc
}
#content {
margin-right: 34%;
}
#sidebar {
position: absolute;
top: 40px;
rightsolute;
top: 40px;
right: 0; width: 30%;
background: #999;
}
#footer {margin-right: 34%;
padding: 20px; }
這個解決方案在內容很短,側邊欄很長的頁面上看起來有點怪,但是它的確有效,結果可參照圖12- 9,示範了側邊欄避開頁尾的情況.
圖12-9 外補丁和主內容相同的頁尾
#p#
三人行
如果想做三欄佈局的話該怎麼辦?沒問題,而且在使用絕對定位時很容易加入.只需要為主內容,也為加上左外補丁,大小足夠容納第三欄即可.
另一個側邊欄能夠放在標記原始碼之內任何地方,因為會需要再度使用絕對定位進行佈局.
假設加了第二個側欄,並將它取名# sidecolumn ,接著以下面這段CSS為它空出位置,再把它放進去.
body {
margin: 0;
padding: 0;
}
#header {
height: 40px;
background: #ccc
}
#content {
margin-right: 24%;
margin-left: 24%;
}
sidecolumn {
position: absolute;
top: 40px;
width: 20%;
background: #999;
}#sidebar {
position: absolute; right: 0;
width: 20%;
background: #999;
}
#footer {margindo> : 24%;
margin-left: 24%;
padding: 20px; background: #eee; }
剛才完成的部分是在主內容,頁尾區空出左外補丁(避免重疊),與之前做右側邊欄一樣,接著以絕對定位法放進新的#sidecolumn ,將它放在距離上邊緣40像素,距離左邊緣0像素的位置.
你有留意我們稍微修正了寬度以容納第三欄嗎?由於我們使用百分比,因此這個佈局會隨著瀏覽器的寬度縮放,或者也可以為任何一欄指定像素寬度,以便使佈局寬度固定下來.
圖12-10是用瀏覽器查看這個範例的效果,一份以CSS絕對定位完成的靈活三欄佈局.
圖12-10 以定位法作出的靈活三欄佈局
#p#
歸納
我們在這章稍微研究了以CSS規劃版面佈局是能夠達成的效果.本章的目的是提供你發揮的基礎,因此示範了兩種主要的做法: 浮動和定位.
我希望你能繼續深入嘗試CSS佈局技巧,去掉頁面內的嵌套表格,並且換上更多瀏覽器與設備能讀取的靈活的結構化的標記語法.
如果你想知道更多關於CSS版面佈局的資訊,那麼一定要看看這些資源:
"The Layout Reservoir" (http://www.php.cn/):這是個使用絕對定位製作多欄排版的絕佳範例.
"From Table Hacks to CSS Layout: A Web Designer's Journey" (http://www.php.cn/): Jeffrey Zeldman撰寫的絕佳教學,記錄了建立雙欄佈局所需的步驟.
"CSS Layout Technoques: For Fun and Profit"(http://www.php.cn/): Eric Costello的各種CSS佈局資源.
"Little Boxes" (http://www.php.cn/): Owen Briggs編寫的許多CSS佈局範例的漂亮介面.
"CSS Zen Garden"(http://www.php.cn/): "示範以CSS為基礎的設計能達成什麼視覺效果". Dave Shea培養的"花園"以單一XHTML文檔展示讀者投稿的最新CSS設計(當然也包含佈局).這是個能看到CSS佈局能力極致的神奇網站.
技巧延伸現在我們經過了建立基本CSS佈局的基礎,該是討論Windows版Internet Explorer 5與5.5版,以及它們錯誤解析CSS盒模型這個不幸問題的時候了.稍後也會分享一個通過平鋪背景圖片達成等高欄位佈局的秘密技巧.
盒子模型問題
本章開始的時候我們討論了建立多欄CSS佈局的方法,只用width屬性定義每欄的寬度,當你開始為這些欄位加上補丁,邊框的時候,事情就變得有些複雜了.為什麼?
不幸的是,Internet Explorer 5for Windows在加上內外補丁,邊框的時候,無法正確計算外包元素的寬度.
舉例來說,除了IE5 for Windows之外,所有支援CSS1的瀏覽器都會將外包元素的寬度計算為寬度,內補丁,邊框三者相加,這是W3C希望所有瀏覽器處理CSS盒模型的方式.
但是IE5 for Windows會將邊框和內補丁算在指定的寬度之內,搞混淆了?不用擔心,直接看看問題會對你有所幫助.
眼見為實
比較一下圖12-11和12-12,圖12-11是個200像素寬的元素,兩側各有10像素的內補丁,以及5像素的邊框,把水平部分的數值全加起來,就能知道實際寬度為230像素.
圖12-11 盒模型的正確計算結果
圖12-12 IE5 for Windows 錯誤的內補丁,邊框,寬度計算結果
這是符合設計的盒子模型:width屬性總是定義元素的內容範圍,而內補丁,邊框則會加到這個數值上.
因此,如果將側邊欄的寬度定義成200像素然後加上內補丁和邊框,CSS的聲明如下:
#sidebar {
width: 200px;
padding: 10px;
border: 5px solid black;
}
把寬度設定為200像素,但是側邊欄實際需要230像素的空間,除了IE5 for Windows以外. IE5 for Windows 裡側邊欄總共會佔用200像素,把內補丁和邊框都算在裡面.
圖12-12 顯示的是當width屬性指定為200像素時,邊框和內補丁會佔用內容空間,而不是內容空間之外.
#p#
搖擺不定的寬度
我們反對為元素指定邊框,內補丁的理由就是實際寬度會隨著用戶瀏覽器的不同而不同,就算在今天,幾百萬使用IE5.x的用戶還是會看到明顯偏差的設計結果.同時有個重點必須記住:在這段文字撰寫的時候,仍然有太多人在使用IE5以致我們不能忽視這個問題.
所以該怎麼辦?恩,幸運的是,有個能修復這個問題的技巧,這個技巧可以提供兩種不同的寬度,一種給IE5 for Windows,另一種給其他瀏覽器以便得到正確的盒模型.
盒子模型Hack
親切的Tantek Celik寫了盒模型Hack (http://www.php.cn/) 讓我們能提供兩種不同寬度:一種調整過,只會被Window Internet Explorer 5使用,另一種則給其他所有瀏覽器使用.
透過IE5和IE5.5才有的CSS解析Bugs,可以指定一個略大的寬度(容納邊框和內補丁),然後以實際的寬度覆蓋這個數值,讓其他瀏覽器能顯示出正確的結果.
原始碼範例
舉例來說,如果希望把側邊欄的內容區域寬度設為200像素寬,加上10像素內補丁和5像素邊框,那麼我們的CSS看起來就像:
,則需要把寬度指定為230像素(加上兩側內補丁和邊框的寬度),接著再以200像素覆蓋回來,讓符合標準的瀏覽器得到正確的寬度.
#sidebar {
width: 200px;
padding: 10px;
border: 5px solid black;
}
padding: 10px;對於同樣擁有IE5 for Windows解析錯誤的CSS2兼容瀏覽器來說,我們必須在每次使用盒模型補丁之後加上一段額外的聲明,這個稱為"對Opera友好"的規則會讓所有符合標準的瀏覽器不被解析Bug卡住,確保他們能顯示出期望中的寬度.
border: 5px solid black;
width: 230px; /* for IE5/Winack ""}"";
voice-family: inherit;
width: 200px; /* actual value */
} }
留意IE5 for Windows的值先出現,接著幾條讓IE5 for Windows認為聲明已經結束的規則,在此我們使用voice-family屬性,原因單純只是瀏覽器認得它的話也不會改變視覺效果,最後指定實際的寬度,覆蓋最初的width規則,第二個width規則會被IE5 for Windows忽略.
結果在IE5 for Windows以及其他所有兼容CSS2的瀏覽器上看起來應該完全相同.沒有使用這個hack的話,IE5 for Windows的使用者就會看到比設計還瘦的欄寬. 對Opera友好
#sidebar {
padding: 10px;
border: 5px solid black;
width: 230px; /* for IE5/Win */
voice-family "";
voice-family: inherit;
width: 200px; /* actual value */
}
html>body #sidebar { }
html>body #sidebar {
width: 200px;
}
有了這段規則,就可以完全繞過IE5 for Windows錯誤解析CSS盒模型的問題,讓所有人都能看到正確的效果.
#p#
不只寬度
在這裡以"盒模型Hack"達成顯示相同寬度,但是這個Hack其實能在任何想為IE5 for Windows提供不同CSS內容時派上用場.任何Hack都必須小心使用,同時只有在真正需要的時候才使用,記住"盒模型Hack"的使用地點是個好主意,這樣才能在未來輕易拿掉它.
本文撰寫時仍有上百萬網絡用戶仍然使用IE5 for Windows,因此這個補丁不可或缺.
下面這段"偽裝的欄位"原始出自2004年一月份的A List Apart雜誌(http://www.php.cn/).
偽裝的欄位
關於我個人網站的設計,我最常被問到的問題是:
"你是如何讓右欄的背景色一路延伸到整頁底部的?"其實這只是個簡單的概念,真的.而且這個概念能應用到本章開始所述的每種佈局方法上.
垂直伸展
CSS最容易讓人感到挫折的性質之一,是元素只會垂直伸展到真正需要的長度.這代表如果在
裡放一張200像素高的圖片,那麼
就只會在頁面上延伸200像素.
當你以
切割頁面段落,接著用本章開始時的方法用CSS完成多欄佈局時,這就會成為有趣的困境,某一欄可能比其他欄都長(圖12-13),當你想為每欄選用獨特的背景色彩時,視內容多寡而定,做出兩個一樣長的欄位可能十分困難.
圖12-13 長度不一樣的欄位
有幾個做法能讓闌尾看起來一樣長,不受欄位包含的內容的影響.我準備分享我的解決方法(適用於絕對定位佈局法) ,而這個方法實在是莫名其妙的...簡單.
作弊
這個難以啟齒的簡單秘訣,是用一個垂直排列的背景圖片作出彩色欄位的錯覺.在SimpleBits(http://www.php.cn/),我用了類似圖12-14的背景圖片(為了示範而修改了比例):左邊有裝飾用條紋,中間留下寬闊的空白空間安放主要內容,接著是一條1像素的邊框,然後是右側邊欄的淺棕色區域,跟著是反向的裝飾用條紋.
background: #ccc url(tile.gif) repeat-y 50% 0;
這會使整個頁面的背景色設為灰色,並且只垂直平鋪圖片(repeat-y),後面的50% 0代表背景圖片的定位:在這個例子裡,是從瀏覽器視窗左邊緣算起50%(使圖片居中),並且緊貼上邊緣.
欄位定位
放好背景圖之後,在把我的定位佈局放到上面,為左欄,右欄指定內外補丁以確保它們會對齊正確位置:也就是背景圖創造出來的虛假欄位裡(圖12-15).
圖12-15 平鋪背景圖創造出的彩色欄位
有個重點必須要注意:如果哪一欄指定了邊框,內外補丁的話,就仍然用Tantek Celik的盒子模型Hack為IE5 for Windows修正盒模型問題(參照本章稍早的"盒模型問題").
或者是,如果能夠只使用外補丁,避免邊框與內補丁的話,就不需要加上盒子模型Hack了,同時,如果欄位的內容只單純放在平鋪背景圖之上(透明顯示),那麼要避免使用Hack也應該很簡單.
只要有用就好
雖然我以絕對定位法在自己的網站上做了兩欄佈局,但是你也能用本章開始時提過的其他方法達成一樣好的效果.同樣的想法仍然適用:平鋪背景圖,接著再浮動某個欄位,使其覆蓋在模擬的欄位背景上.
這是個簡單的概念,但是能夠解決設計者在構建CSS佈局時經常遇到的挫折之一.
結論
我希望本章能帶給你開始探索CSS佈局的刺激世界,本章開始時我們看到了四種構建版面佈局的方式,其中三種用了float屬性,還有一種用了絕對定位.一定要去看看我列出的額外資源,裡面有更多佈局的技巧和示範.
我們也討論了盒模型Hack在建立具備邊框,內補丁的欄位時有何重要性,讓這些效果在IE5 for Windows以及其他瀏覽器上表現一致.
最後,我分享了一個有用的技巧,讓你在設計CSS佈局時能做出等高欄位,這是某些人認為十分基本,但實現上經常讓人感到挫折的設計目標.只要小小一個平鋪背景圖就能搞定,讓你得到能夠抵達頁面底部(不管內容多長)的欄位.
個人比較習慣用多次浮動來佈局,這方面隨個人喜好了,沒必要強迫使用哪一種佈局方法,就算你用table來佈局,你認為爽也不會有人說什麼...哈哈,玩笑