css盒模型和定位掃盲

原文:原文鏈接

轉載請標明出處

css盒模型與定位

說到css的盒子模型和定位相信大家一定都聽說過,因為它們是css中的基礎,同時也是難點,這篇文章的作用在於基礎知識的掃盲。

先來說說盒子模型吧

什麼是盒子模型

簡單地說每個html標籤都是一個方塊,然後這個方塊又包著幾個小方塊。分別是:margin、border、padding、content。它們的關係是margin包著border包著padding包著content。就像盒子一層一層地包著一樣,這就是我們所說的盒模型。

嗯,看上面的文字有點文縐縐的,我們直接上圖吧。

打開谷歌瀏覽器,按下F12,然後把右邊欄的滾動條拉到最下面你就會看到一個東西:

這就很直觀給我們展示了什麼是盒子模型!

盒子有多大

我相信這個問題肯定會問倒很多人,這個問題是個非常經典的問題。我在百度上查都能查到有很多人寫的博客上都在這方面有錯誤,所以,我覺得我有必要在這篇文章上講清楚盒子到底有多大。

老規矩,先上代碼

.red{n width:200px;n height:200px;n background-color:red;n}n

補全html代碼就會在頁面左上角出現這麼個玩意兒:

對應的盒子模型:

很明顯這個時候的盒子大小就是content的大小。來,我們繼續往下走,我們給這個方塊加上padding:

.red{n width:200px;n height:200px;n padding:10px;n background-color:red;n}n

這時你就會發現這個方塊比原來稍微胖了那麼一點:

對應的盒模型:

這個時候將滑鼠移到控制台上的這個元素你就會發現:

下面寫有盒子的長寬變成了220x220,很明顯,padding是能夠改變盒子的大小的,這時盒子大小就等於content+padding。

接下來,我們給盒子加上邊框:

.red{n width:200px;n height:200px;n padding:10px;n border:10px solid black;n background-color:red;n}n

這個時候變成了下面這樣:

盒模型:

它的長寬:

可以發現長寬變為了240x240,所以這時盒子大小就等於content+padding+border。

接下來講margin。在給這個方塊加margin之前為了方便觀察我們加個類名為blue的div,並且加上樣式:

.blue{n width:100px;n height:100px;n background-color:blue;n}n

效果圖:

因為div是塊級元素,所以新加的藍色div自動跑到紅色的下面。

接下來給紅色方塊加上margin-bottom:

.red{n width:200px;n height:200px;n padding:10px;n margin-bottom:10px;n border:10px solid black;n background-color:red;n}n

效果圖:

可以發現,盒子的底部產生了10px的空白。

對應的盒模型

方塊的長寬

很明顯盒子的大小並沒有變大,還是原來的240x240。

所以,最終盒子的大小為content+padding+border即內容的(width)+內邊距的再加上邊框,而不加上margin。

看到網上很多文章都把margin算進去了,如果按照他們所說的,上面盒子的大小應該是240x250,然而實際情況並不是。從這裡可以看出,很多人對盒模型有誤解。把margin算進去的那是盒子佔據的位置,而不是盒子的大小!

其實盒模型一共分為兩種,一種是上面講的標準盒模型,還有一種是怪異盒模型,這兩種盒模型的區別在於width/height。前者width/height指的是content區域的寬度和高度,後者width/height指的是content+padding+border。

在ie8+瀏覽器中使用哪個盒模型可以由box-sizing控制,默認值為content-box,即標準盒模型;如果將box-sizing設為border-box則用的是怪異盒模型。如果在ie6,7,8中DOCTYPE缺失會觸發怪異模式。

我們可以把上面的紅色方塊的box-sizing設為border-box發現,無論我們怎麼改border和padding盒子大小始終是定義的width和height:

定位

定位(position)有四個值:

  1. static
  2. relative
  3. absolute
  4. fixed

static

一般如果我們不設置position的話它的默認值就是static,這個時候left、top、bottom、right是不起作用的

,現在有如下兩個div,他們的關係是兄弟關係:

.red{n width:200px;n height:200px;n left:100px;n top:100px;n background-color:red;n}n.blue{n width:100px;n height:100px;n background-color:blue;n}n

效果圖:

可以發現,並沒有什麼變化。紅色方塊的left和top加不加都一樣。

relative

但是,現在我們給紅色方塊加個position:relative:

.red{n position:relative;n width:200px;n height:200px;n left:100px;n top:100px;n background-color:red;n}n

嘿嘿,變這樣了:

可以發現,紅色方塊跑到藍色方塊的右邊了,左邊緣和頂邊緣都距離原來100px,但是藍色方塊還是在原來的地方不動,現在可以得出一個結論:使用相對定位給元素加left/top/right/buttom元素會以原來的位置為基礎加上這些值,即以原來的位置為基礎定位,並且沒有脫離文檔流

嗯,是不是看起來有點文縐縐的,那來個形象的比喻吧:

假如position:static是一個活人的話,並且擁有靈魂,這個時候我想給他加個left:100px想讓他的靈魂出來,但是並沒有效果。當這個人剛去世而且屍體還沒火化的時候(相當於position:relative),這時我加個left:100px靈魂就可以移動了,並且靈魂往屍體的右邊移動了100px。因為屍體還沒火化,所以這個人還是佔一定的空間的。

absolute

現在,我們把position改為absolute:

.red{n position:absolute;n width:200px;n height:200px;n left:100px;n top:100px;n background-color:red;n}n

效果圖:

可以發現藍色方塊如我們所願移動到了紅色方塊的上面,說明紅色方塊已經脫離文檔流。雖然紅色方塊的位移和relative一樣但是,紅色方塊位移的參考不再是原來的位置而是body只不過紅色方塊的位置剛好在body的最左上角,剛好碰巧位移一樣,上面的這個例子可能看不出來,讓我們來改改代碼。

首先將html結構改成:

<div class="red">n <div class="blue"></div>n</div>n

然後紅色方塊的absolute改回relative

效果圖:

然後藍色方塊代碼改為:

.blue{n position:absolute;n top:100px;n left:100px;n width:100px;n height:100px;n background-color:blue;n}n

可以發現在給藍色方塊添加position:absolute前,藍色方塊像我們想的那樣在紅色方塊的左上角;當我們給藍色方塊添加position:absolute並且添加left和top時,藍色方塊就跑到了紅色方塊的右下角。

那麼這次這個藍色方塊是以誰為參考進行位移的?剛剛你說的以body為參考又是什麼情況?

好,我這裡就給大家說清楚,當給一個元素設置position:absolute時,這個元素的位置就是以他父代元素position不為static的元素作為參考,如果他的父代元素都是position:static那就以body作為參考。剛剛紅色方塊的情況就是他父代元素沒有position不為static的元素,所以只能以body作為參考。

嗯,講的文縐縐的,我不喜歡。來,舉個例子:

還是剛剛那個人與靈魂的例子,當設置position:absolute時,就相當於人死了,屍體已經火化了,只剩下靈魂和骨灰,所以是不佔空間的(就是已經脫離文檔流)。這個時候靈魂可以亂飄了,但是有個限制,只能相對於骨灰飄。

fixed

現在讓我們再來創建一個綠色方塊:

.green{n position:fixed;n top:150px;n left:150px;n width:100px;n height:100px;n background-color:green;n}n

效果圖:

這個看起來貌似沒有什麼特別的,現在我們來給body加個height:2000px(這個高度隨意,但是要使瀏覽器右邊出現滾動條),然後把瀏覽器的滾動條往下拉,一個神奇的事情發生了:綠色方塊固定在我們定義的位置上屏幕上不動了!

這個fixed我們見得最多的就是網頁中頑固的小廣告,不管我們怎麼拖拽滾動條,它總是固定在那,就是一個升級版的absolute。

用上面的例子來說就是人已經成仙了,可以不受限制地亂飄,而且不管你怎麼拉,都拉不動他,他就在那不動了!

z-index

說到定位,肯定少不了z-index。用上面的例子來說z-index就是靈魂飄的高度,設置得越大,自然就飄得越高,既然扯到了靈魂,z-index肯定是對活人(static)無效的了。

正常情況下(沒有加z-index),元素是按照後來居上原則進行堆疊。在這個例子上的html元素是這樣的:

<div class="red">n <div class="blue"></div>n </div>n<div class="green"></div>n

按照後來居上原則,紅色方塊最先被瀏覽器渲染到,所以在最下面,其次到藍色,最後到綠色。

如果我們想讓紅色方塊顯示到前面我們可以給它加個z-index:1,結果:

發現綠色方塊「消失了」。其實綠色方塊並沒有消失,你可以將滾動條往下拉,或者看盒子模型:

可以發現它並沒有消失,只是被蓋在了紅色方塊下面。由於紅色方塊與藍色方塊是父子關係,紅色的上來了,藍色肯定的上來啊。

現在我有個想法,想讓藍色方塊弄到紅色方塊下面該怎麼辦?很多人可能會想到簡單啊,直接給藍色方塊加個z-index:-1不就得了嗎?但是很可惜,沒用。

要解釋這個現象就得扯到層疊上下文的東西了。解釋這東西又得花些篇幅來講,具體的可以看這裡。

這裡我就一筆帶過了,用最通俗易懂的例子來解釋了,老爸的靈魂包著兒子的靈魂飄到了一樓(z-index:1),但是兒子想下到-1樓(z-index:-1)這是不行的因為兒子的靈魂已經被老爸的靈魂包著了(當z-index為數值時,會產生層疊上下文),如果兒子想下到一樓,得先不讓老爸的靈魂包著兒子的靈魂(不設置紅色方塊的z-index或者設置為z-index:auto),這樣就能下到-1樓了這樣藍色方塊就被紅色方塊擋住了。

但是不設置紅色的z-index的話,綠色方塊又出來作怪了,這個時候只能設置綠色方塊z-index:-1,紅色方塊就沒誰能擋得住了!

總結

  1. css的盒模型由content(內容)、padding(內邊距)、border(邊框)、margin(外邊距)組成。
  2. 在w3c和模型中,設置的width/height是content的寬度/高度,在怪異模式中width/height設置的是content+padding+border寬度/高度。
  3. 在w3c盒子模型中盒子的大小由content、padding、border決定,在在怪異模式中盒子大小由width和height決定。
  4. 定位有四個值static(靜止)、relative(相對)、absolute(絕對)、fixed(固定)。
  5. left、top、right、bottom、z-index不能對static起作用。

推薦閱讀:

為什麼(2.55).toFixed(1)等於2.5?
2016前端開發技術巡禮
聊聊前端開發中的長列表
Vuejs 中使用 markdown

TAG:HTMLCSS | 前端开发 |