深入理解margin属性
盒子尺寸的几种算法
1 .盒子尺寸:border box。从boder 往里算原生api 是offsetWidth
2 .盒子内部尺寸:padding box。从padding往里算。原生dom api是clientWidth
3 .盒子外部尺寸:margin box。从margin往里算.没有原生的dom api

margin与元素的内部尺寸
1 .如果元素有宽度,并且是块级元素.此时添加margin:元素的宽度不会发生改变
1 .margin正值的时候会拉大和其他元素的间距
2 .如果margin是负值的时候,会缩小和其他元素的间距
3 .红色的是正常的,没有添加边距,此时会有间隙是body元素的margin值,不知道为啥会显示在里面
4 .紫色和绿色都是margin:-20的结果,可以看到向左边运动了
5 .只要元素的宽度设定,margin就无法改变元素尺寸

2 .父元素宽度不变,如果元素是块级,并且宽度没有给,那么margin的宽度会发生变化
1 .margin是负值,变化相应的大小.往大绿色是父元素,可以看到宽度只有100px;紫色的是子元素,没有给宽度,默认用的是父元素的宽度,此时给他加了-200px的margin,最后他的宽度就变成了500px;已经远远超了父元素,大逆不道。margin-left,top是负值,都会改变自己的原来的大小
2 .margin是正值,变化相应的大小,往小。可以看到父元素宽度是300px,子元素的宽度没有给,默认是父元素的大小。margin左右是100px。最后的宽度是100px



3 .元素margin在垂直方向上无法改变自身的内部尺寸,往往需要父元素作为载体
使用场景1,图片左侧定位:一侧定宽,右边文字自定义布局
<div class="box">
<img src="baidu.jpg" alt="">
<p>文字内容</p>
</div>
.box{
overflow: hidden;
}
.box>img{
float: left;
}
.box>p{
margin-left:140px;
}
1 .图片右侧定位的时候,只需要把图片的左浮动改成右浮动
使用场景2 利用margin改变元素尺寸的特性实现两端对齐布局效果
li{
float:left;
width:100px;
margin-right:20px;
}
1 .上面这样处理的结果就是最右边一个会有20px的空格,虽然有其他不同的解决方法,但是这里用margin的写法
ul{
margin-right:-20px
}
2 .给ui加20px的宽度,对冲掉最后一个的20px的宽度.
3 .但是他这里说的都是float下的问题,不是不推荐使用float布局了么。。
margin与元素的外部尺寸
1 .只要元素是块状元素,无论有没有设置宽高,无论是水平还是垂直方向,即使发生了margin合并,margin对外部尺寸都实实在在的发生了变化
2 .内联元素,完全无影响,不论是垂直方向,还是左右方向,不论是外部还是内部尺寸。但是加了margin还是会有间距显示的
使用场景1 margin-bottom实现底部留白
1 .使用padding-bottom实现留白有兼容性问题,因为不同的浏览器实现滚动的逻辑是不一样的,chrome以content box为基准算是否触发滚动条,ie和firefox则是超过padding box尺寸触发滚动条。
2 .所以这种情况下直接使用margin-bottom,完全没有兼容问题
使用场景2 margin外部尺寸实现等高布局
1 .两个的宽度以最多的一个为基准,算高的。但是这个css也太狰狞了吧。flex直接实现,天然支持


2 .实现原理:margin-bottom:-9999px先给外部尺寸在垂直方向减小9999px。padding-bottom:9999px又增加了元素高度,抵消了刚才的,对布局没有影响,但是带来了多的的9999px的可使用背景色.多了这个多的可使用背景色,于是父元素overflow:hidden;消除了多余的颜色。这谁想出来的。。最关键的是这种方法兼容性超级强,ie6,ie7
margin的百分比
1 .和padding一样,也是相对于元素的宽度计算的.
2 .还是不要使用百分比算了,随便一调一个属性就是一个新的表现。完全解释不了啊.一定要走宽阔的大路
深入理解margin:auto属性
1 .必须知道的知识
1 .div元素没有设置width,height,也会自动填充,充满容器
div{
position:absoute;
left:0;
right:0;
2 .如果此时设置了宽度和高度,就会覆盖默认全部填充的特性,但是这样就没有像刚才一样,自动使用那些可以被使用的剩余空间了.margin:auto就是为了使用这些空白属性而生的
}
2 .填充规则1:如果一侧是固定值,一侧是auto,则auto为剩余空间大小

可以看到,没有margin-left的时候,虽然有了margin-right。但是是不生效的,因为流式布局先从左边走

可以看到,左边margin-left:auto的时候,是margin-right:右边距离取完的值,虽然正好也是50
1 .想要让某个元素右对齐,最可靠的是margin-left:auto;
3 .填充规则2 :两侧都是auto,平分固定值。这不是规则1 的特殊情况么。。

margin实现上下居中垂直

1 .首先发现设置margin:auto;左右方向会自动居中,但是上下是无效的.容器定高,容器定高为啥不行呢。
2 .甚至发现如果单独给他添加margin-top:还会发生边距折叠,给父元素加上了
3 .margin实现元素居中
.father{
width: 300px;
background-color: darkolivegreen;
height: 100px;
/* 父元素加这个 */
position: relative;
}
.son{
width: 100px;
height: 50px;
background-color: darkred;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
//实现原理
1 .son元素首先表现为格式化宽度和格式化高度
2 .正常添加margin:auto。什么都不管的时候,可以找到左右的居中.但是上下是不行的
3 .添加绝对定位,top:0;bottom:0;在父元素上垂直方向铺满了子元素,但是子元素是由自己的高度的,这个时候margin-top,margin-bottom的auto可以生效了
4 .相对于父元素居中的时候,给父元素加一个position:relivative;如果不加,那么就是相对于全局进行居中布局,比如浏览器居中,就可以使用这个
5 .这种实现居中比:top:50%;margin-top:负一半高度好很多.
margin无效的情况
1 .display:inline计算值的非替换元素的垂直margin是无效的,虽然规范提到有渲染,但是浏览器表现的无迹可寻

1 .inline元素和flex元素一样蠢得不会自动换行,导致会超出父元素
2 .使用float:left,又会让他们变成块级元素

可以看到,有margin值,但是效果表现是无效的
2 .表格中的tr,td元素或者设置display:table-cell,table-row的margin都是无效的
3 .绝对定位的非定位方位的margin值无效
img{
position:absolute;
left:10px;
top:10px;
margin-bottom:10px;
margin-right:10px
}
1 .一般情况下我们只需要操作两个方向的值就可以达到目的,这个时候如果是没操作的那俩方向的margin值,设置是无效的
4 .高度确定父元素下子元素的margin-bottom。或者宽度确定的父元素下子元素的matgin-right失效。

本质是,如果想要margin改变自己的位置,那么必须是当前元素定位一样的方向才可以,否则就只会影响到其他兄弟元素,所以看图下一个的元素是明确可以看到被影响到了
5 .鞭长莫及的margin无效
img{
float: left;
width: 200px;
}
p{
margin-left: 10px;
}
//这个值一定要超过左边照片宽度才行,其实是有效的,但是表现不出来
6 .内联特性导致的margin无效

确实会在只剩一个屁股的时候不在上移动,不论负值多么变大,但是这个是父元素没有任何属性,加了一个absolute之后就不是这样了,没有这个限制了
margin有效
1 .内联替换元素,垂直margin是有效的,比如照片是一定是可以的,并且不会发生margin合并
2 .如果计算值是table-caption,table或者inline-table则没有此问题
总结
1 .block元素,可以使用四个方向的margin值
2 .inline元素,只可以使用左右方向的margin值
3 .inline-block匀速,使用上下方向的值看起来是无效的,其实是和vertial-align的值有关系
重叠原则
1 .两个block元素重叠时,后面元素可以覆盖前面元素的背景。但是无法覆盖内容,也就是内容是一起显示的

2 .两个inline,两个inline-block,inline和inline-block元素重叠时,后面元素会覆盖前面元素

可以看到后面的覆盖了前面的
3 .inline元素和block元素,inline覆盖block的背景,内容的话,是后面的覆盖前面的内容
4 .最后,在浏览器不居中,浏览器将页面布局分为内容和背景,内容的层叠始终高于背景,block元素分为内容和背景,而inline元素或inline-block元素,本身就是内容