任务11-inline-block、BFC、边距合并

2016-07-31  本文已影响104人  饥人谷_任磊

1.在什么场景下会出现外边距合并?如何合并?如何不让相邻元素外边距合并?给个父子外边距合并的范例


那么根据上面的文档规范产生外边距合并的场景就是下面这几种:

举例说明:

<!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发生了外边距合并,合并值为它们中较大的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>
父元素设置了height

上图可以看到,父元素ct的margin-top与第一个子元素box1的margin-top发生了合并,但是最后一个子元素box2的margin-bottom与父元素的margin-bottom却没有合并,原因是我们对父元素设置了height。
那么取消父元素的height试试看:

.ct{
                background-color: #ccc;
                width: 400px;
                margin: 100px;
            }
取消height

看上图,取消height值(即height值为auto)之后父元素ct的margin-bottom与最后一个子元素box2的margin-bottom发生了合并。

<!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为空块元素,给它设置margin,它自身的margin-top与margin-bottom发生了合并,为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,期间发生了多次外边距合并。


对合并结果的值举例:

<!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>
margin都为正值

从上图看到,box1和box2相邻,发生了边距合并,合并值为它们中margin值更大的50px。
1.2;margin都为负数:

.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;
            }
margin值为负数

为了更方便观察给父元素设置margin:100px,从上图可以看出,当2个兄弟元素的margin都为负数时,它们发生外边距合并时,合并的值为绝对值更大的那一方,即为-50px。
1.3;margin值为一正一负

.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;
            }
margin一正一负
从上图可以看到,当margin值为一正一负时,它们发生的外边距合并值为2者之和,即-30px+50px=20px

如何阻止合并

<!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>
使用overflow形成BFC

BFC内部的子元素不会影响到外面的元素,反之也如此,所以阻止了合并。

<!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>
浮动元素

浮动元素会脱离文档流,其他元素也就“感觉”不到它的外边距了,自然就不会合并。

<!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>
绝对定位元素

同浮动元素一样,绝对定位会使元素脱离文档流。

<!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>
inline-block

文档中规定,外边距合并的块级盒子的display属性必须是下面三种之一:"block","list-item","table",所以,inline-block不符合要求。

<!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>
clearance
从上图我们可以看出闭合浮动的元素的border-top会紧贴着相应的浮动元素的margin-bottom
<!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>
padding和border

根据盒模型,padding和border会组织父元素与其第一个子元素的外边距相遇。

同上。


<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>

上面的图中我们可以看到,我们为红色块盒设置的40px的margin-top(这里我们通过相同高度的阴影来将其可视化)好像并没有对紫色块盒起作用,而且无论我们怎么修改这个margin-top值都不会影响红色块盒的位置(当margin-top的值超过了clearance时,还是会影响的),而只由绿色块盒的margin-bottom所决定。

通过w3c的官方规范可知,闭合浮动的块盒在margin-top上所产生的间距(clearance)的值与该块盒的margin-top之和应该足够让该块盒垂直的跨越浮动元素的margin-bottom,使闭合浮动的块盒的border-top恰好与浮动元素的块盒的margin-bottom相邻接。

也就是说可以得出这样一个式子:r-margin-top + r-clearance = g-margin-top + g-height + g-margin-bottom。

2.去除inline-block内缝隙有哪几种常见的方法?

在写HTML代码时如果有多个元素标签使用换行,那么在元素设置display:inline-block后就会出现缝隙,就像这样:

<!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>
内缝隙

有以下方法可以消除:

<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>
取消换行
            li{
                display: inline-block;
                background: blue;
                color:#fff;
                padding: 3px;
                margin-left: -4px;
            }
            .box>li:first-child{
                margin-left: 0;
            }
margin负值

使用margin负值时要注意,第一个子元素会跑到父元素外面,所以要单独对第一个子元素进行修正。
这个方法有另外一个问题就是各个浏览器需要使用的margin负值不一样,在默认字体下,chrome浏览器是-4px,就像上图,而Firefox需要-5px才能消除,看下图对比:

使用-4px的Firefox浏览器 改为-5px的Firefox浏览器

所以使用负margin除了要修正第一个子元素外,还需要考虑到浏览器兼容的问题。

       .box{
               border: 1px solid red;
               margin-left: 10px;
               overflow: hidden;
           }
           li{
               display: inline-block;
               background: blue;
               color:#fff;
               padding: 3px;
               float: left;
           }
float

浮动会使元素脱离文档流,那么这些空格自然也影响不到这些浮动元素了。
那么理论上说使用绝对定位也能脱离文档流,清除这些缝隙,但是需要计算每个元素的位置,太过于麻烦。

        .box{
                border: 1px solid red;
                margin-left: 10px;
                font-size: 0;
            }
            li{
                display: inline-block;
                background: blue;
                color:#fff;
                padding: 3px;
                font-size: 16px;
            }
font-size为0

空格其实也是一种字符(也能被选定),那么font-size也能对空格进行控制,所以只要在父元素中使用font-size:0,然后在子元素设置你需要的字体大小,就能清除这些缝隙了。

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

对父元素使用overflow: auto| hidden,会使这个父元素形成一个新的BFC,这个BFC里面的子元素不会受到外界元素的影响,也不回影响外界的元素。
BFC有一个特性就是可以包含浮动元素,也就是说在计算BFC的高度时,浮动元素也参与计算,所以父容器的高度被撑开。

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

-BFC是什么
BFC(Block Formatting Context),直译为“块级格式化上下文”。BFC是一个独立渲染的区域,里面元素的布局是不受外界的影响(我们往往利用这个特性来消除浮动元素对其非浮动的兄弟元素和其子元素带来的影响。)并且在一个BFC中,块盒和行盒(行盒由一行中所有的内联元素所组成)都会垂直的沿着其父元素的边框排列。

5.浮动导致的父容器高度塌陷指什么?为什么会产生?有几种解决方法?

浮动的子元素会脱离文档流,那么父容器在计算高度时会忽略这个浮动的子元素,导致高度坍塌。
就像这样:

<!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;
           }
浮动父元素

如图,根据问答3的回答,使用float,让父元素形成BFC,能够包含浮动的子元素。
注意,使用这些属性形成BFC的时候会对父元素或者子元素造成一些影响,需要根据实际情况来选择合适的属性。
2.在浮动的子元素后面增加一个div来清除浮动

<!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>
清除浮动

额外增加一个div,影响语义化。
3.使用伪元素来建立一个空块清除浮动。

<!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>
伪元素

目前最适用的方法,不会造成额外的影响。

6..以下代码每一行的作用是什么? 为什么会产生作用? 和BFC撑开空间有什么区别?

.clearfix:after {
                content: '';
                display: block;
                clear: both;
            }
            
            .clearfix {
                *zoom: 1;
            }

关于伪元素的使用可以参考这篇文章学习使用:before和:after伪元素,官方的文档是用“前”、“后”
来描述伪元素的位置,所以我曾经以为伪元素是创建一个兄弟元素,但是审查元素时又发现伪元素是创建目标元素的子元素,所以查了一下资料,通过大漠这篇的博客就确定了伪元素确实是创建一个子元素。

这段代码总的作用就是利用after伪类来创建一个虚拟空块元素,再利用clear属性清除浮动。
而BFC是撑开空间是利用了BFC可以包含浮动元素的特性,与清除浮动让父容器撑开空间是2种不同的方法。


本文版权归本人和饥人谷所有,转载请注明来源。

上一篇 下一篇

猜你喜欢

热点阅读