一道關(guān)于 Box-Sizing 的字節(jié)面試題
大家好,我是前端西瓜哥。今天講講我很久以前面試字節(jié)時(shí)遇到的一道 CSS 面試題。
有如下的 HTML 和 CSS 樣式,問兩個(gè)塊橙色區(qū)域?qū)捀叻謩e為多少?
<style>
.box {
width: 10px;
height: 10px;
border: 1px solid #000;
padding: 2px;
margin: 2px;
background-color: orange;
}
.content-box {
box-sizing: content-box;
}
.border-box {
box-sizing: border-box;
}
</style>
<div class="box content-box"></div>
<div class="box padding-box"></div>
本題考查的是 CSS 盒子模型。
CSS 盒子模型
CSS 盒子組成由 4 個(gè)區(qū)域組成,從內(nèi)到外依次為:
- Content box:內(nèi)容盒子,用于顯示內(nèi)容(innerHTML),默認(rèn)通過 width 和 height 控制寬高。但如果 box-sizing(盒模型的意思)屬性設(shè)置為非 content-box 值,運(yùn)用的規(guī)則會發(fā)生改變。
- Padding box:內(nèi)邊距盒子,通過 padding 屬性可以設(shè)置內(nèi)邊距大小。
- Border box:邊框盒子,通過 border 屬性可以設(shè)置邊框大小及樣式。
- Margin box:外邊距盒子,通過 margin 屬性設(shè)置外邊距大小。
需要注意的是,margin 不計(jì)入盒子的實(shí)際大小。比如盒子的背景色不會覆蓋到 margin 的范圍。你可以把 margin 當(dāng)作多個(gè)盒子之間的空氣墻,是用來控制盒子間的距離的。
我們可以通過 box-sizing 來控制 width 和 height 被應(yīng)用到哪個(gè)盒子上,下面具體展開來說一說。
標(biāo)準(zhǔn)盒模型(content-box)
對于現(xiàn)代瀏覽器來說,元素默認(rèn)應(yīng)用標(biāo)準(zhǔn)盒模型。當(dāng)然你也可以像下面這樣做顯式的設(shè)置。
.box {
box-sizing: content-box;
}
標(biāo)準(zhǔn)盒模型中,width 和 height 屬性用于設(shè)置 Content box 盒子。
我們回到題目,先看看第一個(gè)橙色塊的寬高。
.box {
width: 10px;
height: 10px;
border: 1px solid #000;
padding: 2px;
margin: 2px;
background-color: orange;
}
.content-box {
box-sizing: content-box;
}
<div class="box content-box"></div>
content 的寬度為 10px。
padding 為 2px,這個(gè) padding 是 padding-left、padding-right、padding-bottom、padding-left 的簡寫屬性。盒子的寬需要將 padding-left 和 padding-right 都計(jì)算在內(nèi)。
然后是左右兩個(gè) border 條。margin 不計(jì)算在盒模型中。
所以對于盒模型來說,寬度就是 16px(10 + 2 * 2 + 1 * 2),高度同理,也是 16px。
這個(gè)就是答案了嗎?
并不是,因?yàn)槲覀円业降某壬珘K的寬高,其實(shí)就是 Padding box 的寬高,這個(gè)塊并不包括黑色的 border 邊框線。所以我們的第一個(gè)橙色塊寬高為 14px。
我們再深挖一下,如果我們給 border 顏色設(shè)置為透明,比如 border: 1px solid rgb(0, 0, 0, 0),你覺得橙色塊寬高為多少?
答案是 16px。背景色會先填充整個(gè)盒子,然后再在其上添加 border。如果 border 變成透明了,就會將它原本覆蓋的部分橙色區(qū)域顯現(xiàn)出來。
怪異盒模型(border-box)
怪異盒模型,也叫 IE 模型。
IE 瀏覽器的早期版本沒有遵循 CSS 標(biāo)準(zhǔn),width 和 height 是用來設(shè)置 Border box 的寬高,而不是 Content box 的寬高,導(dǎo)致不同瀏覽器的表現(xiàn)不同,毫無疑問是個(gè)瀏覽器 bug。
后來 CSS3 引入了 box-sizing,讓開發(fā)者可以選擇使用哪種盒模型,提供更好的靈活性。通過下面的設(shè)置,我們可以將元素的盒模型設(shè)置為怪異盒模型。
.box {
box-sizing: border-box;
}
怪異盒模型中,width 和 height 屬性用于設(shè)置 Border box 盒子。即我們直接給元素對應(yīng)的盒子設(shè)置了寬高,再通過 padding 和 border,才能計(jì)算出 Content box。
我們看看題目中第二個(gè)橙色塊的寬高如何計(jì)算。
.box {
width: 10px;
height: 10px;
border: 1px solid #000;
padding: 2px;
margin: 2px;
background-color: orange;
}
.border-box {
box-sizing: border-box;
}
<div class="box border-box">
盒模型寬為 10px,減去 border 的 2px(左右兩條 1px 的邊框線),計(jì)算出來的就是 Border box 盒子的寬度 8px。高度計(jì)算同理。
所以本題的答案是:第一個(gè)橙色塊的寬高為 14px,第二個(gè)橙色塊的寬高為 8px。
結(jié)尾
對于 DOM 元素來說,我們有兩種盒模型:
- box-sizing: content-box:width 和 height 對 Content box 生效的標(biāo)準(zhǔn)盒模型,是默認(rèn)的盒模型;
- box-sizing: border-box:width 和 height 對 Border box 生效的怪異盒模型。
另外,box-sizing 僅支持上面兩種值,是沒有 padding-box 這種盒模型的,不要想太多。