一、前言

在学习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. 云计算OpenStack核心组件---cinder存储服务(10)

    一.cinder介绍 1.Block Storage 操作系统获得存储空间的方式一般有两种: (1)通过某种协议(SAS,SCSI,SAN,iSCSI 等)挂接裸硬盘,然后分区.格式化.创建文件系统: ...

  2. nosql数据库之Redis集群

    Redis 集群是一个可以在多个 Redis 节点之间进行数据共享的设施(installation). Redis 集群不支持那些需要同时处理多个键的 Redis 命令, 因为执行这些命令需要在多个 ...

  3. CentOS 7 网络配置详解

    今天在一台PC上安装了CentOS 7,当时选择了最小安装模式,安装完成后马上用ifconfig查看本机的ip地址(局域网已经有DHCP),发现报错,提示ifconfig命令没找到. ? 1 2 3 ...

  4. 图解 Redis | 不就是 AOF 持久化嘛

    AOF 日志 试想一下,如果 Redis 每执行一条写操作命令,就把该命令以追加的方式写入到一个文件里,然后重启 Redis 的时候,先去读取这个文件里的命令,并且执行它,这不就相当于恢复了缓存数据了 ...

  5. Docker系列——Grafana+Prometheus+Node-exporter服务器告警中心(二)

    在前一篇博文中介绍,服务器监控已经部署成功.如果每天都需要人去盯着服务情况,那也不太现实.既然监控平台已经部署好了,是不是可以自动触发报警呢? 在上一篇Prometheus架构中有讲到,核心组件之一: ...

  6. MarkDown笔记二

    表格 列1|列2|列3 --|--|-- 内容1|内容2|内容3 下例冒号在左为左对齐(默认),在右为右对齐,在俩侧为居中对齐 | 左对齐 | 右对齐 | 居中对齐 | | :-----| ----: ...

  7. 详细教程丨如何利用Rancher和Kong实现服务网格?

    服务网格(Service mesh)是当前新兴的架构模式,越来越受到人们的青睐.与Kubernetes一起,服务网格可以形成一个强大的平台,它可以解决在微服务集群或服务基础设施上发现的高度分布式环境中 ...

  8. 解决使用go get 下载模块下载超时的问题

    解决使用go get 下载模块下载超时的问题   解决使用go get 下载模块下载超时的问题 使用go env可以看到,默认的GOPROXY的值是https://proxy.golang.org, ...

  9. GO语言的JSON02---反序列化

    package main import ( "encoding/json" "fmt" ) type Human struct { Name string Ag ...

  10. (续篇)Selenium 安装配置以及如何解决('chromedriver' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/ch)或者(unknown error:cannot find Chrome binary)问题?

    注:本帖针对小小白哦~~(づ ̄3 ̄)づ╭- 接pip安装的帖子,不需要的直接跳过... 首先上图,出现如下的错误,那你可是找到知己了: 或者: 抱歉抱歉,这图截的不太清晰,凑合着用吧,但是也能看出来错 ...