一、前言

在学习CSS时,遇到的很多问题都是和margin有关,这个小怪兽总是出其不意的让我的界面排版变的混乱,还让人摸不着头脑,原因还是在于我对他的一些属性没有进行一个深入的了解,导致我在设计之初就忽略了一些潜在的bug。所以本文就margin属性以及常见的问题做一个总结归纳。

二、什么是margin

CSS 边距属性定义元素周围的空间。通过使用单独的属性,可以对上、右、下、左的外边距进行设置。也可以使用简写的外边距属性同时改变所有的外边距。——W3School

边界,元素周围生成额外的空白区。“空白区”通常是指其他元素不能出现且父元素背景可见的区域。——CSS权威指南

是不是看到以上的权威解释还是不明所以?别急,我画个图你就明白了。

还不明白?那好,我给你举个栗子,假设你住在一个别墅区,每栋别墅都是一个元素, 既然是别墅了那怎么着也得有个围墙吧(当然也可以没有,纯粹取决于业主喜不喜欢)。围墙就相当于上图的border边界(灰色区域),围墙与房子(上图的child即元素内容)之间的空间就是padding内边距(黄色区域),而围墙之外的空间就是外边距margin了(紫色区域),你可以当做是别墅与别墅之间的空间距离。margin存在的目的就是控制元素之间的间隔使页面排版更加的美观整齐,但它不属于元素的私有财产,在计算元素大小的时候可不要把margin算在内哦,毕竟你总不能把你家门口空气算作你自己的吧,那太霸道啦!看到这里你是不是对margin的作用范围有了大致的了解了,如果还不清楚,请继续往下看呀~

三、margin的特性

1、margin始终透明。这个特性其实可以这么理解,margin存在的目的就是为了隔开不同的元素使布局更加的美观,如果margin不是透明的就无法让不同的元素产生间隙达到隔开的目的还会影响其他布局,所以margin必须是透明的。

2、简写特性。margin属性可以设置4个值,分别是margin:top right bottom left;(可以按照顺时针的方式记忆,即:上右下左。顺序不能乱),这四个值也可以单独设置,即:margin-top、margin-bottom、margin-right、margin-left。除了可以单独设置之外,margin还可以进行简写(如非必要,不建议使用第三种简写),基本如下:

  • margin只有一个值,表示top、right、bottom、left都是同一个值。例如:margin:10px等价于margin:10px 10px 10px 10px;
  • margin只有两个值,第一值表示top、bottom的值,第二个值表示right、left的值。例如:margin:10px 20px等价于margin:10px 20px 10px 20px;
  • margin只有三个值,第一个值表示top的值,第二个值表示right、left的值,第三个值表示bottom的值。例如:margin:10px 20px 30px等价于margin:10px 20px 30px 20px;

3、垂直方向外边距合并。块级元素的上外边距(margin-top)与下外边距(margin-bottom)有时会合并为一个外边距,这样的现象称为“margin合并”。只发生在与当前文档流方向相垂直的方向上,并且只能是块级元素。

四、margin合并的三种场景(纵向重叠)

1、相邻兄弟元素margin合并。这是margin合并中最常见、最基本的。例如:

 p {
margin: 1em 0;
background-color: pink;
}
<p>第一行</p>
<p>第二行</p>

效果图:

第一行和第二行的间距还是1em,因为第一行的margin-bottom和第二行的margin-top合并在了一起,并非上下相加。

2、父级和第一个/最后一个子元素合并。

 1 <style>
2 .grandfather {
3 border: 2px solid red;
4 width: 300px;
5 height: 300px;
6 }
7
8 .father {
9 width: 200px;
10 height: 200px;
11 background-color: yellow;
12 }
13
14 .son {
15 margin: 2em 0;
16 background-color: pink;
17 }
18 </style>
19
20 <body>
21 <div class="grandfather">
22 <div class="father">
23 <div class="son">this is son</div>
24 </div>
25 </div>

效果图:

当给子元素添加外边距之后,父元素和子元素的上外边距(margin-top)发生了合并,导致父元素上外边距等同于变成了子元素的上外边距(合并的外边距值若都为正,则外边距取两者的最大值)造成了视觉上的父元素塌陷但实际父元素的上外边距的值并未改变。如何阻止这里margin合并的发生呢?

对于margin-top合并,可以进行如下操作(满足一个条件即可):

  • 父级元素设置为块状格式化上下文元素(设置BFC),比如:给父级元素添加overflow:hidden;(推荐)
  • 父元素设置border-top值;
  • 父元素设置padding-top的值;
  • 父元素和第一个子元素之间添加内联元素进行分隔

对于margin-bottom合并,可以进行如下操作(满足一个条件即可):

  • 父级元素设置为块状格式化上下文元素
  • 父级元素设置border-bottom值
  • 父级元素设置padding-bottom值
  • 父级元素和最后一个子元素之间添加内联元素进行分隔
  • 父级设计height、min-height或max-height

上面例子中在.father中添加overflow:hidden效果如下:

3、空块级元素的margin合并。例如:

 .father {
overflow: hidden;
}
.son {
margin: 1em 0;
}
<div class="father">
<div class="son"></div>
</div>

效果图:

此时,.father所在的这个父级<div>元素高度仅仅是1em,因为.son这个空<div>元素的margin-top和margin-bottom合并在了一起。

五、margin负值问题

  1. margin-top和margin-left负值,元素向上、向左移动
  2. margin-right负值,右侧元素左移,自身不受影响
  3. margin-bottom负值,下方元素上移,自身不受影响

案列展示:

(1)margin-top为负值

(2)margin-left为负值

(3)margin-right为负值

(4)margin-bottom为负值

六、margin无效的问题

1、display:inline的非替换元素的垂直margin无效,对于内联替换元素垂直margin有效,并且没有margin合并的问题,所以图片永远不会发生margin合并。

2、表格中的<tr>和<td>元素或者设置display计算值是table-cell或table-row的元素的margin都是无效的。但是如果计算值是table-caption、table或者inline-table则没有此问题,可以通过margin控制外间距,甚至::first-letter伪元素也可以解析margin。

3、margin合并的时候,更改margin值可能是没有效果的。以父子margin重叠为例,假设父元素设置有margin-top:50px,则此时子元素设置margin-top:30px就没有任何效果表现,除非大小比50px大,或者是负值。

4、绝对定位元素非定位方向的margin值“无效”。因为绝对定位元素的渲染是独立的,普通元素和兄弟元素是互相关联的,但是绝对定位元素由于独立渲染无法和兄弟元素产生联系,因此margin无法影响兄弟元素定位,所以看上去就是无效的。

5、定高容器的子元素的margin-bottom或者宽度定死的子元素的margin-right的定位“失效”。这个现象的本质和和上面绝对定位元素非对立方margin值“无效”类似。原因在于,若想使用margin属性改变自身的位置,必须是和当前元素定位方向一样的margin属性才可以,否则,margin只能影响后面的元素或者父元素。

好了,总结了这么多,我想你应该对margin属性不陌生了吧,如果对你有帮助,就点个赞吧~

参考文档

https://www.cnblogs.com/zhangmingze/articles/4664074.html

https://blog.csdn.net/weixin_39855431/article/details/79929135

http://www.nowamagic.net/librarys/veda/detail/1608

https://blog.csdn.net/xun__xing/article/details/107334925

https://www.cnblogs.com/jjucap/p/5339725.html

margin属性总结,你想知道的这里都有的更多相关文章

  1. margin属性

    可以设置position:absolute/relative/fixed,通过调节top/bottom/left/right实现元素的定位,这样很好,但是有时候想通过margin来实现. 下面是mar ...

  2. 深入理解css中的margin属性

    深入理解css中的margin属性 之前我一直认为margin属性是一个非常简单的属性,但是最近做项目时遇到了一些问题,才发现margin属性还是有一些“坑”的,下面我会介绍margin的基本知识以及 ...

  3. CSS margin 属性

    设置外边距的最简单的方法就是使用 margin 属性. margin 属性接受任何长度单位,可以是像素.英寸.毫米或 em. margin 可以设置为 auto.更常见的做法是为外边距设置长度值.下面 ...

  4. margin属性的正负值确定

    margin属性用来使用设置外边距,大多数情况使用正值,但是一些稍复杂的定位就会使用到负值,所以对margin属性的正负值理解是有必要的,本文同时解释了margin-right和margin-bott ...

  5. 【WPF】C#代码动态添加控件的Margin属性

    需求:一组按钮的数据是从服务器中Json数据发过来的,需要根据这个Json数据动态地添加这组按钮. 工具:使用http://www.newtonsoft.com/json来解析Json. 过程:C#代 ...

  6. CSS的margin属性:详解margin属性

    在网上看到的一篇文章,说的比较全面.原文地址:http://www.poluoluo.com/jzxy/201206/167007.html 你真的了解margin吗? 你知道margin有什么特性吗 ...

  7. 你是否彻底了解margin属性?

    写css,你少不了与margin打交道.你真的了解margin吗?你知道margin有什么特性吗?你知道什么是垂直外边距合并?margin在块元素.内联元素中的区别?什么时候该用padding而不是m ...

  8. HTML a标签如何设置margin属性(转)

    很多同学发现对DIV有效的许多CSS属性对<a>或<p>标签都无效,好比说 <div style="margin-top:5px;"></ ...

  9. margin属性以及垂直外边距重叠问题

       盒子的margin属性         盒子的外边距margin 指的是当前盒子与其他盒子之间的距离,环绕在盒子周围的空白区域,属于不可见的区域,,不会影响到可见框的大小,而是会影响到盒子的位置 ...

随机推荐

  1. cnetos 网卡绑定 eth0+eth1做双网卡绑定到bond0

    1.网卡绑定:eth0+eth1做双网卡绑定到bond0 二.网络配置 网卡绑定1./etc/sysconfig/network-scripts/目录下建立ifcfg-bond0文件,内容如下DEVI ...

  2. linux服务之NFS服务篇

    一.概念 NFS(Network File Server) 网络文件系统(映射).网络文件系统是FreeBSD支持的文件系统中的一种,也被称为NFS: NFS允许一个系统在网络上与他人共享目录和文件. ...

  3. 2.5if语句

    判断(if)语句 目标 开发中的应用场景 if 语句体验 if 语句进阶 综合应用 01. 开发中的应用场景 生活中的判断几乎是无所不在的,我们每天都在做各种各样的选择,如果这样?如果那样?-- 程序 ...

  4. Linux系统添加永久静态路由的方法(包含Centos7)

    一.使用route命令添加 使用route 命令添加的路由,机器重启或者网卡重启后路由就失效了,方法:A.添加到主机的路由# route add –host 192.168.1.10 dev eth0 ...

  5. Apache Jena Fuseki使用

    下载Apache Jena Fuseki 先从apache官网下载fuseki压缩包.然后解压到目标文件夹. apache官网:http://jena.apache.org/download/ 这里我 ...

  6. Go语言安装配置

    一.Go语言下载 官方下载地址:https://golang.google.cn/dl/ 选择自己需要的版本下载即可. 二.Go语言安装 下载完成之后,双击go1.16.4.windows-amd64 ...

  7. Django(43)restful接口规范

    restful接口规范   什么是接口规范?接口规范就是为了采用不同的后台语言,也能使用同样的接口获取到同样的数据.如何写接口:接口规范是规范化书写接口的,写接口要写url.响应数据 ​  注:如果将 ...

  8. RedisPool

    class RedisPool(object): instance = None def __init__(self, host='192.168.2.129', port=7000, passwor ...

  9. 书列荐书 |《黑天鹅&#183;如何应对不可预知的未来》【美】纳西姆 尼古拉斯 塔勒布 著

    你不知道的事比你知道的事更有意义,因为生活中发生了许多微小的事情,尽管出现的概率非常小,但是却以某一种巨大的力量影响我们的生活.但是由于思维习惯的问题,导致我们看问题的方式使得我们不能很快地把握事物的 ...

  10. python 导入同级目录文件、上级目录文件以及下级目录数据集和模块包

    划重点: 其中dataset_path = ''表示在Python工作文件夹 dataset_path = '..'表示在Python工作文件夹的上级文件夹 dataset_path = '某某文件夹 ...