1.在什么場(chǎng)景下會(huì)出現(xiàn)外邊距合并侠驯?如何合并?如何不讓相鄰元素外邊距合并奕巍?給個(gè)父子外邊距合并的范例
概念:在CSS當(dāng)中吟策,相鄰的兩個(gè)盒子(可能是兄弟關(guān)系也可能是祖先關(guān)系)的外邊距可以形成成一個(gè)單獨(dú)的外邊距。這種合并外邊距的方式被稱為合并的止,并且因此所結(jié)合成的外邊距稱為合并外邊距檩坚。
合并的結(jié)果:
兩個(gè)相鄰的外邊距都是正數(shù)時(shí),合并的結(jié)果是它們兩者之間較大的值诅福。
兩個(gè)相鄰的外邊距都是負(fù)數(shù)時(shí)匾委,合并的結(jié)果是兩者絕對(duì)值的較大者。
兩個(gè)外邊距一正一負(fù)時(shí)氓润,合并結(jié)果是兩者的相加的和赂乐。
產(chǎn)生合并的必備條件:margin必須是鄰接的!
而根據(jù)w3c規(guī)范咖气,兩個(gè)margin是鄰接的必須滿足一下條件:必須是處于常規(guī)文檔流(非float和絕對(duì)定位)的塊級(jí)盒子挨措,并且處于同一個(gè)BFC當(dāng)中。
沒有線盒崩溪,沒有間隙(clearance浅役,下面會(huì)講到),沒有padding和border將他們分割開悯舟。
-
都屬于垂直方向上相鄰的外邊距担租,可以是下面任意一種情況。
- 元素的margin-top與其第一個(gè)常規(guī)文檔流的子元素的margin-top
- 元素的margin-bottom與其下一個(gè)常規(guī)文檔流的兄弟元素的margin-top抵怎。
- height為auto的元素的margin-bottom與其最后一個(gè)常規(guī)文檔流的子元素的margin-bottom
- 高度為0并且最小高度也為0奋救,不包含常規(guī)文檔流的子元素,并且自身沒有建立新的BFC的元素的margin-top和margin-bottom反惕。
那么根據(jù)上面的文檔規(guī)范產(chǎn)生外邊距合并的場(chǎng)景就是下面這幾種:
兄弟元素
父元素與第一個(gè)/最后一個(gè)子元素
空塊元素
以上情形混合
舉例說明:
- 兄弟元素外邊距合并
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.box1{
width: 100px;
height: 100px;
border: 1px solid red;
margin: 30px;
}
.box2{
width: 100px;
height: 100px;
border: 1px solid blue;
margin: 50px;
}
</style>
</head>
<body>
<div class="ct">
<div class="box1"></div>
<div class="box2"></div>
</div>
</body>
</html>
上圖可以看到尝艘,相鄰的兄弟元box1與box2發(fā)生了外邊距合并,合并值為它們中較大的50px姿染。
- 父元素與子元素:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.ct{
background-color: #ccc;
width: 400px;
height: 400px;
margin: 100px;
}
.box1{
width: 100px;
height: 100px;
border: 1px solid red;
margin: 30px;
}
.box2{
width: 100px;
height: 100px;
border: 1px solid blue;
margin: 50px;
}
</style>
</head>
<body>
<div class="ct">
<div class="box1"></div>
<div class="box2"></div>
</div>
</body>
</html>
上圖可以看到背亥,父元素ct的margin-top與第一個(gè)子元素box1的margin-top發(fā)生了合并秒际,但是最后一個(gè)子元素box2的margin-bottom與父元素的margin-bottom卻沒有合并,原因是我們對(duì)父元素設(shè)置了height狡汉。
那么取消父元素的height試試看:
.ct{
background-color: #ccc;
width: 400px;
margin: 100px;
}
看上圖娄徊,取消height值(即height值為auto)之后父元素ct的margin-bottom與最后一個(gè)子元素box2的margin-bottom發(fā)生了合并。
- 空塊元素
<!DOCTYPE html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
.ct{
background-color: #ccc;
border: 1px solid;
}
.box1{
width: 100px;
height: 100px;
border: 1px solid red;
margin: 30px;
}
.box2{
height: 0px;
min-height: 0px;
margin: 50px;
}
</style>
</head>
<body>
<div class="ct">
<div class="box1"></div>
<div class="box2"></div>
</div>
</body>
</html>
上圖可以看到盾戴,box3為空塊元素寄锐,給它設(shè)置margin,它自身的margin-top與margin-bottom發(fā)生了合并尖啡,為50px橄仆。
- 以上幾種情形混合
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
.ct{
background-color: #ccc;
width: 400px;
min-height: 0px;
margin: 100px;
}
.box1{
width: 100px;
height: 100px;
border: 1px solid red;
margin: 30px;
}
.box2{
width: 100px;
height: 100px;
border: 1px solid blue;
margin: 50px;
}
.ct1{
height: 0px;
min-height: 0px;
margin: 100px;
}
.ct2{
width: 100px;
height: 100px;
border: 1px solid red;
}
</style>
</head>
<body>
<div class="ct">
<div class="box1"></div>
<div class="box2"></div>
</div>
<div class="ct1"></div>
<div class="ct2"></div>
</body>
</html>
上圖可以看到,盒子ct與盒子ct2之間的外間距為100px衅斩,期間發(fā)生了多次外邊距合并盆顾。
對(duì)合并結(jié)果的值舉例:
- margin值都是正數(shù):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.ct{
background: pink;
}
.box1{
width: 100px;
height: 100px;
border: 1px solid red;
margin: 30px;
}
.box2{
width: 100px;
height: 100px;
border: 1px solid blue;
margin: 50px;
}
</style>
</head>
<body>
<div class="ct">
<div class="box1"></div>
<div class="box2"></div>
</div>
</body>
</html>
從上圖看到,box1和box2相鄰畏梆,發(fā)生了邊距合并您宪,合并值為它們中margin值更大的50px。
1.2具温;margin都為負(fù)數(shù):
.ct{
background: pink;
border:1px soli green;
margin: 100px;
}
.box1{
width: 100px;
height: 100px;
border: 1px solid red;
margin: -30px;
}
.box2{
width: 100px;
height: 100px;
border: 1px solid blue;
margin: -50px;
}
為了更方便觀察給父元素設(shè)置margin:100px蚕涤,從上圖可以看出筐赔,當(dāng)2個(gè)兄弟元素的margin都為負(fù)數(shù)時(shí)铣猩,它們發(fā)生外邊距合并時(shí),合并的值為絕對(duì)值更大的那一方茴丰,即為-50px达皿。
1.3;margin值為一正一負(fù)
.ct{
background: pink;
border:1px soli green;
margin: 100px;
}
.box1{
width: 100px;
height: 100px;
border: 1px solid red;
margin: -30px;
}
.box2{
width: 100px;
height: 100px;
border: 1px solid blue;
margin: 50px;
}
從上圖可以看到贿肩,當(dāng)margin值為一正一負(fù)時(shí)峦椰,它們發(fā)生的外邊距合并值為2者之和,即
-30px+50px=20px
汰规。
如何阻止合并
- 創(chuàng)建了新的BFC的元素(例如浮動(dòng)元素或者“overflow”值為“visible”以為的元素)與它的子元素的外邊距不會(huì)合并汤功。
demo:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
.ct{
background-color: #ccc;
width: 400px;
min-height: 0px;
margin: 100px;
overflow: auto;
}
.box1{
width: 100px;
height: 100px;
border: 1px solid red;
margin: 30px;
}
</style>
</head>
<body>
<div class="ct">
<div class="box1"></div>
</div>
</body>
</html>
BFC內(nèi)部的子元素不會(huì)影響到外面的元素,反之也如此溜哮,所以阻止了合并滔金。
- 浮動(dòng)元素不與任何元素的外邊距產(chǎn)生合并(包括父元素和子元素)
demo:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
.ct{
background-color: #ccc;
width: 300px;
height: 300px;
margin: 100px;
}
.box1{
width: 100px;
height: 100px;
background: red;
margin: 30px;
float: left;
}
.box1:after{
content: "";
display: block;
clear: both;
}
.box2{
width: 50px;
height: 50px;
background: blue;
margin: 15px;
}
</style>
</head>
<body>
<div class="ct">
<div class="box1">
<div class="box2"></div>
</div>
</div>
</body>
</html>
浮動(dòng)元素會(huì)脫離文檔流,其他元素也就“感覺”不到它的外邊距了茂嗓,自然就不會(huì)合并餐茵。
- 絕對(duì)定位元素不與任何元素的外邊距產(chǎn)生合并
demo:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
.ct{
background-color: #ccc;
width: 300px;
height: 300px;
margin: 100px;
position: relative;
}
.box1{
width: 100px;
height: 100px;
background: red;
margin: 30px;
position: absolute;
}
</style>
</head>
<body>
<div class="ct">
<div class="box1"></div>
</div>
</body>
</html>
同浮動(dòng)元素一樣,絕對(duì)定位會(huì)使元素脫離文檔流述吸。
- inline-block元素不與任何元素的外邊距產(chǎn)生折疊忿族。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
.ct{
background-color: #ccc;
width: 400px;
height: 400px;
margin: 100px;
}
.box1{
width: 100px;
height: 100px;
background: red;
margin: 30px;
display: inline-block;
}
.box2{
width: 100px;
height: 100px;
background: blue;
margin: 50px;
}
</style>
</head>
<body>
<div class="ct">
<div class="box1"></div>
<div class="box2"></div>
</div>
</body>
</html>
文檔中規(guī)定,外邊距合并的塊級(jí)盒子的display屬性必須是下面三種之一:"block","list-item","table",所以道批,inline-block不符合要求错英。
- 一個(gè)常規(guī)文檔流元素的margin-bottom與它下一個(gè)常規(guī)文檔流的兄弟元素的margin-top會(huì)產(chǎn)生合并,除非它們之間存在間隙(clearance)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
.ct{
background-color: #ccc;
width: 400px;
height: 600px;
margin: 100px;
}
.box1{
width: 100px;
height: 100px;
background: red;
margin: 30px;
}
.box2{
float: left;
width: 100px;
height: 100px;
background: blue;
}
.box3{
clear:both;
width: 100px;
height: 100px;
background: pink;
margin: 50px;
}
</style>
</head>
<body>
<div class="ct">
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
</div>
</body>
</html>
從上圖我們可以看出閉合浮動(dòng)的元素的border-top會(huì)緊貼著相應(yīng)的浮動(dòng)元素的margin-bottom
- 一個(gè)常規(guī)文檔流元素的margin-top與其第一個(gè)常規(guī)文檔流的子元素的margin-top產(chǎn)生合并隆豹,條件為父元素不包含padding和border走趋,子元素不包含clearance。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
.ct{
background-color: #ccc;
border: 10px solid black;
padding: 10px;
width: 400px;
height: 400px;
margin: 100px;
}
.box1{
width: 100px;
height: 100px;
background: red;
margin: 30px;
}
</style>
</head>
<body>
<div class="ct">
<div class="box1"></div>
</div>
</body>
</html>
根據(jù)盒模型噪伊,padding和border會(huì)組織父元素與其第一個(gè)子元素的外邊距相遇簿煌。
- 一個(gè) 'height' 為 'auto' 并且 'min-height' 為 '0'的常規(guī)文檔流元素的 margin-bottom 會(huì)與其最后一個(gè)常規(guī)文檔流子元素的 margin-bottom 合并,條件為父元素不包含 padding 和 border 鉴吹,子元素的 margin-bottom 不與包含 clearance 的 margin-top 合并姨伟。
同上。
- 一個(gè)不包含border-top豆励、border-bottom夺荒、padding-top、padding-bottom的常規(guī)文檔流元素良蒸,并且其 'height' 為 0 或 'auto'技扼, 'min-height' 為 '0',其里面也不包含行盒(line box)嫩痰,其自身的 margin-top 和 margin-bottom 會(huì)合并剿吻。
反過來說只要不滿足上面任意一個(gè)條件,或者有一定內(nèi)容串纺,就不會(huì)發(fā)生自身合并丽旅。
- 關(guān)于clearance
根據(jù)w3c的文檔規(guī)定,閉合浮動(dòng)的元素會(huì)在其margin-top以上產(chǎn)生一定的空隙(clearance)纺棺,該空隙會(huì)阻止元素margin-top的合并榄笙,并作為間距存在于元素的margin-top的上方。
demo:
<div class="wrapper overHid">
<div class="big-box" style="box-shadow:0 20px 0 rgba(0,0,255,0.2);">non-float</div>
<div class="middle-box green floatL" style="opacity:0.6">float left</div>
<div class="middle-box red clear" style="margin-top:40px;box-shadow:0 -40px 0 rgba(255,0,0,0.2);">clear</div>
</div>
上面的圖中我們可以看到祷蝌,我們?yōu)榧t色塊盒設(shè)置的40px的margin-top(這里我們通過相同高度的陰影來將其可視化)好像并沒有對(duì)紫色塊盒起作用茅撞,而且無論我們?cè)趺葱薷倪@個(gè)margin-top值都不會(huì)影響紅色塊盒的位置(當(dāng)margin-top的值超過了clearance時(shí),還是會(huì)影響的)巨朦,而只由綠色塊盒的margin-bottom所決定米丘。
通過w3c的官方規(guī)范可知,閉合浮動(dòng)的塊盒在margin-top上所產(chǎn)生的間距(clearance)的值與該塊盒的margin-top之和應(yīng)該足夠讓該塊盒垂直的跨越浮動(dòng)元素的margin-bottom罪郊,使閉合浮動(dòng)的塊盒的border-top恰好與浮動(dòng)元素的塊盒的margin-bottom相鄰接蠕蚜。
也就是說可以得出這樣一個(gè)式子:r-margin-top + r-clearance = g-margin-top + g-height + g-margin-bottom。
2.去除inline-block內(nèi)縫隙有哪幾種常見的方法悔橄?
在寫HTML代碼時(shí)如果有多個(gè)元素標(biāo)簽使用換行靶累,那么在元素設(shè)置display:inline-block后就會(huì)出現(xiàn)縫隙腺毫,就像這樣:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
li{
list-style-type: none;
}
.box{
border: 1px solid red;
margin-left: 10px;
}
li{
display: inline-block;
background: blue;
color:#fff;
padding: 3px;
}
</style>
</head>
<body>
<ul class="box">
<li>tag1</li>
<li>tag2</li>
<li>tag3</li>
</ul>
</body>
</html>
有以下方法可以消除:
- 使結(jié)束標(biāo)簽沒有換行或空格
這樣:
<body>
<ul class="box">
<li>tag1</li><li>tag2</li><li>tag3</li>
</ul>
</body>
或者是這樣:
<body>
<ul class="box">
<li>tag1</li
><li>tag2</li
><li>tag3</li>
</ul>
</body>
- 使用margin負(fù)值
li{
display: inline-block;
background: blue;
color:#fff;
padding: 3px;
margin-left: -4px;
}
.box>li:first-child{
margin-left: 0;
}
使用margin負(fù)值時(shí)要注意,第一個(gè)子元素會(huì)跑到父元素外面挣柬,所以要單獨(dú)對(duì)第一個(gè)子元素進(jìn)行修正潮酒。
這個(gè)方法有另外一個(gè)問題就是各個(gè)瀏覽器需要使用的margin負(fù)值不一樣,在默認(rèn)字體下邪蛔,chrome瀏覽器是-4px急黎,就像上圖,而Firefox需要-5px才能消除侧到,看下圖對(duì)比:
所以使用負(fù)margin除了要修正第一個(gè)子元素外勃教,還需要考慮到瀏覽器兼容的問題。
- 使用浮動(dòng)
.box{
border: 1px solid red;
margin-left: 10px;
overflow: hidden;
}
li{
display: inline-block;
background: blue;
color:#fff;
padding: 3px;
float: left;
}
浮動(dòng)會(huì)使元素脫離文檔流匠抗,那么這些空格自然也影響不到這些浮動(dòng)元素了故源。
那么理論上說使用絕對(duì)定位也能脫離文檔流,清除這些縫隙汞贸,但是需要計(jì)算每個(gè)元素的位置绳军,太過于麻煩。
- 使用font-size為0
.box{
border: 1px solid red;
margin-left: 10px;
font-size: 0;
}
li{
display: inline-block;
background: blue;
color:#fff;
padding: 3px;
font-size: 16px;
}
空格其實(shí)也是一種字符(也能被選定)矢腻,那么font-size也能對(duì)空格進(jìn)行控制门驾,所以只要在父元素中使用font-size:0,然后在子元素設(shè)置你需要的字體大小多柑,就能清除這些縫隙了奶是。
3.父容器使用overflow: auto| hidden撐開高度的原理是什么?
對(duì)父元素使用overflow: auto| hidden顷蟆,會(huì)使這個(gè)父元素形成一個(gè)新的BFC诫隅,這個(gè)BFC里面的子元素不會(huì)受到外界元素的影響腐魂,也不回影響外界的元素帐偎。
BFC有一個(gè)特性就是可以包含浮動(dòng)元素,也就是說在計(jì)算BFC的高度時(shí)蛔屹,浮動(dòng)元素也參與計(jì)算削樊,所以父容器的高度被撐開。
4.BFC是什么兔毒?如何形成BFC漫贞,有什么作用?
-BFC是什么
BFC(Block Formatting Context),直譯為“塊級(jí)格式化上下文”育叁。BFC是一個(gè)獨(dú)立渲染的區(qū)域迅脐,里面元素的布局是不受外界的影響(我們往往利用這個(gè)特性來消除浮動(dòng)元素對(duì)其非浮動(dòng)的兄弟元素和其子元素帶來的影響。)并且在一個(gè)BFC中豪嗽,塊盒和行盒(行盒由一行中所有的內(nèi)聯(lián)元素所組成)都會(huì)垂直的沿著其父元素的邊框排列谴蔑。
- 如何形成
- float值為left或right
- position值為absolute或fixed
- display值為inline-block豌骏、table-cells、table-captions隐锭、或inline-flex
- overflow值不為visible
- 有什么用
- 可以包含浮動(dòng)元素
- 不被浮動(dòng)元素覆蓋(清除浮動(dòng))
- 阻止外邊距合并
- 利用BFC的獨(dú)立性來設(shè)計(jì)布局
5.浮動(dòng)導(dǎo)致的父容器高度塌陷指什么窃躲?為什么會(huì)產(chǎn)生?有幾種解決方法钦睡?
浮動(dòng)的子元素會(huì)脫離文檔流蒂窒,那么父容器在計(jì)算高度時(shí)會(huì)忽略這個(gè)浮動(dòng)的子元素,導(dǎo)致高度坍塌荞怒。
就像這樣:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
div {
border: 1px solid black;
padding: 5px;
}
img {
border: 1px solid red;
float: left;
}
</style>
</head>
<body>
<div>
<img src="img/blue.jpg" />
<img src="img/green.jpg" />
<img src="img/lightblue.jpg" />
</div>
</body>
</html>
那么解決方法如下:
1.使父元素形成BFC:
div {
border: 1px solid black;
padding: 5px;
float: left;
}
如圖洒琢,根據(jù)問答3的回答,使用float褐桌,讓父元素形成BFC纬凤,能夠包含浮動(dòng)的子元素。
注意撩嚼,使用這些屬性形成BFC的時(shí)候會(huì)對(duì)父元素或者子元素造成一些影響停士,需要根據(jù)實(shí)際情況來選擇合適的屬性。
2.在浮動(dòng)的子元素后面增加一個(gè)div來清除浮動(dòng)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
div {
border: 1px solid black;
padding: 5px;
}
img {
border: 1px solid red;
float: left;
}
#clear{
display: none;
clear: both;
}
</style>
</head>
<body>
<div>
<img src="img/blue.jpg" />
<img src="img/green.jpg" />
<img src="img/lightblue.jpg" />
<div id="clear">
</div>
</div>
</body>
</html>
額外增加一個(gè)div完丽,影響語義化恋技。
3.使用偽元素來建立一個(gè)空塊清除浮動(dòng)。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
div {
border: 1px solid black;
padding: 5px;
}
img {
border: 1px solid red;
float: left;
}
.clearfix:after {
content: '';
display: block;
clear: both;
}
.clearfix {
*zoom: 1;
}
</style>
</head>
<body>
<div class="clearfix">
<img src="img/blue.jpg" />
<img src="img/green.jpg" />
<img src="img/lightblue.jpg" />
</div>
</body>
</html>
目前最適用的方法逻族,不會(huì)造成額外的影響蜻底。
6..以下代碼每一行的作用是什么? 為什么會(huì)產(chǎn)生作用聘鳞? 和BFC撐開空間有什么區(qū)別薄辅?
.clearfix:after {
content: '';
display: block;
clear: both;
}
.clearfix {
*zoom: 1;
}
- .clearfix:after
使用after偽類在所有包含.clearfix類的元素里面創(chuàng)建一個(gè)虛擬子元素,該子元素為父元素的最后一個(gè)子元素抠璃。
關(guān)于偽元素的使用可以參考這篇文章學(xué)習(xí)使用:before和:after偽元素,官方的文檔是用“前”站楚、“后”
來描述偽元素的位置,所以我曾經(jīng)以為偽元素是創(chuàng)建一個(gè)兄弟元素搏嗡,但是審查元素時(shí)又發(fā)現(xiàn)偽元素是創(chuàng)建目標(biāo)元素的子元素窿春,所以查了一下資料,通過大漠這篇的博客就確定了偽元素確實(shí)是創(chuàng)建一個(gè)子元素采盒。
content: ''
這個(gè)偽元素的內(nèi)容為空display: block;
默認(rèn)的偽元素是行內(nèi)元素旧乞,但是下面的clear屬性只對(duì)塊元素起作用,所以用display將這個(gè)偽元素改為塊元素磅氨。clear:both
清除偽元素兩邊的浮動(dòng)元素尺栖。zoom: 1
ie8以下是不支持偽元素:after的,ie通常是觸發(fā)hasLayout來清除浮動(dòng)了烦租,常見的就是zoom:1延赌,*
號(hào)是是IE68的一個(gè)bug货徙,IE68看到以*
開頭的代碼,會(huì)忽略星號(hào)皮胡,執(zhí)行后面的代碼痴颊。
這段代碼總的作用就是利用after偽類來創(chuàng)建一個(gè)虛擬空塊元素,再利用clear屬性清除浮動(dòng)屡贺。
而BFC是撐開空間是利用了BFC可以包含浮動(dòng)元素的特性蠢棱,與清除浮動(dòng)讓父容器撐開空間是2種不同的方法。
本文版權(quán)歸本人和饑人谷所有甩栈,轉(zhuǎn)載請(qǐng)注明來源泻仙。