1.margin与元素尺寸
我们知道,在W3C盒模型下(即box-sizing:content-box)给一个元素设置padding内边距的时候,会改变元素原有的实际尺寸(即使你设置该元素的width属性)。而margin属性虽然其本意为外边距,让人以为只会影响其与其他元素间的距离。实际上,当元素处于“充分利用可用空间
”的状态时,margin属性会影响其实际尺寸
示例:
<div class="container">
<div class="child"></div>
</div>
.container{
width: 200px;
height: 200px;
background-color: red;
}
.child{
/*未设置具体宽度*/
margin: 0 -20px;
}
当子元素child未设置宽度时,其宽度默认是父元素contanier宽度的100%,此时其状态就是充分利用可用空间。
margin属性影响了元素实际尺寸(由理应的200变成240)。而当child元素设置了具体width或者其宽度由内部元素内容决定时,此时状态不是“充分利用可用空间”,所以这种情况下margin并不会影响元素尺寸
2. margin百分比值
与padding属性值一样,margin属性的百分比相对于父元素(包含块)的宽度来计算
3. margin合并
块级元素(不包括浮动和绝对定位元素)的上外边距(margin-top)与下外边距(margin-bottom)有时会合并为单个外边距,这样的现象称为“margin 合并”。
3.1 margin合并场景
(1)相邻兄弟元素 margin 合并
.container{
width: 200px;
height: 200px;
background-color: yellow;
padding: 10px;
}
.child{
width: 100px;
background-color: green;
margin: 20px 0;
}
(2)父级和第一个/最后一个子元素的margin合并。
<div class="container">
<div class="child">我是child</div>
</div>
.container{
width: 200px;
height: 200px;
background-color: yellow;
margin-top: 20px;
}
.child{
width: 100px;
background-color: green;
margin-top: 20px;
}
实际上,以下三个部分的html代码在默认情况下就是等价的
<div class="father">
<div class="son" style="margin-top:80px;"></div>
</div>
<div class="father" style="margin-top:80px;">
<div class="son"></div>
</div>
<div class="father" style="margin-top:80px;">
<div class="son" style="margin-top:80px;"></div>
</div>
3.2 margin合并计算
margin合并计算规则可概括为——正正取大值,正负值相加,负负最负值
示例:
俩兄弟元素间上面那个个margin-bottom为20px,下面那个margin-top为10px,则最终两元素间外间距为较大的20px
俩兄弟元素间上面那个个margin-bottom为50px,下面那个margin-top为-10px,则最终两元素间外间距为50+(-10)=40px
父子元素间,父元素margin-top为-50px,子元素margin-top为-10px,则最终两元素间外间距为负值较大的-50px
3.3 margin合并消除
对于 margin-top 合并,可以进行如下操作(满足一个条件即可):
• 父元素设置为块状格式化上下文元素(BFC);
• 父元素设置 border-top 值;
• 父元素设置 padding-top 值;
• 父元素和第一个子元素之间添加内联元素进行分隔。
对于 margin-bottom 合并,可以进行如下操作(满足一个条件即可):
• 父元素设置为块状格式化上下文元素(BFC);
• 父元素设置 border-bottom 值;
• 父元素设置 padding-bottom 值;
• 父元素和最后一个子元素之间添加内联元素进行分隔;
• 父元素设置 height、min-height 或 max-height。
所以,我们可以统一采取父元素设置为块状格式化上下文元素(BFC) 的方法消除margin合并:
/*父元素*/
.container {
overflow: hidden;
}
注意:margin合并现象并非CSS的设计Bug,实际上它的存在意义在于让图文信息的排版更加自然
4. 深入margin:auto
margin:auto 的填充规则如下:
(1)如果一侧定值,一侧 auto,则 auto 为剩余空间大小。
(2)如果两侧均是 auto,则平分剩余空间。
看下面例子:
.father {
width: 300px;
}
.son {
width: 200px;
margin-right: 80px;
margin-left: auto;
}
请问:此时.son 的左右边距计算值是多少? 如果是对 margin:auto 没有一定深入了解的人,可能会认为左边距 0、右边距 100px,实际上不是的,应该是左边距 20px、右边距 80px。 margin 的'auto'可不是摆设,是具有强烈的计算意味的关键字,用来计算元素对应方向应该获得的剩余间距大小。譬如这里,总剩 余间距大小是 100 px,其中 margin-right 使用了 80 px,那自然 margin-left 的'auto' 计算值就是剩余的 20px 了。
同理,我们常用的margin:auto则是对水平方向的剩余空间大小进行了平分,所以实现了水平居中的效果。
看到这有人会问,margin属性的值明明是既包含水平,也包含垂直方向的,并且元素和容器也设置了高度,为什么margin:auto不能实现垂直方向的居中呢?
事实上,margin:auto是可以实现垂直方向居中的,只不过,大多数情况下,它并不符合可以垂直居中的条件规则。
margin:auto计算的前提条件:
元素的width 或 height 为 auto 时,元素具有对应方向的自动填充特性。
.father {
width:200px;
height: 200px;
}
.son {
width:100px;
height: 100px;
margin: auto;
}
这段代码例子,.son如果没有设置width,默认会填充为父元素的宽度200px,符合规则所以水平方向会居中,但是height就不一样了,假如说把.son 元素的 height:100px 去掉,.son 的高度会自动填充为跟父元素等高的 200px 吗?显然不会!因此无法触发 margin:auto计算,故而无法垂直居中。
那么什么时候元素的height可以触发margin:atuo垂直方向的计算规则呢?
最经典的场景则是通过据对定位和margin:auto配合实现的垂直水平居中的场景:
<div class="relative">
<div class="absolute"></div>
</div>
.relative{
position: relative;
width:100px;
height:100px;
background-color: red;
}
.absolute{
position: absolute;
background-color: blue;
width: 20px;
height: 20px;
left:0;
right:0;
top:0;
bottom: 0;
margin:auto
}
根据绝对定位的流体特性(当绝对定位 同时设置了left和right或同时设置了bottom和top,那么该元素的宽度或者高度自适应于该元素的包含块的padding-box的宽度和高度,具体宽度和高度由具体的left/top/bottom/right值来确定)。当我们将absolute元素left/bottom/right/top值都设置为0时,此时absolute元素的水平和垂直方向都符合margin :auto的计算规则,实现了水平垂直居中
4. margin值无效场景
-
display 计算值 inline 的非替换元素的垂直 margin
-
表格中的和元素或者设置 display 计算值是 table-cell 或 table-row的元素
-
绝对定位元素非定位方位的 margin 值(见下方示例)
img { top: 10%; left: 30%; margin-right: 30px; }
此时 right 和 bottom 值属于 auto 状态,也就是右侧和底部没有进行定位,此时,这两个方向设置 margin 值我们在页面上是看不到定位变化的
替换元素是浏览器根据其标签的元素与属性来判断显示具体的内容。包括input,select,img和textarea等元素