一,盒模型
說到 CSS 佈局這塊的內容,首當其衝的就是我們的盒模型寬度計算問題,在開始我們的問題之前,我們首先要搞懂這些概念:
- 盒模型裡面的內容(
content
): 也就是實實在在要展現的內容,比如 P 標籤裡面的文字。在沒有設定box-sizing: border-box
之前我們可以把它的寬度理解為就是width
的值,不包括padding
和border
- 盒模型的內邊距(
padding
): 是內容與邊框內部之間的距離 - 盒模型的邊框(
border
): 邊框也可以設定寬度 - 盒模型的外邊距(
margin
): 盒模型的邊框外部與其他盒模型邊框外部之間的距離
瞭解了這些,我們再來看下面的幾個進階概念:
offsetWidth
: 指的是盒模型的邊框(border
) + 內邊距(padding
) + 內容的寬度(width
)clientWidth
: 指的是盒模型的內邊距(padding
) + 內容的寬度(width
)scrollWidth
: 如果內容超出邊框,需要有滾動條,那麼scrollWidth
獲取的是整個文件的內容(而clientWidth
獲取的只是可見部分的寬度)
OK,我們來看一道簡單的計算題
<style>
#main {
width: 100px;
border: 1px solid #ccc;
padding: 10px
}
</style>
//offsetWidth => 122px
很明顯,我們想要的結果offsetWidth
就等於 100+20+2=122px。那麼,我們如果想要offsetWidth
=100px,程式碼該怎麼寫呢?很簡單,加入一句box-sizing: border-box
就可以了。
二,margin 的縱向重疊問題
我們先來看一段程式碼:
/*css*/
p{
margin-top: 10px;
margin-bottom: 15px;
}
/*HTML*/
<p>小巨集</p>
<p></p>
<p></p>
<p></p>
<p>小巨集</p>
執行出來的效果是這樣的:
很明顯,並沒有像我們想象中的,二者之間應該會有很大的距離。所以我們不難得出:相鄰元素的margin-top
和margin-bottom
是會重疊的,以數值大的為主。空白內容的塊級標籤也是會重疊的,只不過他們的margin
我們可以忽略不計。
三,margin 負值問題
我們直接把知識點擺出來:
- 給
margin-top
、margin-left
設定負值,元素會分別向上、向左移動相應的長度 - 給
margin-right
設定負值,當前元素的右側元素左移相應的長度,自身不受影響。如果右邊沒有元素,自身也不會受到影響 - 給
margin-bottom
設定負值,當前元素的下側元素上移相應的長度,自身不受影響。如果下邊沒有元素,自身也不會受到影響
我們來看看效果:
四,BFC(Block Format Context)
何謂 BFC 呢?大部分都將其解析為塊級格式化上下文,是 Web 頁面中盒模型佈局的 CSS 渲染模式,指一個獨立的渲染區域或者說是一個隔離的獨立容器。其內部元素的渲染不會影響到邊界以外的元素。我們主要從以下幾個方面來理解它。
形成條件
- float 不是 none
- position 是 absolute 或 fixed
- overflow 不是 visible
- display 是 flex、inline-block、table-cell、table-caption 其中之一
實際應用
阻止元素被浮動元素覆蓋
兩欄佈局,左邊固定寬度,右邊不設寬,隨瀏覽器自適應
/*html*/
<div class="column"></div>
<div class="column"></div>
/*css*/
.column:nth-of-type(1) {
float: left;
width: 200px;
height: 300px;
margin-right: 10px;
background-color: red;
}
.column:nth-of-type(2) {
overflow: hidden;/*建立BFC */
height: 300px;
background-color: purple;
}
阻止相鄰元素的 margin 合併
我們在 margin 負值的問題中提到過合併問題。我們可以通過設定 BFC 來解決:
/*html*/
<div class="container">
<div class="box1"></div>
<div class="box2"></div>//會出現合併的情況
<div class="wrapper">
<div class="box1"></div>//讓二者其一處於另一個BFC中
</div>
<div class="box2"></div>
</div>
/*css*/
.container {
overflow: hidden;
width: 100px;
height: 100px;
background-color: red;
}
.wrapper {
overflow: hidden;//設定BFC
}
.box1 {
height: 20px;
margin: 10px 0;
background-color: green;
}
.box2 {
height: 20px;
margin: 20px 0;//未設定BFC,以大的為準,二者距離本為20px
background-color: green;
}
阻止字型環繞
很簡單,給我們的 p 標籤設定 BFC 就好了
五,float 的應用
float 是我們 CSS 中非常常用的屬性了,我們在開發中經常用它來實現三欄佈局。主要特點是:
1.中間一欄最先載入和渲染 2.兩側內容固定,中間內容隨寬度自適應 3.主要用於 PC
聖盃佈局
聖盃佈局的方法實現主要是針對容器 div 的padding
這塊來下手的,我們整理一下實現步驟:
- 首先用一個大的 div 來包裹我們的三欄 left、center、right,並給大 div 的
padding-left
設定為 left 欄的寬度,padding-right
設定為 right 欄的寬度 - 給我們的三欄分別設定
float:left
屬性 - center 欄:設定
width:100%
- left 欄:設定
position:relative
;right:[自身寬度]
;margin-left:-100%
- right 欄:設定
margin-right:-[自身寬度]
; 6.注意:要給body
設定min-width
屬性,且值要大於或等於2*left的width+1*right的width
,不然中間會被擠上去
這是 HTML 方面的程式碼
<div class="container">
<div class="center">中間</div>
<div class="left">左</div>
<div class="right">右</div>
</div>
雙飛翼佈局
雙飛翼佈局的方法實現主要是針對margin
這塊來下手的,相比於聖盃佈局,理解起來也方便一些,只是在 HTML 程式碼方面我們要與聖盃佈局的稍作區別:
<div class="main-container col">
<div class="main">中間(將中間包裹在div中,方便留白)</div>
</div>
<div class="left col">左</div>
<div class="right col">右</div>
我們整理一下實現步驟:
- 三欄都設定
float: left
屬性,即上面的col
- 在
main-container
處留白。給main
框設定margin: 0 left的寬度 0 right的寬度
。 left
框設定margin-left: -100%
right
框設定margin-left: -[自身寬度]
- 注意:要給
body
設定min-width
屬性,且值要大於或等於left的width+right的width
,不然中間會被擠上去
六,手寫 clearFix
回到我們的聖盃佈局,我們總覺得好像缺點什麼要素。沒錯,這三欄就像我們的網頁中主要內容,我們還應該要有我們的頭部和尾部佈局。於是我們理所當然的把上面的 HTML 程式碼改成了下面這樣:
<div class="header">頭部內容</div>
<div class="container">
<div class="center">中間</div>
<div class="left">左</div>
<div class="right">右</div>
</div>
<div class="footer">底部內容</div>
可渲染出的效果,並不是很理想
可以看到,我們的底部內容跑到了右邊,並且被 container 框壓住了,這是因為有 float 的原因。當然,我們給 footer 一個clear:both
就可以讓他下去了,這裡呢,我們不準備操作 footer,我們嘗試著自己寫一個 clearFix 來實現這個功能。
/*html*/
<div class="container clearFix">
<div class="center">中間</div>
<div class="left">左</div>
<div class="right">右</div>
</div>
/*css*/
.clearFix:after {
content: '';
display: table;
clear: both;
}
七,flex 佈局
flexBox 佈局,指的是在display: flex
下的佈局操作。首先呢,我們要記住一些我們常見的有關 flex 的 css 屬性:
flex-direction
定義容器要在哪個方向上堆疊 flex 專案。有四個屬性值,分別為:column
[設定垂直堆疊 flex 專案(從上到下)]column-reverse
[垂直堆疊 flex 專案(從下到上)]row
[水平堆疊 flex 專案(從左到右)]row-reverse
[水平堆疊 flex 專案(從右到左)]
justify-content
用於對齊 flex 專案。有五個屬性值,分別為:center
[將 flex 專案在容器的中心對齊]flex-start
[將 flex 專案在容器的開頭對齊(預設)]flex-end
[將 flex 專案在容器的末尾對齊]space-around
[顯示行之前、之間和之後帶有空格的 flex 專案]space-between
[顯示行之間帶有空格的 flex 專案]
align-items
用於垂直對齊 flex 專案。也有五個屬性值,分別為:center
[將 flex 專案在容器的中心對齊]flex-start
[將 flex 專案在容器的頂部對齊]flex-end
[將 flex 專案在容器的底部對齊]stretch
[拉伸 flex 專案填充容器]space-between
[使 flex 專案基線對齊]
flex-wrap
規定是否應該對 flex 專案換行.有三個屬性值,分別為:wrap
[規定 flex 專案將在必要時進行換行]nowrap
[規定 flex 專案不要換行(預設)]wrap-reverse
[規定 flex 專案將在必要時以相反的順序進行換行]
align-self
這個屬性實際上是重寫了align-items
,我們主要來用它實現居中對齊,因此,我們記住center
這一常用屬性值就好了,其他的屬性值和align-items
差不多。也可以理解為align-self: center;
=justify-content: center;align-items: center;
ok,我們來一個簡單的案例:色子。為了方便大家看,我們只實現點數為3的這一面
/*主要程式碼*/
.container{
display: flex;
justify-content: space-between;/*容器*/
}
.item:nth-child(2){
align-self: center;/*第二個點*/
}
.item:nth-child(3){
align-self: flex-end;/*第三個點*/
}
以上就是css常考的一些重要知識點,我也會在後面做出適當的更新補充。下次見!