【譯】關於CSS中的float和position

原文地址:http://www.cnblogs.com/newyorker/archive/2013/02/01/2886282.html


當構建頁面排版時,有不同的方法可以使用。使用哪一種方法取決於具體頁面的排版要求,在不同的情況下,某些方法可能好過於其他的方法。

比如,可以使用若干個浮動元素來構建一個整潔簡潔的頁面排版。或者,如果需要更復雜的排版要求,可以考略使用其他方法,比如使用相對定位和絕對定位。

在這篇文章中,我們首先要討論元素浮動;然後,我們要討論如何使用x,y和z軸控制元素的位置。

 

元素浮動

當構建一個頁面的排版時,使用元素浮動是一種直觀的方法去控制元素的位置。元素浮動可以讓一個元素靠近或者遠離另一個元素。它根據一個元素的大小和其父節點容器的大小來構造這個元素在排版中與其他元素之間的關係。

當一個元素被浮動時,這個元素是挨着前一個元素,還是出現在新的一行?這取決於它相鄰元素的位置。

當然,元素浮動在提供強大威力的同時,也帶來了很多問題。一個著名的問題就是,當一個父節點包括了若干浮動的子元素時,父節點的排版會考慮到浮動子元素的大小和位置,但是子元素並不會影響父節點的大小。在這種情況下,父節點的height變成了0,並且忽略其他屬性。 很多時候,這個問題沒有被注意到,特別是當父節點沒有附合任何的CSS樣式,而且嵌套的元素也看上去被正確地排列了。

如果沒有正確地排列嵌套元素,那麼可能引發排版上的錯誤。請參閱下面的這個例子, 類名爲.box-set的DIV容器應該有淺灰色的背景,但是因爲其嵌套元素都是浮動元素,所以原本期望的背景色沒有出現。如果你查看.box-set的盒模型,你會發現它的height值爲0。

<div class="box-set">
  <div class="box">Box 1</div>
  <div class="box">Box 2</div>
  <div class="box">Box 3</div>
</div>
複製代碼
.box-set {
  background: #e8eae9;
}
.box {
  background: #8ec63f;
  height: 100px;
  float: left;
  margin: 10px;
  width: 200px;
}
複製代碼

一個解決方法是在父容器閉合標籤前加上一個空元素,並且設置它的clear : both。“清除浮動元素”這一招可以解決大多數情況,但是它並不是“語義正確”的。隨着頁面上需要清除的浮動元素 的數量增加,需要的空節點的數量也隨之增加,但是這些空節點並沒有任何的HTML語義。

幸運的是,有一些其他技巧同樣使用,最著名的就是使用overflow和clearfix的技巧。

 

使用overflow

在父容器上設置 overflow:auto 可以讓它自動包含子元素,從而具有了實際的height值,這樣上例中的灰色背景將得到顯示。

在IE6中使用這一招時需要給父節點容器設置height或者width屬性。因爲實際情況中height常常是可變的,所以是設置width的值。對於蘋果平臺上的IE,設置overflow:auto將會給容器增加滾動條,所以最好是設置 overflow : hidden 。

.box-set {
  background: #404853;
  overflow: auto;
}

這一招有些副作用。例如,需要增加樣式或者移動子元素超出了父容器的範圍時,比如實現邊框陰影或者加上一個下拉菜單。在下面的例子中你將看到,當邊框陰影超出父容器的範圍時就會被遮蓋了,同時第二個子元素排列有問題。

 

使用clearfix

clearfix通常搭配 :before 或者 :after 僞元素使用。使用僞元素就是在包含浮動元素的父容器的前面或者後面創造一個隱藏的元素。通過對 :before 僞元素使用 display:table 來創建一個匿名的table-cell元素,從而防止子元素的top margin消失。這一招在IE6和7中具有一致的效果。同樣的,通過設置 :after 僞元素來防止子元素的bottom margin消失。

另外需要對父容器使用 *zoom 屬性觸發hasLayout機制來解決IE6和7的一致性。hasLayout機制決定了元素應該怎樣渲染和框住它的內容,以及元素間的位置關係。

在下面使用clearfix例子,你將看到元素就算超出了父容器也可以顯示了。注意邊框陰影

複製代碼
.box-set:before,
.box-set:after {
  content: "";
  display: table;
}
.box-set:after {
  clear: both;
}
.box-set {
  *zoom: 1;
}
複製代碼

 

有效地包含浮動元素

具體使用哪一個技巧取決於你的個人習慣。有些人傾向於使用clearfix技巧,因爲它在跨瀏覽器上的一致性更好。另一些人覺得clearfix需要更多的代碼。因此,選擇哪個技巧不重要,重要的是註釋註明和寫進文檔。

一個常見的實現就是給所有需要包含浮動元素的父容器一個統一的類名,方便管理樣式。比如使用下列代碼,這樣只需給需要包含浮動元素的父節點加上 group的類名即可。

複製代碼
.group:before,
.group:after {
  content: "";
  display: table;
}
.group:after {
  clear: both;
}
.group {
  *zoom: 1;
}
複製代碼

 

Position屬性

有些情況下,你需要更多的對元素位置的控制,這時候就需要使用position屬性了。position屬性一共有五種不同的取值。

 

Position Static

這是position屬性的默認取值,意味着這個元素沒有也不接受任何對於該元素的位置偏移量屬性。

在下列的例子中,所有的盒子都將一個接一個的堆起來。因爲它們都是塊級元素,並且沒有被浮動。

複製代碼
<div class="box-set">
  <div class="box box-1">Box 1</div>
  <div class="box box-2">Box 2</div>
  <div class="box box-3">Box 3</div>
  <div class="box box-4">Box 4</div>
</div>
複製代碼
複製代碼
.box-set {
  background: #e8eae9;
}
.box {
  background: #8ec63f;
  height: 80px;
  width: 80px;
}
複製代碼

 

Position Relative

relative定位非常相識於static定位。最大的區別就是相對定位的元素可以使用偏移量:top, right, bottom, left。這四個偏移量可以讓元素朝任何方向移動,從而精確的控制顯示出來的位置。

注意儘管相對定位的元素可以使用偏移量屬性,但是它在網頁排版時按照的是跟static position相同的方式(這點區別於fixed position和absolute position)。另外,相對定位的元素可以覆蓋其它元素,或者被其它元素覆蓋,儘管它自身並沒有偏移。

在下列的例子中,所有的盒子都是一個接一個的堆起來。但是他們按照各自被定義的offset相對於原本的位置做了改變。所以,有些盒子覆蓋了其他的盒子,而不是推開其他盒子。如果一個元素是相對定位(甚至它還做了偏移),它周圍的元素排版參考的依然是那個元素原本的位置(沒有偏移時的位置)。

複製代碼
<div class="box-set">
  <div class="box box-1">Box 1</div>
  <div class="box box-2">Box 2</div>
  <div class="box box-3">Box 3</div>
  <div class="box box-4">Box 4</div>
</div>
複製代碼
複製代碼
.box-set {
  background: #e8eae9;
}
.box {
  background: #8ec63f;
  height: 80px;
  position: relative;
  width: 80px;
}
.box-1 {
    top: 20px;
  }
.box-2 {
  left: 40px;
}
.box-3 {
  bottom: -10px;
  right: 20px;
}
複製代碼

如果同時聲明top和bottom的值,那麼top值的優先級更高。如果同時聲明left和right的值,那麼優先級取決於網頁的語言(例如,英語法語德語西班牙語)。比如,在英語的網頁中,left的優先級更高;在阿拉伯語的網頁right優先級更高

 

Position Absolute

絕對定位的元素接受偏移量。在排版中,絕對定位的元素從原來的位置上被抹去了(因此它後面的元素將佔領它目前的位置),然後根據它的相對定位的父節點的位置定位。如果它沒有相對定位的父節點,那麼元素直接參考body容器定位。

對絕對定位的元素使用偏移量屬性,這個元素將以相對定位的父節點作爲參考系進行偏移。

如果沒有對絕對定位的元素使用偏移量屬性,那麼該元素將被放置在父節點的左上角。如果只設置了top屬性,那麼該元素則只做垂直方向的偏移,而水平方向依然靠着父節點的最左邊。

在下面的例子中,所有的盒子相對於父容器作了絕對定位。如果偏移量是正數,那麼盒子被“往裏推”了;如果偏移量是負數,那麼盒子被“往外拉”了。

複製代碼
<div class="box-set">
  <div class="box box-1">Box 1</div>
  <div class="box box-2">Box 2</div>
  <div class="box box-3">Box 3</div>
  <div class="box box-4">Box 4</div>
</div>
複製代碼
複製代碼
.box-set {
  background: #e8eae9;
  height: 200px;
  position: relative;
}
.box {
  background: #8ec63f;
  height: 80px;
  position: absolute;
  width: 80px;
}
.box-1 {
  top: 6%;
  left: 2%;
}
.box-2 {
  top: 0;
  right: -40px;
}
.box-3 {
  bottom: -10px;
  right: 20px;
}
.box-4 {
  bottom: 0;
}
複製代碼

如果絕對定位的元素有固定的height和width值

如果同時聲明top和bottom的值,那麼top值的優先級更高。如果同時聲明left和right的值,那麼優先級取決於網頁的語言(例如,英語法語德語西班牙語)。比如,在英語的網頁中,left的優先級更高;在阿拉伯語的網頁right優先級更高

如果絕對定位的元素沒有固定的height或者width值:

如果元素並沒有固定height值,可是卻同時有top和bottom的值,那麼該元素將橫跨除了top和bottom之外剩下的所有高度。同理,如果元素並沒有固定width值,可是同時有left和right的值,那麼該元素將橫跨除了left和right之外剩下的所有寬度。如果元素既沒有固定height和width值,卻同時有top, bottom, left, right值,那麼該元素將佔據除了四條邊距離之外的所有空間。

 

Position Fixed

固定定位的元素跟絕對定位的元素很相似,只不過它參照的座標系是瀏覽器的視口(viewport)。固定定位的元素不隨着頁面滾動而移動,它會始終保持在那個位置。另外,在IE6中使用固定定位有一個BUG,需要使用一些hack來解決。

一個典型的使用固定定位的例子是網頁中的頂部橫條或者底部橫條。當用戶滾動頁面時,那個橫條始終停留在瀏覽器視口的頂部或者底部。

<footer>Fixed Footer</footer>
複製代碼
footer {
  bottom: 0;
  left: 0;
  position: fixed;
  right: 0;
}
複製代碼

 

z-index 屬性

網頁是一個二維空間,根據x軸和y軸展示各個元素。可是,如果你需要讓某個元素放置在其他元素的上面(可在默認的排版中,她並不是在他的上面),這時你可以改變她的z-index屬性,讓她跑到他的上面。

元素在z軸的位置的位置取決於它在DOM中出現的先後順序。如果兩個元素髮生重疊,先在DOM中出現的元素通常排在後出現元素的下面。改變先出現元素的z-index屬性是一個簡單的方法讓他出現在更上面。擁有最高z-index屬性的元素永遠被排在最上面,與它在DOM樹中的位置無關。

如果你需要設置一個元素的z-index屬性,你必須首先設置這個元素是relative,absolute或者fixed定位。就像對於設置top, bottom, left, right屬性一樣。

複製代碼
<div class="box-set">
  <div class="box box-1">Box 1</div>
  <div class="box box-2">Box 2</div>
  <div class="box box-3">Box 3</div>
  <div class="box box-4">Box 4</div>
</div>
複製代碼
複製代碼
.box-set {
  background: #e8eae9;
  height: 160px;
  position: relative;
}
.box {
  background: #8ec63f;
  border: 3px solid #f7941d;
  position: absolute;
}
.box-1 {
  left: 10px;
  top: 10px;
}
.box-2 {
  bottom: 10px;
  left: 70px;
  z-index: 3;
}
.box-3 {
  left: 130px;
  top: 10px;
  z-index: 2;
}
.box-4 {
  bottom: 10px;
  left: 190px;
  z-index: 1;
}
複製代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章