一起来探索CSS中margin属性的奥秘吧!!
作者:
WangMin
格言:努力做好自己喜欢的每一件事
众所周知 margin属性 是用来声明当前所设置或者指定元素所有外边距的宽度,或者设置各边上外边距的宽度。一直以来我认为它是一个很简单的属性,但是在最近的所做的项目中我遇到了一些关于 margin属性 所涉及到的问题,下面就给大家分享一下吧!!
margin 属性的简单概述
说到 margin 属性 ,就必须先了解 css盒子模型(Box Model) ,因为css盒子模型是用来设计和布局的,本质来讲是一个盒子,下面是 css盒子模型(Box Model) 的图例,如下:

从上图中可以看到 css盒子模型(Box Model) 包括:外边距(margin)、边框(border)、内边距(padding)以及最中间的内容(content),其中就包含我所要讲的 外边距(margin) ,它处于盒子模型的最外层,也就是上图中显示 margin字样 的那一层,它可以用来使不同的盒子之间留有一定的间隔从而达到布局整洁美观的效果。
从上图中的 css盒子模型(Box Model) 中可以看到margin在上下左右四个方向都存在,也就是说我们可以使用margin-top(上外边距)、margin-right(右外边距)、margin-bottom(下外边距)、margin-left(左外边距)分别设置这四个方向的margin值。这是margin 属性 最基本的用法,相信大家运用的很熟练了吧!!
margin 属性的使用语法
上面也提到了margin在上下左右四个方向都存在,可使用margin-top(上外边距)、margin-right(右外边距)、margin-bottom(下外边距)、margin-left(左外边距)分别设置这四个方向的margin值,案例1如下:
<div id="outer">
<div id="inner"></div>
</div>
#outer{
width:90px;
height:150px;
margin: 10px auto;
border:1px solid #ccc;
}
#inner{
width:50px;
height:50px;
margin-top:20px;
margin-bottom:20px;
margin-left:20px;
margin-right:20px;
background:#000;
}
网页效果如下:

所对应的盒子模型如下:

上面的例子中我是分别给元素#outer 添加了四个方向的外边距,并且外边距都相等,这样会让css在渲染的时候时间加长,并且程序性能降低,所以避免这种情况,我们可以把它简写为以下格式,所得到的效果是一样的。
#outer{
width:100px;
height:100px;
margin:20px;
background: #f00;
}
那么可能就有人会问了,如果四个方向的外边距不一样该怎么来设置呢?当然你可以用上边的提到的分别为四个方向设置相对应的外边距,也可以利用简写的方式来设置,效果其实是一样的,案例2如下:
<div id="outer">
<div id="inner"></div>
</div>
#outer{
width:150px;
height:150px;
margin: 10px auto;
border:1px solid #ccc;
}
#inner{
width:50px;
height:50px;
margin:20px 30px 40px 50px;
background:#000;
}
网页效果:

所对应的盒子模型如下:

那么在使用margin属性简写形式应该注意的点如下:
1、如果提供全部四个参数值,第一个参数表示上外边距,第二个参数表示右外边距,第三个参数表示下外边距,第四个参数表示左外边距。如案例2。
2、如果只提供一个参数值,这一个参数值则表示四个方向的外边距。也就是说四个方向的外边距是相等的。 如案例1中的简写形式。
3、如果提供两个参数值,第一个则表示上、下两边的外边距,第二个则表示左、右两边的外边距。 也就是说上、下两边的外边距相等,左、右两边的外边距相等。案例3如下:
<div id="outer">
<div id="inner"></div>
</div>
#outer{
width:110px;
height:150px;
margin: 10px auto;
border:1px solid #ccc;
}
#inner{
width:50px;
height:50px;
margin:20px 30px;
background:#000;
}
网页效果如下:

所对应的盒子模型如下:

4、如果提供三个,第一个则表示上外边距,第二个则表示左、右两边的外边距,也就说左右两边的外边距相等,第三个则表示下外边距。 案例4如下:
<div id="outer">
<div id="inner"></div>
</div>
#outer{
width:110px;
height:150px;
margin: 10px auto;
border:1px solid #ccc;
}
#inner{
width:50px;
height:50px;
margin:20px 30px 10px;
background:#000;
}
网页效果如下:

所对应的盒子模型如下:

margin外边距合并(重叠)的问题
在使用CSS的margin属性时,会出现margin属性垂直外边距的合并(折叠)的现象。这种合并(重叠)现象分为两种: 兄弟元素的合并 和 嵌套元素的合并 。
先来了解什么是垂直外边距?margin-bottom 和 margin-top就是垂直外边距
1、兄弟元素垂直外边距的合并
素垂直外边距重叠要满足三个重要的原因:1) 相邻的元素 ; 2)他们都设置得有垂直的外边距; 3) 在上一个兄弟节点的外边距设置为:margin-bottom,并且下一个兄弟节点的外边距设置为:margin-top的情况下,才会出现垂直外边距重叠的情况。
案例6如下:
<div id="box1" class="box"></div>
<div id="box2" class="box"></div>
.box{
width:100px;
height:100px;
}
#box1{
background:#f00;
margin-bottom: 20px;
}
#box2{
background:#000;
margin-top: 30px;
}
网页效果如下:

从图中可以看出给box1设置的margin-bottom: 20px的下外边距 和 box2设置的margin-top: 30px的上外边距 , 他们两个的外边距并没有求和累加为50px,而是重叠了合并为30px。这是因为 当两个元素为兄弟元素时,两者相隔的外边距,取的是两者所设置垂直margin的最大值。
那么如果给box1的margin-bottom和box2的margin-top都设置为20px,那会是怎样的效果呢?效果如下:

从上图可以看出他们两个的外边距并没有求和累加为40px,而是重叠了合并为20px。这是因为 如果相邻的两个外边距值相等,那么就取这个相等的值作为外边距。
如何解决垂直外边距重叠问题呢?假如有的时候不想让垂直外边距重叠, 应该怎么办呢? 这个问题就要说回到他们为什么重叠,就是因为他们彼此是相邻的兄弟元素! 那么我们可以让他们 不相邻 不就解决了这个问题了吗! 比如: 我们在他们彼此相邻元素之间加入一些字符,换句话说 用一些字符或者其他元素来隔开相邻的兄弟元素,那么他们彼此之间就不会产生外边距重叠的问题了。案例7如下:
<div id="box1" class="box">box1</div>
<span id="line"></span>
<div id="box2" class="box">box2</div>
.box{
width:100px;
height:100px;
color:#fff;
}
#box1{
background:#f00;
margin-bottom: 20px;
}
#box2{
background:#000;
margin-top: 30px;
}
#line{
width:100px;
height:1px;
display: block;
}
网页效果如下:

从上图中我们可以看见 中间的 span元素 的确起到了隔离他们,并且让他们的外边距无法再重叠!
案例6与案例7中margin的垂直外边距都为正数,那么如果其中一个元素的margin垂直外边距为负的情况下,该怎样来计算它们的垂直外边距呢? 如下:
<div id="box1" class="box"></div>
<div id="box2" class="box"></div>
.box{
width:100px;
height:100px;
}
#box1{
background:#000;
margin-bottom: -20px;
}
#box2{
background:#ccc;
margin-top:30px;
}
网页效果如下:

从案例中可以看出两个元素的垂直外边距只有10px,是怎样计算出这10px的呢?如果相邻元素的 margin 中有正值,同时存在负值,先取出负 margin 值和正 margin 值相加就可以了。所以上述案例中最终所得到的垂直外边距为-20px+30px=10px。
那么如果两个元素的margin垂直外边距都为负的情况下,该怎样来计算它们的垂直外边距呢? 如下:
<div id="box1" class="box"></div>
<div id="box2" class="box"></div>
.box{
width:100px;
height:100px;
}
#box1{
background:#000;
margin-bottom: -20px;
}
#box2{
background:#ccc;
margin-top:-50px;
margin-left:10px;
}
网页效果如下:

从上图中可以看出在元素box1与元素box2的margin垂直外边距都为负的情况下,最终它们的垂直外边距取得竟然是元素box2的margin-top的值,也就是元素box2向上移动了50px,覆盖住了元素box1。
由此可以得出一个结论:当 两个元素的margin 都是负值的时候,取的是其中绝对值较大的,然后从 0 位置,负向位移相应的距离。
2、嵌套元素的合并
当两个元素嵌套到一起,也就是一个父元素中嵌套了一个子元素,并且子元素设置了一个margin-top属性,这个时候如果没有内边距或边框把外边距分隔开时,它们的外边距也会发生合并。案例8如下:
<div id="box1" >
<div id="box2"></div>
</div>
#box1{
width:200px;
height:200px;
background:#f00;
}
#box2{
width:100px;
height:100px;
background:#000;
margin-top:20px;
}
网页效果如下:

从上图可以看到 父元素box1往下移动了20px 但其实我认为是子元素box2所产生的margin-top:20px外边距把 父元素box1挤下来了! 但是我要的效果并不是这样的,我只想让子元素box2的上外边距与 父元素box1有20px的距离,效果如下:

上面也提到了如果没有内边距或边框把外边距分隔开时,它们的外边距就会发生合并,那么如果给父元素设置一个边框属性将父元素与子元素分隔开时,就可以实现我想要的效果了,代码如下:
#box1{
width:200px;
height:200px;
border:1px solid #ccc;
background:#f00;
}
除了这种方案,其实解决这个问题的方法还有很多! 比如给父元素添加overflow:hidden、给父元素中加内容,给父元素设置padding等等。但给父元素加border 或 padding 这些属性会改变父元素的可见宽高度,并不是最佳解决方案!所以 推荐使用给父元素添加overflow:hidden来解决嵌套元素的垂直外边距合并的问题。
3、 margin水平外边距合并问题
先来了解什么是水平外边距? 也就是margin-left和margin-right !
两个水平方向的元素,那么最终两者之间的距离为左边盒子的右外边距和右边盒子的做外边距之和,它们之间不存在外边距合并问题。案例9如下:
<div id="box1" class="box"></div>
<div id="box2" class="box"></div>
.box{
width:100px;
height:100px;
float: left;
}
#box1{
background:#f00;
margin-right: 20px;
}
#box2{
background:#000;
margin-left: 30px;
}
网页效果如下:

margin值的单位为%百分比时
以上我举例子时使用margin,它的值都是以px为单位的,这个理解起来很简单。但是如果margin值是以%为单位呢?实际上这时候百分比(%)是相对于该元素的父元素(容器),对于同级元素和父子元素都是这样。
1、同级(兄弟)元素在水平方向使用值为%的margin,案例10如下:
<div id="box1" class="box"></div>
<div id="box2" class="box"></div>
.box{
width:100px;
height:100px;
float: left;
}
#box1{
background:#f00;
}
#box2{
background:#000;
margin-left: 10%;
}
这个例子中,两个元素都设置向左浮动,可以很清楚的看到两者水平方向的margin。其中元素box1没有设置margin,元素box2的margin-left为10%,网页效果如下:

从上图中可以看出两个div之间的间距是父元素宽度(这里的因为两个div没有被外部元素直接包裹住,所以会直接找到根元素body,父元素宽度就是指浏览器的宽度)的10%。可以通过改变浏览器的宽度来观察margin-left值的变化。
2、同级(兄弟)元素在竖直方向使用值为%的margin
上面也讲到同级(兄弟)元素在水平方向设置值为%的margin时,是相对于父元素的宽度,那么(兄弟)元素在垂直方向设置值为%的margin时,会不会相对于父元素的高度呢?案例11如下:
<div id="box1" class="box"></div>
<div id="box2" class="box"></div>
.box{
width:100px;
height:100px;
}
#box1{
background:#f00;
}
#box2{
background:#000;
margin-top: 10%;
}
这个例子中,元素box1没有设置margin,元素box2的margin-top为10%,网页效果如下:

我们可以发现当我们缩小浏览器的高度时,元素box2竖直方向上的外间距并没有相对于浏览器的高度的改变而改变,但是当改变浏览器的宽度时,元素box2竖直方向上的外间距反而随之改变。所以可以的出一个结论:元素之间在竖直方向上使用margin,当值的单位为%时,它也是相对于父元素的宽度。
3、嵌套(父子)元素使用值为%的margin
对于嵌套(父子)元素,如果在子元素中使用单位为%的margin,那么这个margin值是相对于父元素的宽度和高度,案例12如下:
<div id="box1" >
<div id="box2"></div>
</div>
#box1{
width:300px;
height:200px;
background:#f00;
overflow: hidden;
}
#box2{
width:100px;
height:100px;
background:#000;
margin-left: 10%;
margin-top:10%;
}
这个例子中,父元素box1没有设置margin,子元素box2的margin-left为10%,margin-top为10%,那么根据父元素的宽度来计算子元素box2的margin-left值就是300*10%=30px,根据父元素的高度来计算子元素box2的margin-top值就是200*10%=20px,网页效果如下:

子元素box2所对应的盒子模型如下:

从上图中我们可以看出子元素box2的margin-top与margin-left都为30px,而不是上面我们计算出来200*10%=20px,这说明 子元素的margin-top值最终同样是相对与父元素的宽度而不是高度。
margin为负值
margin外边距属性的值 是可以支持 负值的 ,如果设置负值,则元素会向反方向移动!
1、当给一个元素设置负的margin-left值时,案例13如下:
<div id="box1" >
<div id="box2"></div>
</div>
#box1{
width:300px;
height:200px;
background:#f00;
margin:0 auto;
}
#box2{
width:100px;
height:100px;
background:#000;
margin-left: -20px;
}
网页效果如下:

子元素box2所对应的盒子模型如下:

从上图中我们可以看到子元素box2移出了父元素的左边20px。
2、当给一个元素设置负的margin-top值时,案例14如下:
<div id="box1" >
<div id="box2"></div>
</div>
#box1{
width:300px;
height:200px;
background:#f00;
margin:0 auto;
}
#box2{
width:100px;
height:100px;
background:#000;
margin-top: -20px;
}
网页效果如下:

子元素box2所对应的盒子模型如下:

从上图中我们可以看到子元素box2移出了父元素的顶部20px。
从上面两个例子中可以得出一个结论:当给一个元素设置margin-left和margin-top为负值时,元素就会向该方向移动相应的距离
3、当给一个元素设置负的margin-right值时,案例15如下:
<div id="box1" >
<div id="box2" class="box"></div>
<div id="box3" class="box"></div>
<span>我是一个span</span>
</div>
#box1{
width:300px;
height:200px;
background:#f00;
color:#fff;
margin:20px auto;
}
.box{
width:100px;
height:100px;
float: left;
}
#box2{
background:#000;
margin-right: -20px;
}
#box3{
background:#ccc;
}
网页效果如下:

从上图中可以看出元素box1并没有发生改变,反而同级元素box2会向左移动20px并且覆盖了元素box1。
4、当给一个元素设置负的margin-bottom值时,案例16如下:
<div id="box1" >
<div id="box2" class="box"></div>
<div id="box3" class="box"></div>
<span>我是一个span</span>
</div>
#box1{
width:300px;
height:200px;
background:#f00;
color:#fff;
margin:20px auto;
}
.box{
width:100px;
height:100px;
}
#box2{
background:#000;
margin-bottom: -20px;
}
#box3{
background:#ccc;
}
网页效果如下:

从上图中可以看出元素box1并没有发生改变,反而同级元素box2会向上移动20px并且覆盖了元素box1。
从上面案例15、16两个例子中可以得出一个结论:当给一个元素设置margin-right和margin-bottom为负值时,元素的位置不会相对于父元素发生任何改变,但是后面的元素会产生相同方向的位移,并覆盖自己。
利用margin实现元素居中效果
可以利用margin-right 和 margin-left同时设置auto来实现元素居中效果。那么它的实现原理是怎样的呢?
原理如下:如果两个水平方向都设置auto,则会将两侧的外边距设置为相同的左右外边距最大值! 也就是 浏览器会将父元素的宽度减去需要居中的元素的宽度过后剩余空间的宽度分为相等的两份分别作为需要居中的元素的左右外边距。这样一来就可以使元素自动在父元素中 水平居中了! 这个技巧也是我们经常会使用到的。
所以我通常会简写为: margin 0 auto; 对元素进行水平居中,案例17如下:
<div id="box1" >
<div id="box2"></div>
</div>
#box1{
width:300px;
height:200px;
background:#f00;
overflow: hidden;
}
#box2{
width:100px;
height:100px;
background:#000;
margin:0 auto;
}
给box2设置了 margin:0 auto,网页效果如下:

子元素box2所对应的盒子模型如下:

从上图中可以看出子元素box2的margin-left与margin-right都为100px,是怎么得到的呢?根据上面利用margin实现居中的原理,利用 父元素的宽度-子元素的宽度/2 得到的值分别给子元素box2的margin-left与margin-right,就是(300px-100px)/2=100px。
使用margin属性无效的元素
行内元素垂直 margin (margin-top、margin-bottom)值不起作用。也就是说,普通的行内元素是无法使用垂直 margin (margin-top、margin-bottom)的。但是行内元素水平 margin(margin-left、margin-right)是有效的。案例18如下:
<div id="outer">
<span id="inner">inner</span>
</div>
#outer{
width:110px;
height:150px;
margin: 10px auto;
border:1px solid #ccc;
}
#inner{
color:#fff;
margin:20px 10px 10px;
background:#000;
}
网页效果如下:

以上仅是个人见解,若有不足之处欢迎在下方评论指出,那就先分享到这里!! 后续继续更新!!
一起来探索CSS中margin属性的奥秘吧!!的更多相关文章
- CSS中margin属性
css中margin块级元素的垂直相邻外边距会合并,比如 方框的上下外边距并不是2px,而是合并为1px了. 设置float属性就可以避免这种同级元素边距合并
- 深入理解css中position属性及z-index属性
深入理解css中position属性及z-index属性 在网页设计中,position属性的使用是非常重要的.有时如果不能认识清楚这个属性,将会给我们带来很多意想不到的困难. position属性共 ...
- 深入理解css中position属性及z-index属性 https://www.cnblogs.com/zhuzhenwei918/p/6112034.html
深入理解css中position属性及z-index属性 请看出处:https://www.cnblogs.com/zhuzhenwei918/p/6112034.html 在网页设计中,positi ...
- CSS中margin和padding的区别
在CSS中margin是指从自身边框到另一个容器边框之间的距离,就是容器外距离.在CSS中padding是指自身边框到自身内部另一个容器边框之间的距离,就是容器内距离. 下面讲解 padding和ma ...
- CSS中Position属性
也许你看到这个标题觉得很简单,确实这是一篇关于CSS中Position属性基础知识的文章,但是关于Position的一些细节也许你不了解. 1.简介 position有五个属性: static | r ...
- 区分html与css中的属性
CSS中id与Class的区别 1.在CSS文件里书写时,ID加前缀"#":CLASS用"." 2.id一个页面只可以使用一次:class可以多次引用. 3.I ...
- CSS中 Zoom属性
CSS中 Zoom属性 其实Zoom属性是IE浏览器的专有属性,Firefox等浏览器不支撑.它可以设置或检索对象的缩放比例.除此之外,它还有其他一些小感化,比如触发ie的hasLayout属性,清除 ...
- CSS中margin边界叠加问题及解决方案(转)
边界叠加简介 边界叠加是一个相当简单的概念.但是,在实践中对网页进行布局时,它会造成许多混淆.简单地说,当两个垂直边界相遇时,它们将形成一个边界.这个边界的高度等于两个发生叠加的边界的高度中的较大者. ...
- DIV css中cursor属性详解-鼠标移到图片变换鼠标形状 (转)
css中cursor属性详解-鼠标移到图片变换鼠标形状 语法: cursor : auto | all-scroll | col-resize| crosshair | default | han ...
- CSS中Position属性static、absolute、fixed、relative
在html中网页可以看成一个立体的空间,一个完整的页面是由很多个页面堆积形成的,如下图所示 CSS中Position属性有四个可选值,它们分别是:static.absolute.fixed.rel ...
随机推荐
- SAP ABAP 使用GENIOS求解线性规划问题的简单例子
主要内容来自Operations Research & ABAP ,结合我遇到的需求,做了一些修改. 需求:有BOX1和BOX2两种箱子,分别能包装不同数量的A物料和B物料,给出若干数量的A, ...
- Mariadb取24小时数据--九五小庞
Mariadb是一种常用的关系型数据库管理系统.在进行实时数据处理时,我们常常需要查询最近24小时的数据来进行分析和处理.下面我们将介绍如何使用MySQL查询最近24小时的数据. SELECT * F ...
- 最新基于nonebot的qq机器人搭建
导读 核心资源 ( 参考各项目到各自release下载 NoneBot简介 | go-cqhttp 帮助中心qq登录需要包签名,要自己部署 https://github.com/fuqiuluo/un ...
- jwt实现token鉴权(nodejs koa)
为什么需要token 在后台管理系统中,我们通常使用cookie-session的方式用于鉴权,jwt实现token鉴权(nodejs koa) 但这种方式存在着以下问题 比如cookie的容量太小. ...
- Ceres简单应用-求解(Powell's Function)鲍威尔函数最小值
Ceres 求解 Powell's function 的最小化 \(\quad\)现在考虑一个稍微复杂一点的例子-鲍威尔函数的最小化. \(\quad{}\) \(x=[x_1,x_2,x_3,x_4 ...
- [k8s]使用私有harbor镜像源
前言 在node上手动执行命令可以正常从harbor拉取镜像,但是用k8s不行,使用kubectl describe pods xxx 提示未授权 unauthorized to access rep ...
- centos7安装influxdb2
前言 InfluxDB是一个由InfluxData开发的开源时序型数据库,专注于海量时序数据的高性能读.高性能写.高效存储与实时分析等,广泛应用于DevOps监控.IoT监控.实时分析等场景. 服务器 ...
- 如何实现Excel中的多级数据联动
摘要:本文由葡萄城技术团队于博客园原创并首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 前言 在类Excel表格应用中,常用的需求场景是根据单元格之间 ...
- Gin中间件开发
Gin是一个用Go语言编写的Web框架,它提供了一种简单的方式来创建HTTP路由和处理HTTP请求.中间件是Gin框架中的一个重要概念,它可以用来处理HTTP请求和响应,或者在处理请求之前和之后执行一 ...
- Ubuntu安装后续工作
更新源: sudo gedit /etc/apt/sources.list 清华的源 deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial ma ...