CSS最大的用處之一就是能夠將內容和元素定位到任何咱們想要的位置,使咱們的設計具備結構,使內容更加易懂。css
CSS有好幾種不一樣的定位屬性,每種都有本身的使用場景。在這節課中咱們會經過不一樣的案例——可複用的佈局和針對單元素的佈局——來介紹每種方法。html
定位的其中一種方法就是使用float
屬性。float
屬性很是好用,能夠用在不少地方。前端
本質來講,float
屬性是使元素脫離正常的流式佈局,並將它放置在父元素的左側或右側。而後頁面中全部的元素都會環繞浮動元素佈局。例如咱們將段落間的一張圖片設置爲浮動,那麼這些段落都會圍繞圖片換行。segmentfault
當咱們將多個元素同時設置爲浮動元素,那麼這些元素將呈現相鄰或相對佈局,如多列布局。瀏覽器
float
有好幾個值,最經常使用的值是left
和right
。使元素浮動到父級元素的左側或右側。ide
img { float: left; }
咱們先建立一個通用頁面,含有頁頭,頁腳,中間有兩列。最理想的狀況就是在<body>
元素內建立第二節課"瞭解HTML"中提到的<header>
,<section>
,<aside>
和<footer>
元素。佈局
<header>...</header> <section>...</section> <aside>...</aside> <footer>...</footer>
<section>
和<aside>
元素都是塊狀元素,它們默認上下佈局。但咱們實際上想要它們並排顯示。因此在此,咱們就能夠將<section>
元素設爲左浮動,將<aside>
元素設爲右浮動,使它們呈現彼此相對的兩列。
CSS代碼以下:學習
section { float: left; } aside { float: right; }
在此提一下,元素設爲浮動後,會浮動到父級元素的邊緣。若是沒有父級元素,那麼它會浮動到頁面的邊緣。flex
當咱們設置一個元素爲浮動,咱們就將它從HTML文檔的正常流式佈局中取出,這就致使元素的默認寬度取決於其內容的寬度。有時咱們用可複用的佈局建立多列的時候並不但願如此,那就能夠爲列設置一個固定寬度。另外,爲了防止浮動元素緊靠在一塊兒,使內容彼此緊貼,可使用margin
屬性來建立元素間的空隙。
以下所示:網站
section { float: left; margin: 0 1.5%; width: 63%; } aside { float: right; margin: 0 1.5%; width: 30%; }
浮動會改變元素display的狀態
有一個重要的點須要記住:將元素設爲浮動就是將它從正常的流式佈局中脫離,而這會改變元素默認的display
值。float
屬性依賴於display
屬性爲block
的元素。若是一個元素的默認display
值不是block
,那麼它會將默認值改爲block
。
例如,span
是一個內聯元素,它默認的display
值爲inline
,width
和height
值是不生效的。然而,若是咱們將這個內聯元素設置爲浮動,那麼它的默認display
值會變成block
,這時候width
和height
值就生效了。
當咱們設置元素爲浮動時,都須要注意display
值的變化。
若只有兩列,咱們能夠將其中一個元素設置爲左浮動,另外一個元素設置爲右浮動,但如果多列的時候就須要換一種方法。例如,咱們但願在<header>
和<footer>
元素之間添加一行三列的結構,能夠先刪掉以前寫的<aside>
元素並使用三個<section>
元素,以下所示:
<header>...</header> <section>...</section> <section>...</section> <section>...</section> <footer>...</footer>
要將三個<section>
元素並排顯示,咱們再也不用以前的左浮動加右浮動的模式,而是將三個元素都設置爲左浮動。同時也要爲元素設置寬度使其排列更合理。
section { float: left; margin: 0 1.5%; width: 30%; }
如今呈如今咱們眼前的就是三列寬度和外邊距一致,都向左浮動的元素。
float
元素最初的設置是爲了在內容中插入圖片,使內容天然地環繞圖片顯示。雖然它在圖片中使用很是完美,可是float
屬性並非爲了定位和佈局設計的,因此在這方面存在一些缺陷。
其中一個缺陷就是浮動元素的下一個兄弟元素和父元素的樣式可能會渲染異常。當元素浮動時它脫離了正常佈局,致使圍繞在浮動元素周圍的元素的樣式都受到了影響。
最多見的就是margin
和padding
屬性值渲染異常,由於它們shi與浮動元素融爲一體。固然,也有一些其它的樣式也受到了影響。
另外一個缺陷是有時咱們不想內容圍繞環繞浮動元素顯示。浮動元素會從文件流中脫離,其餘元素會徹底佔有它周圍的空間,但不少時候咱們並不但願這樣。
在上述兩個元素並排顯示的例子中, 咱們將<section>
元素和<aside>
元素設爲浮動。在設置元素的width
屬性以前,咱們能夠看到<footer>
元素環繞兩個浮動元素顯示,佔用全部可用空間。如此,<footer>
元素就顯示在兩個浮動元素之間的凹槽中。以下所示:
爲了不這種狀況,咱們就須要將浮動元素包裹起來或者清除浮動,使它們回到正常文件流中。接下來,咱們先着眼於如何清除浮動,再來介紹怎麼包裹浮動元素。
清除浮動
清除浮動須要用到clear
屬性,它最經常使用的屬性值是:left
,right
,both
。
div { clear: left; }
屬性值left
清除左浮動,right
清除右浮動。both
清除同時左浮動和右浮動,這也是咱們最推薦使用的屬性值。
回到上例中,咱們爲<footer>
元素添加clear:both
屬性就能夠清除浮動了。清除浮動可使頁面迴歸正常文件流,因此很是重要。
footer { clear: both; }
包裹浮動元素
除了清除浮動,還能夠包裹浮動元素。這兩種方式頁面呈現的效果是差很少的,但包裹元素的方式還有助於確保樣式都渲染正常。
包裹元素就是將浮動元素置於父元素中,父元素做爲容器會置於正常的文件流中。咱們爲父元素添加一個class
屬性group
,併爲其設置CSS:
.group:before, .group:after { content: ""; display: table; } .group:after { clear: both; } .group { clear: both; *zoom: 1; }
上述寫了不少代碼,但實際上就是爲class值爲group
元素中的浮動元素清除浮動,使其迴歸正常文件流。
再具體點,代碼中使用了在第四節中有提到過的:before
和:after
兩個僞類,它們在class爲group
的元素先後分別添加了一個動態元素。這些元素不包含任何內容,並以與塊狀元素block
很類似的表格元素table
的形式呈現。動態生成的元素:after
清除了class爲group
的元素內的元素浮動。在.group
中設置的清除浮動則清除了排版在它之上的兄弟元素的浮動。老版本的瀏覽器也能夠很好的兼容。
clear:both
單獨聲明會很合適。
回到示例,咱們能夠將<section>
和<aside>
元素放置在一個父元素內,以下所示:
<header>...</header> <div class="group"> <section>...</section> <aside>...</aside> </div> <footer>...</footer>
.group:before, .group:after { content: ""; display: table; } .group:after { clear: both; } .group { clear: both; *zoom: 1; } section { float: left; margin: 0 1.5%; width: 63%; } aside { float: right; margin: 0 1.5%; width: 30%; }
這種包裹元素清除浮動的方式被稱爲clearfix
,咱們能夠很容易在其它網站中找到定義它的class名clearfix
或cf
。咱們示例中使用了group
,它表明一組元素,更好地表達了內容的意義。
設置浮動元素時咱們要時刻注意它是否影響了頁面的佈局,並確認是否已根據須要清除浮動。不清除浮動會致使不少頭疼的問題,尤爲當頁面多行多列排版的時候。
接下來,咱們打開「樣式討論會」網站來嘗試將一部份內容浮動。
main.css
中的grid樣式下添加清除浮動的樣式group
,以下所示:/* ======================================== Clearfix ======================================== */ .group:before, .group:after { content: ""; display: table; } .group:after { clear: both; } .group { clear: both; *zoom: 1; }
-如今咱們要將<header>
元素內的<h1>
設置爲左浮動,其餘元素環繞這個元素顯示。
先爲<h1>
添加一個class屬性,值爲logo
,並在CSS中將其設置爲左浮動:
<h1 class="logo"> <a href="index.html">Styles Conference</a> </h1>
/* ======================================== Primary header ======================================== */ .logo { float: left; }
<br/>
元素,使兩個單詞分兩行顯示。padding
。<h1 class="logo"> <a href="index.html">Styles <br> Conference</a> </h1>
.logo { border-top: 4px solid #648880; padding: 40px 0 22px 0; float: left; }
<h1>
設置爲浮動,那麼就須要在最靠近它的父級元素<header>
上添加class屬性值group
來清除浮動:<header class="container group"> ... </header>
<header>
元素上的操做已經完成,接着咱們來處理<footer>
元素。與<header>
元素設置類似,咱們將包含版權信息的<small>
設置爲左浮動,其餘元素圍繞這個元素顯示。<header>
不一樣的是,咱們不直接在浮動元素上添加class屬性設置浮動。咱們先爲其父元素添加一個class屬性值,而且使用這惟一的選擇器選中元素設置浮動。首先在<footer>
上添加class屬性值primary-footer
。因爲咱們已事先知道了要將<footer>
元素中的某個元素設爲浮動,因此在<footer>
中添加class屬性值group
。<footer class="primary-footer container group"> ... </footer>
<footer>
上添加了class屬性值primary-footer
。咱們能夠以其爲預選擇器選中<small>
元素並添加左浮動。以下所示:/* ======================================== Primary footer ======================================== */ .primary-footer small { float: left; }
primary-footer
的元素內的<small>
元素,例子中對應的就是<footer>
元素。<footer>
元素設置縱向padding
,使<footer>
的內容與其它內容分離。咱們能夠直接在primary-footer
上添加樣式:.primary-footer { padding-bottom: 44px; padding-top: 44px; }
<header>
和<footer>
的設置以後,咱們要將這些修改應用到每一個頁面中。
除了浮動,咱們也能夠經過display:inline-block
來佈局定位。它主要是幫助咱們作頁面佈局或同行元素間的的佈局。
在此回顧一下,display:inline-block
使元素同行顯示外,接受全部盒子模型的屬性,包括height
,width
,padding
,border
和margin
。inline-block
能夠充分使用盒子模型的全部屬性,而且不須要清除浮動。
咱們來看上述三列並排顯示的例子,HTML結構以下:
<header>...</header> <section>...</section> <section>...</section> <section>...</section> <footer>...</footer>
以前咱們爲<section>
元素設置了浮動,如今咱們以display:inline-block
來代替,並保留以前設置的margin
和width
。 CSS呈現以下:
section { display: inline-block; margin: 0 1.5%; width: 30%; }
此時,代碼並無很好的解決問題,最後一個<section>
元素掉到了下一行。行內塊元素是行內一個接着一個佈局,但它們之間有一個空格。當咱們將空格佔用的空間和全部元素的width
、margin
相加,那麼佔用寬度會很是大,會將最後一個<section>
擠到下一行。爲了讓全部<section>
顯示在同一行,咱們就須要把這些空格移除。
inline-block
元素之間的空格有好幾種方法能夠移除掉空格,但有些方法會相對複雜一些。咱們將介紹兩種最簡單的方法,都是應用在HTML中的。
第一中解決方案是將<section>
的開始標籤和前一個<section>
的結束標籤寫在同一行。一行內的代碼以開始標籤爲結尾,以下所示:
<header>...</header> <section> ... </section><section> ... </section><section> ... </section> <footer>...</footer>
用這種方法要確保HTML在書寫時元素之間時沒有空格,那麼最終渲染時頁面也不會呈現出空格。
另外一種方法是在元素之間添加註釋。結束標籤和開始標籤之間以註釋鏈接,註釋必須緊跟元素。這麼寫能夠容許HTML元素在書寫時換行,代碼以下:
<header>...</header> <section> ... </section><!-- --><section> ... </section><!-- --><section> ... </section> <footer>...</footer>
這兩種方法沒有一種是很是完美的,但它們都很好用。我(做者)更傾向於添加註釋的方案,由於它更利於排版,但你徹底能夠根據你的喜愛來選擇。
在構建網站時,編寫可複用的模塊是很是有益的,而可複用的佈局就是可複用代碼中很是重要的一部分。佈局可使用float
或者inline-block
元素的方法實現,但那一種方法更好呢?
這是值得商榷。我(做者)的作法是使用inline-block
元素實現頁面的網格或佈局,而當我想讓某部份內容環繞某個元素顯示時會使用float
(float
原本是用於處理圖片的)。並且我也發現inline-block
元素的佈局方式更簡單,更易處理。
和前面說的同樣,你能夠根據本身的須要選擇最合適的方案,若是你對其中一種方法更滿意,那你就能夠選擇它。
目前,新的CSS規範提到了flex
和grid-
開頭的屬性——它們有助於實現頁面的最佳佈局。要時常關注留意這些新的方法。
對可複用的佈局有所瞭解以後,咱們將其實施到咱們的Styles Conference
網站。
inline-block
元素來實現一個一排三列的可複用佈局。能夠將其分爲等寬的三列,或者分爲兩列,一列佔2/3寬,一列佔1/3寬。class
選擇器定義列寬width
,在main.css
文件中定義佔1/3寬的選擇器col-1-3
,佔2/3寬的選擇器col-2-3
。以下所示:.col-1-3 { width: 33.33%; } .col-2-3 { width: 66.66%; }
inline-block
元素的方式呈現,咱們就須要確保它們垂直對齊爲頂部對齊。.col-1-3, .col-2-3 { display: inline-block; vertical-align: top; }
col-1-3
,col-2-3
之間用逗號,
隔開。逗號表示第一個選擇器結尾,後面跟着第二個選擇器。第二個選擇器後跟隨大括號{
標識樣式開始申明。用逗號隔開選擇器可讓共用的樣式同時綁定到多個選擇器上。padding
。padding
屬性。grid
的class
選擇器,將其添加到共用的padding
定義中。代碼以下所示,選擇器以前一樣用逗號隔開:.grid, .col-1-3, .col-2-3 { padding-left: 15px; padding-right: 15px; }
padding
後,咱們須要當心。上節課中,咱們建立了一個寬度爲960px
,class名爲container
的元素,並相對於頁面左右居中。如今若是咱們將grid
元素嵌入container
元素中,那麼它們的橫向padding
就會相加,咱們的列與其餘的部分呈現出的寬度會不一致。container
和grid
選擇器共享一部分樣式。具體的來講,就是共享寬度width
(確保咱們的頁面固定在960px
寬)和外邊距margin
(使grid
元素居中),代碼以下所示:.container, .grid { margin: 0 auto; width: 960px; } .container { padding-left: 30px; padding-right: 30px; }
class
屬性包含有container
或者grid
的元素寬度都爲960px
,並相對於頁面居中。此外,咱們也將container
選擇器的橫向padding
分離寫到了另外一個樣式集中。index.html
主頁的三個宣傳欄開始,將它們設置爲三列。如今它們由一個class名爲container
的<section>
包裹。咱們要將這個container
替換爲grid
,以下所示:<section class="grid"> ... </section>
class
屬性col-1-3
添加到每一個gird
元素內的<section>
元素上:<section class="grid"> <section class="col-1-3"> ... </section> <section class="col-1-3"> ... </section> <section class="col-1-3"> ... </section> </section>
inline-block
元素,咱們要確保咱們移除了它們之間的間隙。咱們用註釋來完成這一工做,並在每塊中添加一些模塊說明,以便更好的組織咱們的代碼。<section class="grid"> <!-- Speakers --> <section class="col-1-3"> ... </section><!-- Schedule --><section class="col-1-3"> ... </section><!-- Venue --><section class="col-1-3"> ... </section> </section>
<\section>
後緊跟了註釋,在第9行添加了用以標識的註釋「Schedule」,並在11行開始標籤<section>
前閉合了註釋。相同的註釋結構貫穿第13行和第17行,標識內容替換爲Venue
。總的來講咱們已經將全部的間隙都註釋掉了併爲每一塊<section>
添加了標識。
這是練習的源代碼。點擊下載
咱們經常想要定位一個元素,但float
和inline-block
並不能知足這種需求。浮動將元素從正常的文檔流中移除,常常出現咱們不但願獲得的環繞浮動元素顯示的佈局。inline-block
元素,除非咱們建立多列,不然不易實現咱們想要的定位。針對這些狀況,咱們可使用position
屬性來作位置偏移。
position
屬性表示元素應該怎樣定位在頁面中,是否按正常文檔流顯示。這須要結合盒子的位移屬性——top
,right
,bottom
和left
——經過定義位移值設置不一樣方向的位p移來定位元素在什麼位置顯示。
position
屬性的默認值爲static
,他表示元素以正常文檔流呈現,而且不接受盒子位移屬性。static
經常會被relative
和absolute
這兩個值複寫。這就是咱們接下來要講的內容。
position:relative
在容許元素以正常文檔流呈現,保留元素的空間不被其餘元素佔用外,也容許元素經過修改位移屬性來定位,以下所示:
<div>...</div> <div class="offset">...</div> <div>...</div>
div { height: 100px; width: 100px; } .offset { left: 20px; position: relative; top: 20px; }
例子中第二個<div>
元素設置了class屬性爲offset
,offset
選擇器設置了position:relative
和兩個位移屬性left
和top
。這保留了元素原來的位置,不會被其餘元素佔用。另外位移屬性從新定位了元素的位置,使它向右偏移20px
,向下偏移20px
。
使用相對定位有一個重要的點要知道:盒子位移屬性是根據元素自己的位置來進行位移的。因此設置left:20px
就是將元素從左向右位移20px
。top:20px
就是元素至上向下位移20px
。
當使用position
對元素進位移時,該元素會與其餘元素重疊,而不是將其餘元素像使用了margin
和padding
同樣移到下面。
position:absolute
爲絕對定位,它與相對定位不一樣,絕對定位脫離了文檔流,而它原有的位置不會被保留。
另外,絕對定位的元素位移與離他最近的設置了相對定位的父級元素有關。若是沒有相對定位的父級元素,那麼絕對定位會根據<body>
來定位(譯者:根據個人實踐,瀏覽器在絕對定位的元素沒有相對定位的父級元素時,並非根據<body>定位,而是經過視窗的位置定位,有興趣的讀者能夠嘗試一下)
。這裏的信息量比較多,咱們經過例子來看一下:
HTML
<section> <div class="offset">...</div> </section>
section { position: relative; } div { position: absolute; right: 20px; top: 20px; }
在這個例子中,<section>
元素是不包含位移屬性的相對定位的元素,因此它沒有位移。div
元素設置了包含position: absolute
的class
屬性offset
。因爲<section>
是離它最近的設置了相對定位的父級元素,因此div
依賴<section>
元素的位置進行偏移
因爲設置了right
和top
位移,<div>
根據<section>
元素從右向左位移20px
,從上向下位移20px
。
因爲<div>
元素是絕對定位,它不在頁面的正常文檔流中,會與它周圍的元素重疊。另外,<div>
元素原來的位置也沒有被保留,其餘元素能夠佔據這個位置。
一般狀況下,大多數的定位都不須要經過定位和位移屬性來處理,但在某些狀況下它們確實很是有用。
學習如何經過HTML和CSS來定位內容是掌握這兩門語言很是重要的一步。再加上盒子模型,咱們正走在成爲前端開發者的路上。
回顧一下,在這節課中咱們所碰到的知識點:
inline-block
元素定位內容。inline-block
元素間的間隙。咱們每節課都在學習新的技能,因此讓咱們繼續。接下來,排版!