1. 程式人生 > 實用技巧 >CSS世界(張鑫旭)系列學習總結 (三)width和height作用的具體細節

CSS世界(張鑫旭)系列學習總結 (三)width和height作用的具體細節

元素最基本最常用的兩個屬性就是width和height了,他們雖然很普通很常見,卻有著我不瞭解的東西。

先看看width屬性,預設值是auto,意思就是自動計算寬度,具體怎麼自動計算是有一個計算規則的,而且對於塊級和內聯元素這個規則還不一樣。

假如,我在頁面中寫了一個元素,且沒有設定width屬性時,會有什麼表現呢?

如果這個元素是div、p等塊級元素,則它的width表現為父容器的寬度,隨著容器的變化變化,始終和父容器寬度一致;(流特性)

如果這個元素是inline-block、浮動、絕對定位等內聯元素,則它的寬度取決於元素包含內容的多少,內容為空的話寬度就是0,隨著內容增加寬度增加;(包裹性)

對於以上兩種情況,當元素中的內容多到快要超出父容器邊界時,內容都會自動換行。

換個說法就是,塊級元素的尺寸由外部尺寸也就是父容器尺寸決定,內聯元素的尺寸由內部尺寸也就是由包含的內容或子元素尺寸決定。

width屬性auto的這種表現,正是為了滿足佈局需要產生的,我們可以合理利用這種特性可以輕鬆實現自適應佈局。

絕對定位元素一般情況下寬度表現的是包裹性,即由內容決定,但是有一種情況下會表現出流特性,比如:

div {position:absolute;left:20px;right:20px;}

可以這樣理解,當對立方位屬性值都存在,如left、right 或 top、bottom,此時該元素的尺寸已經可以確定了,因此就確定出來了。

1.width的作用細節

先來了解下“盒尺寸“概念,上篇說了,元素由外在盒子和內在盒子構成,外在盒子決定能不能換行,長啥樣我也不知道,內在盒子就是我們耳熟能詳的盒模型了。

這個盒模型從內到外依次是 content box、padding box、border box、margin box,簡單明瞭。

前輩們設計了這個模型,也相應地定義了一堆屬性來控制模型具體表現,而width、height這兩個普通的屬性就是作用在content box上的。

因此,我們看到的元素實際尺寸是content+padding+border的總和,這很容易理解,但實際中我們佈局需要控制的是這個實際的總尺寸,往往有些麻煩。

麻煩在於,假如想讓元素佔據100px寬度,設定width為100px後,再調整padding、border的話,最終的寬度就不符合預期了,當然也可以直接設定一個減掉paddng、border之後的寬度值,如此再想調整佈局,程式碼改動較多。

針對此問題,css3給出瞭解決方案 box-sizing,我們也可以使用寬度分離原則來處理,

.father{
  width:180px  
}

.son{
margin:0 20px;
padding:20px;
border:1px solid;
}

2.height的作用細節

height的預設值也是auto,但它的計算規則卻沒有width那麼複雜,只是簡單的把子元素高度相加。

為什麼如此簡單呢?因為犯不上搞那麼複雜。因為css預設流是水平方向的,寬度是稀缺的,而高度是無限的,所以關於寬度如何分配的規則就比較複雜。

2.1 width、 height:100%

對於width而言,無論父元素width是否為auto,子元素100%有效。

對於height而言,如果父元素height為auto,則100%會被忽略。

比如,直接在頁面中插入div,程式碼如下:

div {
width:100%; /*這是多餘的*/
height:100%; /* 這是無效的*/
background:url(bg.jpg);
}

因為,div屬於塊級元素,width預設auto,具有自適應性,不用設定100%,寬度始終自動充滿父元素空間;height無效是因為父元素body寬度目前預設是auto;

想要生效,還需要這樣操作一下:

html,body{
height:100%;
}

這就是我們經常在專案,index.css檔案中看到的程式碼。

做是這樣做了,可是為什麼呢?

官網解釋:如果包含塊的高度沒有顯示指定(即高度由內容決定),並且該元素不是絕對定位,則計算值為auto。

寬度的解釋:如果包含塊的寬度取決於該元素的寬度,即取決於子元素,則行為未定義。

但是各瀏覽器對此情況下寬度100%的表現行為一致,而高度由於是auto,該值無法和百分比進行計算,‘auto’*100/100=NaN,因此此情況下高度百分比無效。

父元素寬度auto,子元素寬度百分比的表現可以看這段程式碼:

<div class="box">
    <img src="1.jpg">
    <span class="text">紅色背景是父級</span>
</div>

.box{
display:inline-block;
white-space:nowrap;
background-color:#cd0000;
}

.text{
display:inline-block;
width:100%;
background-color:#34538b;
color:#fff;

}

瀏覽器如何渲染呢,最終父元素多寬,子元素多寬?

瀏覽器的渲染順序是自上而下、由外到內渲染DOM內容,因此在這裡,會先渲染父元素,寬度是圖片寬度加文字寬度,此時文字寬度是文字本身的寬度,沒有被width 100%渲染,等父元素渲染完成,父元素寬度確定,子元素width 100%才會計算。

因此,height 100%生效的程式碼如下:

1. 設定顯式高度值,600px,或可以生效的100%,比如我們從html一層層設定下來的height:100%

html,body{
height:100%;
}

2.使用絕對定位

div{
height:100%;
position:absolute;
}

大概,按照規範的意思,絕對定位的時候,子元素百分比的計算值就不是auto了,父元素已經渲染結束了,height已經確定了。