這個篇文章介紹的是現在廣泛使用於網站布局領域的CSS基礎。
你也許知道什麼叫選擇器,什麼叫屬性,什麼叫數值,也許你對CSS布局略懂一二,但這還遠遠不夠。如果你想著從頭開始學習Html和CSS的話,我建議你認真查看下 this tutorial. 否則,在工作的時候,你依然陷入迷惘的泥潭中苦苦掙扎。
如果你希望你的網頁內容以一個欄的形式顯示出來的話,那麼就用不著使用CSS布局了。然而,如果用戶的浏覽器界面調整得很寬的話,那麼每一次看完一行文字的時候,你的視線都要從右到左地移動到下一行,很麻煩啊有沒有,你自己調整一下界面的大小就知道我所說的情況了。
在我們解決這個問題之前,先讓我們了解下一個非常重要的display屬性吧。
在控制布局方面,display是最重要的CSS屬性,每一個元素都有其默認的display屬性值,大部分的默認值不是block就是inline,用block標記的元素一般稱為塊級元素,而用inline的元素一般稱為內聯元素。
Div標簽是塊級元素的代表,塊級元素占據著整整獨立的一行,其他常見的塊級元素有p和form,還有hml5中加入的header,section和footer等等。
Span標簽是內聯元素的代表,內聯元素能夠避免破壞段落結構的情況下,往其中添加文本段落。而元素a就是最常見的內聯元素,經常用他來作鏈接使用。
另一個比較常見的display屬性值就是none,像script這些比較特別的元素的默認屬性值就是none,他經常被用來隱藏Javascript語句,適當隱藏暫時不用著顯示的元素.但這區別於visibility。設置display:none的元素,經過頁面的渲染過後,就好像這個元素不存在了。而設置visibility:hidden;的時候,同樣會對該元素進行隱藏,但是,如果他被完全隱藏的時候,其依然還是占據原來的空間。換句話說 display:none會真的把你弄沒,而bisibility:hidden則僅僅是為你披上一件隱身衣而已,你還在原來的地方呆著。
除了上面講到的display屬性值之外,其實還有很多display屬性值,比如list-item以及table這些。(鏈接)這裡有一個詳盡的列表。我們接下來還會討論到inline-block和flex,敬請期待。
<4>友情提示
正如我所提到的,每一個元素都具備一個默認的的display屬性值。其實你完全可以忽略這句話!雖然說div在默認情況下不可能是內聯的,但是你定制出你想要的display屬性值元素。舉個常見的例子來說吧,li內聯元素常常被用作水平的菜單。
在線查看
擴展閱讀
- "display" property
- display
- CSS display: inline-Block: Why It Rocks, And Why It Sucks
- Use CSS display:table for Layout
- display
——大漠
#main { width: 600px; margin: 0 auto; }
在塊級元素中設計width屬性能夠防止在水平上撐滿容器。然後,你還能夠設置左右margin來進行水平居中。在中間占據指定的水平寬度,然後剩下來的寬度空間就會一分為二成為左右外邊距。
現在唯一需要解決的問題就是,一旦浏覽器的顯示窗口的寬度小於你設定的元素寬度。浏覽器就會自動加上一個水平滾動條來進行內容顯示,有時這種情況不是我們想要的,需要改進改進。
在線查看
擴展閱讀
- Box model
- CSS CENTERING 101
- How to Center Anything With CSS
- Equal Height Column Layouts with Borders and Negative Margins in CSS
- Collapsing Margins
——大漠
#main { max-width: 600px; margin: 0 auto; }
使用max-width來代替width能夠提升浏覽器對小窗口情況的處理效果。這個處理方法在移動端上顯得更加尤為重要。現在你就可以調整下窗口的大小,來對照下吧!
順便說下,max-width得到了所有的主流浏覽器的支持包括IE7在內,所以盡管使用它就行了。
當我們談及width的時候,我們應該談論到關於width一個重要的注意點,box模型。當你在元素中設定width,該元素的實際大小一般大於你的所設定的數值:元素的border以及padding會在原設定寬度的大小上進一步撐大容器的寬度。看看下面的例子,兩個設定相同width大小的容器,卻是以不同大小的形式顯示出來。
.simple { width: 500px; margin: 20px auto; } .fancy { width: 500px; margin: 20px auto; padding: 50px; border-width: 10px; }
在線查看
一般來說,我們需要通過計算來解決這個問題,CSS開發者總是需要預先把容器設定得小一點(減去border以及padding占據的寬度)來最終達到理想的大小,讓人慶幸的是,現在你再也不用這麼苦逼了。
隨著日子一天一天過,人們越來越發現為容器的大小計算得非常苦逼,於是,一個名字叫box-sizing的CSS屬性新鮮出爐了。當你在容器當中設定box-sizing:border-box的時候,容器中的border和padding已經不能影響該容器的寬度了。下面的例子和上面的例子大部分都一樣,只是下面的例子多了個box-sizing:border-box;
.simple { width: 500px; margin: 20px auto; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .fancy { width: 500px; margin: 20px auto; padding: 50px; border: solid blue 10px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }
在線查看
這是目前為止保持寬度大小一致最好的解決辦法了,css開發者把下面CSS代碼放在他們的頁面上,這樣,頁面上所有容器都具備這種屬性了。
* { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }
這樣,頁面上的所有元素就可以得到更加直觀的排版。
由於box-sizing是相當新的屬性,你應該像我之前的例子那樣添加-webkit-和-moz-前綴,這樣在其對應的浏覽器中得到更好的顯示。IE8+支持這個屬性的。
擴展閱讀
- CSS3 Box-sizing
- Box Sizing
- A Look Into: CSS3 Box-Sizing
- box-sizing
- Start using CSS box-sizing today
- ‘box-sizing’ property
——大漠
為了應對更加復雜的布局需求,我們就不能忽略position這個屬性。它有一攬子有用的屬性,而且他們的名稱又抽象難記,好吧,我們一個一個地攻破它吧,不過你要做好打持久戰的心理准備哦。
.static { position: static; }
Static是元素與生俱來的默認屬性。它表示著不進行特殊的定位。一般來說static屬性表示該元素沒有被定位,而一旦把position屬性設定其他值的時候,那麼就表示該元素被定位了。
.relative1 { position: relative; } .relative2 { position: relative; top: -20px; left: 20px; background-color: white; width: 500px; }
relative表現跟staitc一樣,除非你另外添加了其他的屬性。
在相對(position:relative)定位的元素中設定top,left,right,bottom屬性都會使得改元素的位置發生改變。而且其他內容的位置不會因為該元素位置的改變而改變。
Fixed屬性值的元素相對於視窗進行相對定位,也就是不管你的滾動條滾到哪裡去,該元素總會出現在屏幕的相同位置。和position一樣,屬性top,right,bottom和left都會用上。
我想你一定注意到了在屏幕的右下方的fixed屬性。好吧,現在你可以仔細地研究研究它了,下面是相關的CSS代碼。
.fixed { position: fixed; bottom: 0; right: 0; width: 200px; background-color: white; }
一個fixed元素不會影響其在頁面中的已經定位了的布局。然而移動端的浏覽器對fixed屬性的支持卻表現得很差勁,這裡有相應的解決方案。
Absolute是最復雜的position屬性值了,absolute跟fixed相似,只是fixed相對於視窗進行定位,而absolute則是相對於最近的一個父系定位元素進行定位而已,如果absolute沒有父系定位元素的話,那麼他就相對文檔中的body元素,也就是說會跟隨頁面的滾動而移動。記住,被定位元素就是那些具備position屬性且屬性值不為static的元素。
下面是一個簡單的例子
.relative { position: relative; width: 600px; height: 400px; } .absolute { position: absolute; top: 120px; right: 0; width: 300px; height: 200px; }
class=“relative”,改元素屬於相對定位。如果該元素設定為position:static;那麼其子系絕對定位就不會脫離該元素,而跑去跟body對齊了。
class=“absolute”:該元素屬於絕對定位,相對於其父系進行定位。
這個東西非常棘手,但要想弄出一個優秀的CSS布局你就必須學習它。下面,將給大家帶來關於position更多優秀的例子。
在線查看
一個實際的例子能夠使我們對position的印象更加深刻。下面是一個真正的頁面布局
.container { position: relative; } nav { position: absolute; left: 0px; width: 200px; } section { /* position is static by default */ margin-left: 200px; } footer { position: fixed; bottom: 0; left: 0; height: 70px; background-color: white; width: 100%; } body { margin-bottom: 120px; }
在線查看
section中設置margin-left就是為了能夠給nav騰出足夠的空間,否則absolute元素就會和static元素相互重疊。
留意當你改變窗口大小的時候發生了什麼。效果非常不錯。
如果你對footer或者header設定了position:fixed;要記得給他們騰出個地方來,而對於footer我就在body中設定了一個margin-bottom的值給它。
在該容器高度大於nav的時候,能夠正常顯示。否則nav就會脫離container。接下來,我們將會為你繼續分析其他CSS布局技術的優劣之處。
擴展閱讀
- 十步圖解CSS的position
- Html和CSS高級指南之二——定位詳解
- CSS Positioning 101
- CSS Positioning: A Comprehensive Look
- position
——大漠
另一個要介紹的CSS布局屬性就是float。Float可以實現文字在圖片周圍浮動的效果,如下圖所示。
img { float: right; margin: 0 0 1em 1em; }
在線查看
擴展閱讀
- CSS的Float之一
- CSS的Float之二
- 應不應該使用inline-block代替float
- All About Floats
- CSS Floats 101
- Float vs. Inline-Block
——大漠
Clear就是一個控制float的一個有用屬性,我們可以對比下面的兩個例子:
<div class="box">...</div> <section>...</section>
.box { float: left; width: 200px; height: 100px; margin: 1em; }
在線查看
在這個例子中, section 元素實際上是在 div 之後的(譯注:DOM結構上)。然而 div 元素是浮動到左邊的,於是 section 中的文字就圍繞了 div ,並且 section 元素包圍了整個元素。如果我們想讓 section 顯示在浮動元素之後呢?
.box { float: left; width: 200px; height: 100px; margin: 1em; } .after-box { clear: left; }
在線查看
使用 clear 我們就可以將這個段落移動到浮動元素 div 下面。你需要用 left 值才能清除元素的向左浮動。你還可以用 right 或 both 來清除向右浮動或同時清除向左向右浮動。
當我們使用float的時候,有時候會遇到一些意外的棘手問題。
img { float: right; }
在線查看
噔噔噔~有個叫clearfix hack的方法來解決這個問題,但是有點煩人哦,讓我們來嘗試添加一個新的CSS語句。
.clearfix { overflow: auto; }
現在再看看發生了什麼:
在線查看
這個可以在現代浏覽器上工作。如果你想要支持IE6,你就需要再加入如下樣式:
.clearfix { overflow: auto; zoom: 1; }
有些獨特的浏覽器需要“額外的關照”。清除浮動這譚水很深很深,但是這個簡單的解決方案已經可以在今天所有的主要浏覽器上工作。
擴展閱讀
- Clear Float
- CSS Float Theory: Things You Should Know
- Page layout with floats and clearing
- Clearing floats
——大漠
看到布局到處都用到float那是再常見不過的事情了。下面的布局是我們之前介紹position的時候用到的,現在用float代替position也能夠實現相同的效果。
nav { float: left; width: 200px; } section { margin-left: 200px; }
在線查看
這個例子和之前那個外觀一模一樣。請注意我們在容器上做了“清除浮動”。原本在這個例子中是不需要的,但是當 nav 比非浮動的內容還要高時就需要了。
你可以使用百分比來進行布局,但是這個需要更多的代碼。在下面的實例中,當視窗太過狹小的時候這個nav容器會被壓扁。所以在選擇布局方案的時候,要考慮你設計到的內容。
article img { float: right; width: 50%; }
在線查看
你甚至還能同時使用 min-width 和 max-width 來限制圖片的最大或最小寬度!
你可以使用百分比來進行布局,但是這個需要更多的代碼。在下面的實例中,當視窗太過狹小的時候這個nav容器會被壓扁。所以在選擇布局方案的時候,要考慮你設計到的內容。
nav { float: left; width: 25%; } section { margin-left: 25%; }
在線查看
當布局很窄時, nav 就會被擠扁。更糟糕的是,你不能在 nav 上使用 min-width 來修復這個問題,因為右邊的那列是不會遵守它的。
“響應式設計”是一個網站根據在不同浏覽器以及設備平台上都能夠做出不同表現的效果的方案,你可以現在改變下視窗的大小,再也沒有比這更酷的了。
要做到這點,媒體查詢這步工作必不可少。現在讓我們用百分比寬度布局,接著調整浏覽器的大小,一直到其無法容納nav菜單的時候,布局開始就成了一列顯示,代碼如下。
@media screen and (min-width:600px) { nav { float: left; width: 25%; } section { margin-left: 25%; } } @media screen and (max-width:599px) { nav li { display: inline; } }
在線查看
現在我們的布局在移動浏覽器上也顯示的很棒。這裡有一些同樣使用了媒體查詢的著名站點。在MDN文檔中你還可以學到更多有關媒體查詢的知識。
在使用meta vIEwport之後,在移動端的布局會更加錦上添花。
擴展閱讀
- CSS3 Media QuerIEs
- 媒體查詢
- How To Use CSS3 Media QuerIEs To Create a Mobile Version of Your Website
- Media QuerIEs
- CSS Media QuerIEs & Using Available Space
- How to use CSS3 Orientation Media QuerIEs
——大漠
我們可以很好地使用網格來鋪滿整個浏覽器。在之前的很長一段時間中,我們都使用float來實現,但是現在inline-block能夠更輕易地完成任務。Inline-block跟inline差不多但是他們具備一個width和height。下面讓我們比較下兩者的例子吧。
.box { float: left; width: 200px; height: 100px; margin: 1em; } .after-box { clear: left; }
在線查看
你同樣能夠使用display:inline-block最後實現相同的結果。
.box2 { display: inline-block; width: 200px; height: 100px; margin: 1em; }
在線查看
如果需要IE6和IE7支持inline-block這個屬性值得話,你還需要做些工作。大家在談論inline-block的時候,你只需要記得在老式的浏覽器觸發一個叫haslayout的東西就可以了。如果你對這方面很感興趣的話,那麼請你點擊前面的鏈接,深入了解一下吧,如果沒有問題的話,我們繼續進入到下一步的學習。
你同樣可以使用inline-block來進行布局,但有些地方需要我們注意的:
nav { display: inline-block; vertical-align: top; width: 25%; } .column { display: inline-block; vertical-align: top; width: 75%; }
在線查看
擴展閱讀
- What’s the Deal With Display: Inline-Block?
- Using inline-block to Display a Product Grid VIEw
- Fighting the Space Between Inline Block Elements
- 如何解決inline-block元素的空白間距
- inline-block
——大漠
這裡有一系列新的CSS屬性,可以幫助你很輕松的實現文字的多列布局。讓我們瞧瞧:
.three-column { padding: 1em; -moz-column-count: 3; -moz-column-gap: 1em; -webkit-column-count: 3; -webkit-column-gap: 1em; column-count: 3; column-gap: 1em; }
在線查看
CSS column是非常新穎的屬性,因此你需要對其使用前綴標明,而且這個屬性不被IE9及以下和Opera Mini所支持。下面有更多與column相關的屬性,點擊這裡了解更多,沒問題的話,那我們繼續學習下一個。
擴展閱讀
- CSS3 Multi-columns 之column-gap column-rule
- CSS3 Multi-columns 之列數和列寬
- CSS3 Multi-columns 之跨列
- Multiple Columns Layout (Magazine-Alike) With CSS3
- An Introduction To The CSS3 Multiple Column Layout Module
- CSS Multi-column Layout Module
- CSS3 Multi-column layout
- Multiple Columns
——大漠
新的 flexbox 布局模式被用來重新定義CSS中的布局方式。很遺憾的是最近規范變動過多,導致各個浏覽器對它的實現也有所不同。不過我仍舊想要分享一些例子,來讓你知道即將發生的改變。這些例子目前只能在支持 flexbox 的 Chrome 浏覽器中運行,最新的標准。
網上有太多過時的flexbox相關資源。如果你想對flexbox有更深的了解,從這裡,學習識別關於flexbox資源是否是最新的。我已經整理出一篇關於最新標准的詳細文章。
使用flexbox你還可以做的更多;這裡只是一些讓你了解概念的例子:
.container { display: -webkit-flex; display: flex; } nav { width: 200px; } .flex-column { -webkit-flex: 1; flex: 1; }
在線查看
.container { display: -webkit-flex; display: flex; } .initial { -webkit-flex: initial; flex: initial; width: 200px; min-width: 100px; } .none { -webkit-flex: none; flex: none; width: 200px; } .flex1 { -webkit-flex: 1; flex: 1; } .flex2 { -webkit-flex: 2; flex: 2; }
在線查看
.vertical-container { display: -webkit-flex; display: flex; height: 300px; } .vertically-centered { margin: auto; }