多欄自適應布局+水平垂直居中+清除浮動——集錦


前言

首先聲明在這篇博客里我將不會細說每一個知識點(比如什么是BFC,什么是flex等等),我主要是總結一下自己對標題中所列三個知識點的一些方法。

一、多欄自適應布局

首先,在這里我將從最簡單的兩欄固定布局慢慢講到多欄自適應布局。

1.固定布局

說到固定布局想必大家已經覺得無愛了,但我還是要簡單地講一下,下面通過一個簡單的實例進行講解:

html代碼:

<div class="wrap">
   <div class="left">left</div>
   <div class="right">right</div>
</div>

css代碼:

.wrap{
  width:500px;
  height:400px;
  border:1px solid red;
  margin:0 auto;
}
.left{
  width:200px;
  height:400px;
  background:#ccc;
}
.right{
   width:300px;
   height:400px;
   background:#ddd;
}

我們希望的布局效果是500px寬的容器內分別有一個200px寬和300px寬的子元素容器,可此時運行結果為:

5AUJTVB~)}IAM~3913()5F4_thumb[1]

這是因為div元素是塊級元素,默認是會占據整行的,於是我們就采用浮動的方法來解決這個問題。

此時我們只需要再添加如下樣式:

.left,.right{
  float:left;
}

那么就能得到我們想要的結果了:

NF`QG4~)Y)[)VY%TD}(YRJ2_thumb[2]

由於這里只有兩欄布局,而且都是固定布局,並且剛好占滿父容器,所以第二個子元素右浮動也是一樣的效果。但如果是多欄布局(比如四欄布局)並且剛好占滿父容器的話,那么最后一個可以是左浮動或者右浮動。

對於兩欄固定布局,其實並不一定兩個子元素都需要左浮動,可以第一個子元素左浮動,第二個設置margin-left值撐開就行了:

.left{
  float:left;
}
.right{
  margin-left:200px;
}

這樣也能實現上面的效果。但如果是多欄固定布局,個人覺得還是浮動比較方便。

在固定布局中,除了浮動之外,還有一種比較常用的方法就是定位。

把上面的樣式代碼改一改:

.wrap{
  position:relative;
}
.left{
  position:absolute;
  top:0;
  left:0;
}
.right{
   position:absolute;
   top:0;
   left:200px;
}

這樣寫同樣能達到之前的那種效果,但定位布局比較煩的就是得精確計算每一塊的位置。

所以,個人覺得目前固定布局一般會結合浮動+定位+必要時的內外邊距來進行布局會更加實用。當然了,浮動+定位+內外邊距也同樣適用於自適應布局,彼此之間都不是等號關系的。

2.兩欄自適應布局

同樣是上面的實例,我把它改成自適應布局:

.wrap{
  width:80%;
  height:400px;
  border:1px solid red;
  margin:0 auto;
}
.left{
  width:40%;
  height:100%;
  float:left;
  background:#ccc;
}
.right{
   width:60%;
   height:100%;
   float:left;
   background:#ddd;
}

此時運行看一下結果:

$Q3Q)~TMTM]_{%H8NL7()@T_thumb[1]

因為現在已經改成流式布局了,所以容器的寬度會隨着瀏覽器的寬度而按比例縮放。當然,需要配合浮動或者定位。

但是CSS3提供了一種更好的彈性伸縮布局flexbox,看看怎么實現:

.wrap{
  width:80%;
  height:400px;
  border:1px solid red;
  margin:0 auto;
  display:flex;
}
.left{
  flex:2;
  background:#ccc;
}
.right{
   flex:3;
   background:#ddd;
}

是不是更簡單。所以說,不管多少欄布局(實際開發中也不會很多欄的),通過流式布局或者flexbox彈性伸縮布局基本能解決。但目前來說,彈性布局兼容性還不是很好,所以用得比較多的還是移動端布局,但總體上更多的還是使用流式布局,必要時可以配合媒體查詢。

既有固定布局也有自適應布局

還是上面的實例,現在兩欄布局第一個子元素固定寬度,而第二個子元素自適應剩余的寬度,該怎么做?

第一種方法就是給第二個子元素加左外邊距,擠出來:

.wrap{
  width:80%;
  height:400px;
  border:1px solid red;
  margin:0 auto;
}
.left{
  width:200px;
  height:300px;
  float:left;
  background:#ccc;
}
.right{
   height:100%;
   margin-left:200px;
   background:#ddd;
}

結果就是這樣的:

72LU~RHH1XJ6O8FB8K$PK`L_thumb[1]

第二種方法就是絕對定位+外邊距:

.wrap{
  width:80%;
  height:400px;
  border:1px solid red;
  margin:0 auto;
  position:relative;
}
.left{
  width:200px;
  height:300px;
  background:#ccc;
  position: absolute;
  top:0;
  left:0;
}
.right{
   height:100%;
   background:#ddd;
   margin-left:200px;
}

但其實第一種方法和第二種方法原理是一樣的,換湯不換葯罷了。

第三種方法,利用BFC特性:

.wrap{
  width:80%;
  height:400px;
  border:1px solid red;
  margin:0 auto;
}
.left{
  width:200px;
  height:300px;
  background:#ccc;
  float:left;
}
.right{
   height:100%;
   background:#ddd;
   overflow: hidden;
}

這里給第二個子元素設置了overflow:hidden之后呢,它就生成了一個BFC塊,BFC其中的一個布局規則就是不會和float box 發生重疊,於是就和第一個浮動了的子元素隔開了,我說得比較蒼白,大家可以去多了解BFC的一些布局特性,包括如何生成一個新的BFC塊。那為了方便,我這里就把BFC的一些相關知識點直接放上來給大家了解一下:

BFC布局規則:
  • 內部的Box會在垂直方向,一個接一個地放置。
  • Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊
  • 每個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,否則相反)。即使存在浮動也是如此。
  • BFC的區域不會與float box重疊。
  • BFC就是頁面上的一個隔離的獨立容器,容器里面的子元素不會影響到外面的元素。反之也如此。
  • 計算BFC的高度時,浮動元素也參與計算
哪些元素會生成BFC:
  • 根元素
  • float屬性不為none
  • position為absolute或fixed
  • display為inline-block, table-cell, table-caption, flex, inline-flex
  • overflow不為visible

OK,還有一種方法就是flex布局:

.wrap{
  width:80%;
  height:400px;
  border:1px solid red;
  margin:0 auto;
  display:flex;
}
.left{
  width:200px;
  height:300px;
  background:#ccc;
}
.right{
   height:100%;
   background:#ddd;
   flex:1;
}

是不是也挺方便的?現在我提升一下難度,現在是三欄布局,左右欄固定寬度,中間自適應,該怎么做?

這時候flex布局就是最佳的選擇了:

.wrap{
  width:80%;
  height:400px;
  border:1px solid red;
  margin:0 auto;
  display:flex;
}
.left{
  width:200px;
  height:300px;
  float:left;
  background:#ccc;
}
.right{
    width:200px;
   height:300px;
   float:right;
   background:#ddd;
}
.center{
    height:100%;
    background:#666;
    flex:1;
}

這種本來就很苦惱的布局,對於flex布局來說都能輕松解決意外煩惱。

且慢,如果我想讓中間的子元素優先渲染呢?

<div class="wrap">
   <div class="center">中間自適應欄</div>
   <div class="left">左邊固定欄</div>
   <div class="right">右邊固定欄</div>
</div>

這時的情況是這樣的:

[{6O_ZOOV4ELX(~63{C]0UE_thumb[1]

這時候吧,還是得利用flex來解決這個問題:

.wrap{
  width:80%;
  height:400px;
  border:1px solid red;
  margin:0 auto;
  display:flex;
}
.left{
  width:200px;
  height:300px;
  float:left;
  background:#ccc;
  order:1;
}
.right{
    width:200px;
   height:300px;
   float:right;
   background:#ddd;
   order:3;
}
.center{
    height:100%;
    background:#666;
    flex:1;
    order:2;
}

這時候出來的效果就是我們想要的:

HRKDFY]ADRI9`BUQ){KZZTL_thumb[1]

好的,關於多欄自適應布局我就講到這里,其他方面的知識擴展與應用,就留給大家去研究了。

二、水平垂直居中

水平居中最常用的就是text-align:center; 和 margin:0 auto; 其中text-align:center;是對內部子元素(inline/inline-block)起作用,而margin:0 auto;是對元素自身(block)起作用,具體根據自己的需要適當地運用。

垂直居中常用的有line-height 和 vertical-align:middle,但是它們都有使用的限制條件或者前提吧。比如line-height得和height一樣高,vertical-align:middle 只對inline-block起作用,但其實還有很多坑,個人不怎么喜歡使用vertical-align。

下面我們就直接進入水平垂直居中的討論吧:

其實吧,水平垂直居中也是有兩種情況:知道寬高 和 不知道寬高。

1.已知寬高的水平垂直居中

在這種情況下,其實就很好解決了,實例說明一下:

html代碼:

<div class="wrap">
   <div class="child">水平垂直居中</div>
</div>

默認樣式:

.wrap{
  width:400px;
  height:400px;
  border:1px solid red;
  margin:0 auto;
}
.child{
  width:200px;
  height:200px;
  background:#ccc;
}

現在的情況是這樣的:

360截圖20150907094514427

因為我們是已知寬高的,所以可以給子元素加外邊距擠到中間位置,或者通過絕對定位到中間位置,當然還有一些方法,我就放在未知寬高的情況下再介紹,因為已知寬高包含於未知寬高,所以為了避免重復,我就分開了,這里就只講僅適合已知寬高的情況。

我們給子元素加上外邊距:

.child{
  margin-top:100px;
  margin-left:100px;
}

這時內部子元素就水平垂直居中了。

EXK{G1@JN8Y_7@R0M5VPCOT

現在使用絕對定位來實現:

.wrap{
  position:relative;
}
.child{
  position:absolute;
  top:50%;
  left:50%;
  margin-top:-100px;
  margin-left:-100px;
}

貌似絕對定位比較麻煩,但其實絕對定位對整體布局更好一些,也是比較常用。

2.未知寬高的水平垂直居中

1.絕對定位+css3 transform:translate(-50%,-50%)

.wrap{
  position:relative;
}
.child{
  position: absolute;
  top:50%;
  left:50%;
  -webkit-transform:translate(-50%,-50%);
}

2.css3 的flex布局

.wrap{
  display:flex;
  justify-content:center;
}
.child{
  align-self:center;
}

3.table布局

<div class="wrap">
   <div class="child">
          <div>sadgsdgasgd</div>
   </div>
</div>
.wrap{
  display:table;
  text-align:center;
}
.child{
  background:#ccc;
  display:table-cell;
  vertical-align:middle;
}
.child div{
    width:300px;
    height:150px;
    background:red;
    margin:0 auto;
}

table布局貌似得多套一層,試了好多遍,兩層都出不來效果。但是這種html結構太冗余了。所以前兩種比較新潮一些。

OK,水平垂直居中就講到這里,以上都是自己琢磨的一些方法,有什么紕漏或者不恰當的地方,歡迎留言指正。

三、清除浮動

這里就不講為什么我們要清楚浮動,反正不清除浮動事多多。

下面我就講三種常用清除浮動的方法,夠用了。

1.在浮動元素后面加一個空的div,並為它清除浮動

html代碼:

<div class="wrap">
   <div class="float">浮動</div>
   <div class="clear"></div>
   <div class="nofloat">不想被浮動影響</div>
</div>

css代碼:

.wrap{
  width:500px;
  height:400px;
  border:1px solid red;
  margin:0 auto;
}
.float{
  width:200px;
  height:200px;
  background:#ccc;
  float:left;
}
.nofloat{
    width:300px;
    height:150px;
    background:red;
}

現在雖然加了一個空的div,但是並沒有給它清除浮動,所以目前的效果就是第三個子元素.nofloat還是收到浮動的影響。

360截圖20150907132503001

OK,現在給.clear加上清除浮動:

.clear{
    clear:both;
}

刷新一下效果就出來了:

360截圖20150907132808775

PS:這種情況比較適合元素之間是垂直排列布局的,為了不受彼此浮動的影響。

2.利用BFC特性清除浮動

html代碼:

<div class="wrap">
   <div class="float">浮動</div>
   <div class="nofloat">不想被浮動影響</div>
</div>

css代碼:

.wrap{
  width:500px;
  border:1px solid red;
  margin:0 auto;
  overflow:hidden;
}
.float{
  width:200px;
  height:200px;
  background:#ccc;
  float:left;
}
.nofloat{
    width:300px;
    height:150px;
    background:red;
    overflow:hidden;
}

效果是這樣的:

360截圖20150907134136407

這里父容器是沒有設置固定高度的,本來第一個子元素浮動之后,父元素的高度會塌陷到跟第二個子元素一樣高,但由於這里分別給第二個子元素和父元素都設置了overflow:hidden ,所以它們都生成了一個新的BFC區域,根據上文提供的BFC布局規則可以得知:BFC區域不會與float box 重疊;計算BFC高度時浮動元素的高度也參與計算。所以就得到清除浮動的效果。說得比較繞,但其實清除浮動得根據自己開發中的實際情況合理使用。

3.使用:after偽元素,給浮動元素的父元素清除浮動

html代碼:

<div class="wrap">
   <div class="float">浮動</div>
</div>

css代碼:

.wrap{
  width:500px;
  border:1px solid red;
  margin:0 auto;
}
.float{
  width:200px;
  height:200px;
  background:#ccc;
  float:left;
}

此時子元素浮動了,脫離了文檔流,所以父元素高度酒塌陷了:

360截圖20150907134730403

可以看到父元素的邊框擠在一起了。

OK,現在給父元素添加一個clearfix類:

<div class="wrap clearfix">
   <div class="float">浮動</div>
</div>
.clearfix{
    *zoom:1;
}
.clearfix:after{
    content:'clear';
    display:block;
    height:0;
    clear:both;
    overflow:hidden;
    visibility:hidden;
}

現在刷新后的效果就是:

360截圖20150907135058497

這種方法和BFC清除浮動個人用的比較多,實際開發中,其實這兩種就夠用了。

好的,清除浮動我也就簡單地提到這里!

 

總結

以上我總結了自己對標題中列出的三個知識點——(多欄自適應布局,水平垂直居中,清除浮動)的一些個人積累。如果有什么錯誤的話,歡迎留言指正。

 

若需轉載,請注明出處,謝謝合作!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM