最全面的css佈局

1.定位

定位的概念就是它容許你定義一個元素相對於其餘正常元素的位置,它應該出如今哪裏,這裏的其餘元素能夠是父元素,另外一個元素甚至是瀏覽器窗口自己。還有就是浮動了,其實浮動並不徹底算是定位,它的特性很是的神奇,以致於它在佈局中被人普遍的應用。咱們會在後文中專門說起它的。css

談及定位,咱們就得從position屬性提及。你能準確的說出position的屬性值嗎?相信你能夠完美地說出這麼六個屬性值:static、relative、absolute、fixed、sticky和inherit。html

  • static(默認):元素框正常生成。塊級元素生成一個矩形框,做爲文檔流的一部分;行內元素則會建立一個或多個行框,置於其父元素中。
  • relative:元素框相對於以前正常文檔流中的位置發生偏移,而且原先的位置仍然被佔據。發生偏移的時候,可能會覆蓋其餘元素。
  • absolute:元素框再也不佔有文檔流位置,而且相對於包含塊進行偏移(所謂的包含塊就是最近一級外層元素position不爲static的元素)
  • fixed:元素框再也不佔有文檔流位置,而且相對於視窗進行定位
  • sticky:(這是css3新增的屬性值)粘性定位,官方的介紹比較簡單,或許你不能理解。其實,它就至關於relative和fixed混合。最初會被看成是relative,相對於原來的位置進行偏移;一旦超過必定閾值以後,會被當成fixed定位,相對於視口進行定位。

簡單地,介紹一下position的屬性值的含義後,在來看一下偏移量top、right、bottom、left四個屬性。css3

不清楚,當初在初學css的時候,會不會與margin這個屬性混淆?其實,它們之間是很容易去辨識地。由於這四個屬性值,實際上是,定位時的偏移量。偏移量不會對static的元素起到做用。而margin,相對應的是盒子模型的外邊距,它會對每一個元素框起到做用,使得元素框與其餘元素之間產生空白。瀏覽器

下面:咱們來看一下一些經常使用定位的偏移app

  • relative:它的偏移是相對於原先在文檔流中的位置
  • absolute:它的偏移量是相對於最近一級position不是static的祖先元素的
  • fixed:它的偏移量是相對於視口的。

其實,這裏說描述的內容,應該都是須要理解的。這些相對於佈局來講是基礎的,同時也是很是重要的。須要注意的是,這裏的偏移量其實已經涉及到了接下來要說的尺寸。在作自適應佈局設計時,每每但願這些偏移量的單位可以使用百分比,或者相對的單位例如rem等。佈局

2.尺寸

那以前上面談到過尺寸的單位——百分比。那麼,下面部分咱們就圍繞着尺寸單位展開。字體

尺寸,咱們就應該從單位聊起,對於px這個單位,作網頁的應該在熟悉不過了,所以很少作介紹。flex

那麼,咱們能夠來介紹一下下面幾個單位:spa

  • 百分比:百分比的參照物是父元素,50%至關於父元素width的50%
  • rem:這個對於複雜的設計圖至關有用,它是html的font-size的大小
  • em:它雖然也是一個相對的單位,相對於父元素的font-size,可是,並不經常使用,主要是計算太麻煩了。

單位只是一個來定義元素大小的相應參考。另外一個概念,或許能夠用房子來打一個比方,在早年每幢房子都會在房子的外圍建一層柵欄,使得整一塊地區能夠當作房子+內部地塊+柵欄+外圍地塊的模型。而在css中,每一個元素也會有盒子模型的概念。設計

盒子模型:每一個元素,都會造成一個矩形塊,主要包括四部分:margin(外邊距)+border(邊框)+padding(內邊距)+content(內容)

css中存在兩種不一樣的盒子模型,能夠經過box-sizing設置不一樣的模型。兩種盒子模型,主要是width的寬度不一樣

這是標準盒子模型,能夠看到width的長度等於content的寬度;而當將box-sizing的屬性值設置成border-box時,盒子模型的width=border+padding+content的總和。

能夠看出,對於不一樣的模型的寬度是不一樣的。寬度默認的屬性值是auto,這個屬性值會使得內部元素的長度自動填充滿父元素的width。

 

可是,height的屬性值也是默認的auto,爲何沒有像width同樣呢?

其實,auto這個屬性值表示的是瀏覽器自動計算。這種自動計算,須要一個基準,通常瀏覽器都是容許高度滾動的,因此,會致使一個問題——瀏覽器找不到垂直方向上的基準。

一樣地道理也會被應用在margin屬性上。相信若是考察居中時,水平居中你可能閉着眼睛都能寫出來,可是垂直居中卻繞着腦殼想。這是由於若是是塊級元素水平居中只要將水平方向上的margin設置成auto就能夠了。可是,垂直方向上卻沒有這麼簡單,由於你設置成auto時,margin爲0。這個問題,仍是須要仔細思考一下的。

到此爲止,佈局最基本的部分咱們已經將去大半,還有就是一塊浮動。

3.浮動

浮動,這是一個很是有意思的東西,在佈局中被普遍的應用。最初,設計浮動時,其實並非爲了佈局的,而是爲了實現文字環繞的特效

可是,浮動並非僅僅這樣而已。何爲浮動?浮動應該說是‘自成一派’,相似於ps中的圖層同樣,浮動的元素會在浮動層上面進行排布,而在原先文檔流中的元素位置,會被以某種方式進行刪除,可是仍是會影響佈局。你可能會以爲有疑問,什麼叫影響佈局?咱們能夠來舉個例子:

 

能夠,發現雖然left塊由於左浮動,而使得原先元素在文檔流中佔有的位置被刪除,可是,當right塊補上原先的位置時,right塊中的字體卻被擠出來了。這就是所謂的影響佈局。

浮動爲何會被使用在佈局中呢?由於設置浮動後的元素會造成BFC(使得內部的元素不會被外部所幹擾),而且元素的寬度也再也不自適應父元素寬度,而是適應自身內容。這樣就能夠,輕鬆地實現多欄佈局的效果。

浮動的內容還須要介紹一塊——清除浮動。能夠看到,浮動元素,其實對於佈局來講,是特別危險的。由於你可能這一塊作過浮動,但未作清除,那麼形成高度塌陷的問題。就是上面圖示的那種狀況。

清除浮動,最經常使用的方法有兩種:

  • overflow: 將父元素的overflow,設置成hidden。
  • after僞類:對子元素的after僞類進行設置。

這裏只是稍微的提上一嘴。下面咱們正式來介紹一下網頁的佈局,本篇最核心的東西。

4.最初的佈局——table

最初的時候,網頁簡單到可能只有文字和連接。這時候,你們最經常使用的就是table。由於table能夠展現出多個塊的排布。

這種佈局如今應該不經常使用了,由於在形色單一時,使用起來方便。可是,如今的網頁變得愈來愈複雜,適配的問題也是愈來愈多,這種佈局已經再也不時候了。

主要是div塊的出現,可使得網頁進行靈活的排布,使得網頁變得繁榮。這時,開發者也開始思索如何去更加清晰地分辨網頁的層次。接下來,咱們能夠看看有哪些比較出名的佈局方式。

5.兩欄佈局

是否記得,那些一邊主體內容,一邊目錄的網頁,如圖:

 

相似於上圖的佈局,能夠定義爲兩欄佈局

兩欄佈局:一欄定寬,一欄自適應。這樣子作的好處是定寬的那一欄能夠作廣告,自適應的能夠做爲內容主體。

實現的方式:

  1. float + margin:
<body>
  <div class="left">定寬</div>
  <div class="right">自適應</div>
</body>
.left{
  width: 200px;
  height: 600px;
  background: red;
  float: left;
  display: table;
  text-align: center;
  line-height: 600px;
  color: #fff;
}

.right{
  margin-left: 210px;
  height: 600px;
  background: yellow;
  text-align: center;
  line-height: 600px;
}

 

其餘的方法:還可使用position的absolute,可使用一樣的效果

6.三欄佈局

三欄佈局,也是常常會被使用到的一種佈局。

它的特色:兩邊定寬,而後中間的width是auto的,能夠自適應內容,再加上margin邊距,來進行設定。

三欄佈局能夠有4種實現方式,每種實現方式都有各自的優缺點。

1.使用左右兩欄使用float屬性,中間欄使用margin屬性進行撐開,注意的是html的結果

<div class="left">左欄</div>
<div class="right">右欄</div>
<div class="middle">中間欄</div>
.left{
  width: 200px;height: 300px; background: yellow; float: left;    
}
.right{
  width: 150px; height: 300px; background: green; float: right;
}
.middle{
  height: 300px; background: red; margin-left: 220px; margin-right: 160px;
}

 

缺點是:1. 當寬度小於左右兩邊寬度之和時,右側欄會被擠下去;2. html的結構不正確

2. 使用position定位實現,即左右兩欄使用position進行定位,中間欄使用margin進行定位

<div class="left">左欄</div>
<div class="middle">中間欄</div>
<div class="right">右欄</div>
.left{
    background: yellow;
    width: 200px;
    height: 300px;
    position: absolute;
    top: 0;
    left: 0;
}
.middle{
    height: 300px;
    margin: 0 220px;
    background: red;
}
.right{
    height: 300px;
    width: 200px;
    position: absolute;
    top: 0;
    right: 0;
    background: green;
}

 

 

好處是:html結構正常。

缺點時:當父元素有內外邊距時,會致使中間欄的位置出現誤差

3. 使用float和BFC配合聖盃佈局

將middle的寬度設置爲100%,而後將其float設置爲left,其中的main塊設置margin屬性,而後左邊欄設置float爲left,以後設置margin爲-100%,右欄也設置爲float:left,以後margin-left爲自身大小。

<div class="wrapper">
    <div class="middle">
        <div class="main">中間</div>
    </div>
    <div class="left">
        左欄
    </div>
    <div class="right">
        右欄
    </div>
</div>
 
.wrapper{
    overflow: hidden;  //清除浮動
}
.middle{
    width: 100%;
    float: left;
}
.middle .main{
    margin: 0 220px;
    background: red;
}
.left{
    width: 200px;
    height: 300px;
    float: left;
    background: green;
    margin-left: -100%;
}
.right{
    width: 200px;
    height: 300px;
    float: left;
    background: yellow;
    margin-left: -200px;
}

7.彈性佈局(flex)

彈性盒子(Flexbox)佈局是一種爲一維佈局而設計的佈局方法。一維的意思是你但願內容是按行或者列來佈局。你可使用display: flex來將元素變爲彈性佈局。

.container {
    display: flex;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

該容器的直接子元素會變爲彈性項(flex item),並按行排列。

如圖:

7.1. 彈性盒子的軸(axes)

在上面的例子中,咱們會稱彈性項在行內是從起始位置開始排列,而不是說它們是左對齊。這些元素會按行排列是由於默認的flex-direction值爲rowrow表明了文本的行文方向。因爲咱們工做的環境是英文(中文也是如此),一種自左向右的語言,行的開始位置就是在左邊,所以咱們的彈性項也是從左邊開始的。所以flex-direction的值被定義爲彈性盒子的主軸(main axis)。

交叉軸(cross axis)則是和主軸垂直的一條軸。若是你的flex-directionrow而且彈性項是按照行內方向排列的,那麼交叉軸就是塊級元素的排列方向。若是flex-directioncolumn那麼彈性項就會以塊級元素排列的方向排布,而後交叉軸就會變爲row

若是你習慣於從主軸與交叉軸的角度來使用彈性盒子,那麼一切會變得很是簡單。

7.2. 方向和次序

彈性盒子模型讓咱們能夠經過爲flex-direction屬性設置row-reversecolumn-reverse值來改變主軸上彈性項的方向。

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: flex;
  flex-direction: row-reverse;
}

.item {
  width: 100px;
  height: 100px;
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}

7.3. 一些Flex的屬性

這些flex的屬性是用來控制彈性項在主軸上空間大小的。這三個屬性是:

  • flex-grow
  • flex-shrink
  • flex-basis

一般可使用它們的簡寫形式:flex。第一個值表明flex-grow,第二個是flex-shrink,而第三個則是flex-basis

.item {
    flex: 1 1 200px;
}

flex-basis會爲彈性項設置未拉伸和壓縮時的初始大小。在上面的例子中,大小是200px,所以咱們會給每一個項200px的空間大小。可是大多數狀況下容器元素大小不會正好被分爲許多200px大小的項,而是可能有一些不足或剩餘空間。flex-growflow-shrink屬性容許咱們在容器大小不足或有空餘時控制各個彈性項的大小。

若是flex-grow的值是任意的正數,那麼彈性項會被容許拉伸來佔據更多的空間。所以,在上面的例子中,當各項被設爲200px後,全部多餘的空間會被每一個彈性項平分並填滿。

若是flex-shrink的值爲任意的正數,那麼當彈性項被設置了flex-basis後,元素溢出容器時會進行收縮。在上面這個CSS的例子中,若是容器空間不足,每一個彈性項會等比例縮放以適應容器的大小。

flex-growflex-shrink的值能夠是任意的正數。一個具備較大flex-grow值的彈性項會在容器有剩餘空間時拉伸更大的比例;而一個具備更大flex-shrink值的項則會在容器空間不足時被壓縮的更多。

1 <div class="container">
2   <div class="item">1</div>
3   <div class="item">2</div>
4   <div class="item">3</div>
5 </div>
 1 body {
 2   padding: 20px;
 3   font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
 4 }
 5 
 6 * {box-sizing: border-box;}
 7 
 8 p {
 9   margin: 0 0 1em 0;
10 }
11 
12 .container {
13   width: 500px;
14   border: 5px solid rgb(111,41,97);
15   border-radius: .5em;
16   padding: 10px;
17   display: flex;
18 }
19 
20 .item {
21   flex: 1 1 0;
22   width: 100px;
23   height: 100px;
24   padding: 10px;
25   background-color: rgba(111,41,97,.3);
26   border: 2px solid rgba(111,41,97,.5);
27 }
28 
29 .container :first-child {
30   flex: 2 1 0; 
31 }

8. 網格佈局(grid layout)

CSS網格佈局(grid layout)是一種用來進行二維佈局的技術。二維(two-dimesional)意味着你但願按照行和列來排布你的內容。和彈性盒子相似,網格佈局也須要設置一個display值。你能夠爲容器元素設置display: grid,而且使用grid-template-columnsgrid-template-rows屬性來控制網格中的行與列。

.container {
    display: grid;
    grid-template-columns: 200px 200px 200px;
    grid-template-rows: 200px 200px;
}

上面這段CSS會建立一個行列元素大小固定的網格。不過這也許並非你但願的。默認值爲auto,你能夠認爲這表明了「讓格子儘量的大」。若是你每沒有指定行(row track)的大小,全部添加進來的行內容大小都會被置爲auto。一種經常使用的模式是爲網格制定列寬度,可是容許網格按需添加行。

你可使用任意的長度單位或時百分比來設置行與列,同時你可使用爲網格系統所創造的新的單位——frfr是一種彈性單位,它能夠指定網格容器內的空間被如何劃分。

網格會替你計算與分配空間,你不須要去計算元素的百分比去適應容器大小。在下面這個例子中,咱們使用fr來建立網格的列,這使得網格的列能夠自適應。同時咱們還使用了grid-gap來保證元素間的間距(關於網格內元素與的間距會在「對齊」這一部分詳細介紹)。

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5<br>has more content.</div>
</div>
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 20px;
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}

相關文章
相關標籤/搜索