任務11- inline-block、BFC、邊距合并

問題

1. 在什么場景下會出現外邊距合并?如何合并?如何不讓相鄰元素外邊距合并?給個父子外邊距合并的范例

外邊距合并指的是,當兩個垂直外邊距相遇時,它們將形成一個外邊距。合并后的外邊距的高度等于兩個發(fā)生合并的外邊距的高度中的較大者。

外邊距合并主要有 2 種典型的例子:
  1. 相鄰元素的外邊距合并
  2. 父子元素的外邊距合并(假如“父”與“子”都在正常的文檔流里面,“父”沒有 border 和 padding ,那么它們之間就會產生外邊距合并,取其中的最大值。)
  3. 自身“空元素”(無內容,無 border,無 padding)也有可能發(fā)生合并(這種情況比較特殊)
demo - 父元素與子元素的外邊距合并
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>父元素與子元素外邊距合并</title>
    <style media="screen">
        * {
            margin: 0;
            padding: 0;
        }
        .container {
            width: 300px;
            height: 300px;
            background-color: blue;
            /*border: 1px solid;*/
            margin: 100px;
        }
        .box {
            width: 100px;
            height: 100px;
            background-color: red;
            margin: 100px;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="box"></div>
    </div>
</body>
</html>
父元素與子元素外邊距合并1.png

可以看出,父元素的 margin-top 與子元素的 margin-top 發(fā)生合并,變?yōu)?100px。

當父元素有 border 的時候,
.container {
            width: 300px;
            height: 300px;
            background-color: blue;
            border: 1px solid;
            margin: 100px;
        }
父元素與子元素外邊距合并2.png

當父元素添加了 border ,父元素與子元素的外邊距沒有合并

demo-兄弟元素和它們的子元素
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>兄弟元素和它們的子元素</title>
    <style media="screen">
        * {
            margin: 0;
            padding: 0;
        }
        .ct1 {
            width: 300px;
            height: 300px;
            margin-bottom: 25px;
            background-color: yellow;
        }
        .box1 {
            width: 100px;
            height: 100px;
            background-color: red;
            margin-bottom: 100px;
        }
        .box2 {
            width: 100px;
            height: 100px;
            background-color: blue;
            margin-top: 100px;
            margin-bottom: 200px;
        }
        .ct2 {
            width: 300px;
            height: 300px;
            margin-top: 50px;
            background-color: lightgreen;
        }
    </style>
</head>
<body>
    <div class="ct1">
        <div class="box1"></div>
        <div class="box2"></div>
    </div>
    <div class="ct2"></div>
</body>
</html>
兄弟元素和它們的子元素1.png

注意:ct1 和 ct2 之間的間隔只有 50px。(各元素之間并沒有“間隔”padding,border,BFC),推測:這個 “50px” 是 ct2 的。

當 ct2 的 margin-top 改為 30px 時,間隔為 30px。
兄弟元素和它們的子元素2.png
當 ct2 的 margin-top 改為 10px 時,ct1 與 ct2 之間的間隔為 25px。
兄弟元素和它們的子元素3.png
所以知道,ct1 與 box2 之間的下外邊距為 “ct1”的。

原因:bottom margin of a last in-flow child and bottom margin of its parent if the parent has 'auto' computed height
(對于margin-bottom來說,父元素高度需為auto才能和子元素合并。)

設置 height 為 auto
.ct1 {
            width: 300px;
            /*height: 300px;*/
            margin-bottom: 25px;
            background-color: yellow;
        }
兄弟元素和它們的子元素4.png

ct1 和 ct2 之間的 “間隔” 為 box2200px

demo - “空元素”,高度為0并且最小高度也為0(無內容)的元素
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>空元素</title>
    <style media="screen">
        * {
            margin: 0;
            padding: 0;
        }
        .box {
            background-color: red;
            margin-top: 100px;
            margin-bottom: 100px;
        }
        p {
            background-color: green;
        }
    </style>
</head>
<body>
    <div class="box"></div>
    <p>testtesttesttesttesttesttesttest</p>
</body>
</html>
空元素外邊距合并1.png

可以看見,.box 的上下 margin 發(fā)生合并(100px)。

當 .box 設置了 height (有數值)時,
.box {
            height: 100px;
            background-color: red;
            margin-top: 100px;
            margin-bottom: 100px;
        }
空元素上下外邊距合并2.png
tips:
  1. 當 2 個 “div” 之間沒有 border、padding以及不滿足 BFC 的時候,會發(fā)生外邊距合并。
  2. 在CSS當中,相鄰的 2 個盒子(可能是兄弟關系也可能是祖先關系)的外邊距可以結合成一個單獨的外邊距。
  3. 外邊距合并的規(guī)則
  • 兩個相鄰的外邊距都是正數時,折疊結果是它們兩者之間的較大值
  • 兩個相鄰的外邊距都是負數時,折疊結果是它們絕對值的較大值兩者之間的較小值(例如,一個是 -90px, 另一個是 -30px, 則取 -90px)
  • 兩個外邊距一正一負時,折疊結果時兩者相加的和
拓展閱讀:
  1. CSS基礎學習十五:盒子模型補充之外邊距合并
  2. MDN_外邊距合并
  3. 細說 CSS margin

2. 去除 inline-block 內縫隙有哪幾種常見的方法?

!!!!!代碼之間的“間隔”會顯示為這個“內縫隙”
這個“間隔”可以理解為一個“空格”,可以應用“font”。

消除 inline-block 內縫隙方法
第 1 種方法:(刪除間隔)

可以直接把各行代碼的間隔全部刪掉(簡單粗暴的方法)

第 2 種方法:(設置margin-left)

設置 margin-left: -4px;(這個 -4px 是個約定俗成的數字)然后單獨為第一個元素設置 margin-left: 0px;(防止走出父容器)

第 3 種方法:(font-size: 0px;)

font-size: 0px;然后為每個“字體”單獨設置各自的“font-size”

第 4 種方法:(float)

float + 清除浮動

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>inline-block縫隙</title>
    <style media="screen">
        html,body,ul,li {
            margin: 0;
            padding: 0;
        }
        li {
            list-style: none;
        }

        .box {
            border: 1px solid green;
            overflow: auto;
            /*font-size: 0;*/
        }
        .box>li:first-child {
            /*margin-left: 0*/
        }
        .box>li {
            display: inline-block;
            /*margin-left: -4px;*/
            float: left;
            background-color: blue;
            color: #fff;
            padding: 3px;
            /*font-size: 12px;*/
        }
    </style>
</head>
<body>
    <ul class="box">
        <li>tag1</li>
        <li>tag2</li>
        <li>tag3</li>
    </ul>
    <p>
        dfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdf
    </p>
</body>
</html>

沒清除浮動的后果:
沒有清除浮動.png

父容器沒有撐開,后面的 p圍繞著浮動元素。

清除浮動:
已清除浮動.png

3. 父容器使用 overflow: auto | hidden 撐開高度的原理是什么?

overflow,指定如果內容溢出一個元素的框,會發(fā)生什么。
描述
visible 默認值。內容不會被修剪,會呈現在元素框之外
hidden 內容會被修剪,并且其余內容是不可見的
scroll 內容會被修剪,但是瀏覽器會顯示滾動條以便查看其它的內容
auto 如果內容被修剪,則瀏覽器會顯示滾動條以便查看其余的內容
inherit 規(guī)定應該從父元素繼承 overflow 屬性的值
首先,先來看看滿足 BFC 的條件:
  1. float 的值不是 none
  2. position 的值不是 static 或者 relative
  3. display 的值是 inline-block、table-cell、flex、table-caption、inline-flex
  4. overflow 的值不是 visible

所以,只要 overflow 的值不是 visible ,都能形成 BFC。
這樣,就可以讓容器內的元素不受外面影響。

BFC是一個名詞,是一個獨立的布局環(huán)境,我們可以理解為一個箱子(實際上是看不見摸不著的),箱子里面物品的擺放是不受外界的影響的。轉換為BFC的理解則是:BFC中的元素的布局是不受外界的影響(我們往往利用這個特性來消除浮動元素對其非浮動的兄弟元素和其子元素帶來的影響。)

拓展閱讀:
  1. 關于overflow:hidden
  2. 清理浮動的全家

4. BFC 是什么?如何形成 BFC,有什么作用?

Block formatting contexts,塊級格式化上下文。

創(chuàng)建了 BFC 的元素就是 1 個獨立的盒子,不過只有 Block-level box 可以參與創(chuàng)建 BFC,它規(guī)定了內部的 Block-level box 如何布局,并且與這個獨立盒子里的布局不受外部影響,當然它也不會影響到外面的元素。

BFC 是個很奇怪的東西,它一直隱式地存在CSS的樣式里,但是要記住 BFC 是頁面元素里一個獨立存在作用塊,它不影響它外面的布局,外面的元素也不會影響到 BFC 里面的布局。

定義:浮動元素和絕對定位元素,非塊級盒子的塊級容器(例如:inline-blocks, table-cells, table-captions),以及 overflow 值不是 “visible” 的塊級盒子,都會為他們的內容創(chuàng)建新的 BFC (塊級格式上下文)。

一個 HTML 元素要創(chuàng)建 BFC ,則滿足下列的任意一個或多個條件即可:
  1. float 的值不是 none
  2. position 的值不是 static 或者 relative
  3. display 的值是 inline-block、table-cell、flex、table-caption、inline-flex
  4. overflow 的值不是 visible
作用:
  1. 撐開父元素
  2. 阻止外邊距
  3. 清除浮動的文字環(huán)繞和位置的影響

BFC 是一個獨立的布局環(huán)境,其中的元素布局是不受外界的影響,并且在一個 BFC 中,塊盒與行盒(行盒由一行中所有的內聯元素所組成)都會垂直地沿著其父元素的邊框排列。

BFC 有以下特性:
  1. 內部的 Box 會在垂直方向,從頂部開始一個接一個地放置。
  2. Box 垂直方向的距離由 margin 決定。屬于同一個 BFC 的 2 個相鄰 Box 的 margin 會發(fā)生疊加。
  3. 每個元素的 margin box 的左邊,與包含塊 border box 的左邊相接觸(對于從左到右的格式化,否則相反)。即使存在浮動也是如此。
  4. BFC 的區(qū)域不會與 float box 疊加。
  5. BFC 就是頁面一個隔離的獨立容器,容器里面的子元素不會影響到外面的元素,反之亦然。
  6. 計算 BFC 的高度時,浮動元素也參與計算。
拓展閱讀:
  1. CSS之BFC詳解

5. 浮動導致的父容器高度塌陷指什么?為什么會產生?有幾種解決方法

父容器里面的元素浮動-->脫離文檔流,父容器自然就會高度塌陷
這種情況,清除浮動即可。

父容器高度塌陷例子:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>父容器高度塌陷</title>
    <style media="screen">
        .container {
            width: 500px;
            border: 1px solid red;
        }
        .item1 {
            width: 100px;
            height: 100px;
            background-color: blue;
            float: left;
        }
        .item2 {
            width: 100px;
            height: 100px;
            background-color: green;
            float: right;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="item1"></div>
        <div class="item2"></div>
    </div>
</body>
</html>
父容器高度塌陷.png

清理浮動的方法

1. 清理浮動-使用帶有 clear 屬性的空元素
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>清理浮動-使用帶有 clear 屬性的空元素</title>
    <style media="screen">
        .container {
            width: 500px;
            border: 1px solid red;
        }
        .item1 {
            width: 100px;
            height: 100px;
            background-color: blue;
            float: left;
        }
        .item2 {
            width: 100px;
            height: 100px;
            background-color: green;
            float: right;
        }
        .clear {
            clear: both;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="item1"></div>
        <div class="item2"></div>
        <div class="clear"></div>
    </div>
</body>
</html>
清理浮動-使用帶有 clear 屬性的空元素.png

盡管這種方法兼容所有瀏覽器并且隨用隨清,但是這會添加大量無語義的 html 元素。

2. 使用 CSS 的 :after 偽元素
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>使用CSS的 :after 偽元素</title>
    <style media="screen">
        .container {
            width: 500px;
            border: 1px solid red;
        }
        .item1 {
            width: 100px;
            height: 100px;
            background-color: blue;
            float: left;
        }
        .item2 {
            width: 100px;
            height: 100px;
            background-color: green;
            float: right;
        }
        .container:after {
            content: '';
            display: block;
            clear: both;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="item1"></div>
        <div class="item2"></div>
    </div>
</body>
</html>
CSS-after清除浮動.png

父容器添加一個看不見的塊元素( :after )來清理浮動。
需要注意的是,為了兼容 IE6 和 IE7,要添加一條 zoom:1; 來觸發(fā) haslayout (可以寫到 IE6 和 IE7 的 CSS hacker 文件里,這樣不會影響 W3C 標準驗證。)

這種方法需要給每組浮動元素都添加一個容器,推薦在頁面布局時使用。大量使用依然會對代碼量造成一些影響。

3. 使用 CSS 的 overflow 屬性
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>使用 CSS 的 overflow 屬性進行怪異處理</title>
    <style media="screen">
        .container {
            width: 500px;
            border: 1px solid red;
            
            /*overflow: hidden;*/
            overflow: auto;
        }
        .item1 {
            width: 100px;
            height: 100px;
            background-color: blue;
            float: left;
        }
        .item2 {
            width: 100px;
            height: 100px;
            background-color: green;
            float: right;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="item1"></div>
        <div class="item2"></div>
    </div>
</body>
</html>
使用 overflow 屬性.png

雖然很多地方以“將來瀏覽器可能不兼容”為由,不建議使用這個方法。但是短時間內瀏覽器不會在這個問題上后退處理。另外,這個方法無需添加額外的 class ,在做主題時比較實用。建議,在局部和無法添加 class a 的地方使用該方法清理浮動,但不要作為主要清理浮動方式。 overflow: auto; 還是不要用了。

4. 給浮動元素的容器添加浮動
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>給浮動元素的容器添加浮動</title>
    <style media="screen">
        .container {
            width: 500px;
            border: 1px solid red;
            float: left;
        }
        .item1 {
            width: 100px;
            height: 100px;
            background-color: blue;
            float: left;
        }
        .item2 {
            width: 100px;
            height: 100px;
            background-color: green;
            float: right;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="item1"></div>
        <div class="item2"></div>
    </div>
</body>
</html>
給浮動元素的容器添加浮動.png

給浮動元素的容器添加浮動屬性也可清除內部浮動。但是這會對接下來的文檔造成影響。
建議,在容器原本就浮動,或者容器使用了絕對定位時使用這個方法。不要在主要布局中使用。

5. 使用鄰接元素清理
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>使用鄰接元素清理</title>
    <style media="screen">
        .container {
            width: 500px;
            border: 1px solid red;
        }
        .item1 {
            width: 100px;
            height: 100px;
            background-color: blue;
            float: left;
        }
        .item2 {
            width: 100px;
            height: 100px;
            background-color: green;
            float: right;
        }
        .content {
            clear: both;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="item1"></div>
        <div class="item2"></div>
        <div class="content"></div>
    </div>
</body>
</html>
使用鄰接元素清理.png

給浮動元素后面的元素添加 clear 屬性。
要確保后面的元素與浮動元素同在一個容器(.container)內。
如果 .content 在 .container 后面,建議使用 :after 偽元素清理。

總結:

在網頁主要布局中,使用 :after 偽元素作為主要清理浮動方式。
在小模塊( ul )使用 overflow: hidden; (留意可能產生的隱藏溢出元素問題。
如果本身就是浮動元素則可自動清除內部浮動,無需額外處理。
正文中,使用鄰接元素清理之前的浮動。

需要熟悉各種清理方式的原理和利弊。

拓展閱讀:

清理浮動的那些事兒

6. 以下代碼每一行的作用是什么?為什么會產生作用?和 BFC 撐開空間有什么區(qū)別?

.clearfix:after{
    content: '';
    display: block;
    clear: both;
}
.clearfix{
    *zoom: 1;
}
/* 這段代碼用于普通瀏覽器清除浮動 */
.clearfix:after{  /* :after 偽元素清理浮動 */
    content: '';  /* 在后面添加一個“空”的內容 */
    display: block;  /* 設置這個“空”的內容為塊級元素 */
    clear: both;  /* 這個”空“的內容左右兩邊不能有浮動元素 */
}

/* 用于 IE 瀏覽器清除浮動 */
.clearfix{  /* class 屬性為 clearfix 的元素 */
    *zoom: 1;  /* 設置縮放比例為 1 ,這是 IE 專有屬性。*/
}

第一段代碼:在父容器后面加一個“空”元素,令這個“空”元素左右不能有浮動元素。然后這個“空”元素就會下移,這樣就撐開了父元素。

第二段代碼:zoom: 1; 縮放頁面,重新排版,父元素重新計算浮動元素的高度。父容器就因此撐開了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,546評論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 98,570評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,505評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,786評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,219評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,438評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 48,971評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,796評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,995評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,230評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,697評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容