一、前言

在学习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. Https实践

    https实践 常用端口 ssh 22 telnet 23 ftp 21 rsync 873 http 80 mysql 3306 redis 6379 https 443 dns 53 php 90 ...

  2. Datatables 实现前端分页处理

    引言 Datatables 是一款 jquery 表格插件.它是一个高度灵活的工具,可以将任何 HTML 表格添加高级的交互功能. 支持分页(包括即时搜索和排序) 支持几乎任何数据源(DOM.java ...

  3. SpringCloud Alibaba实战(2:电商系统业务分析)

    选用了很常见的电商业务来进行SpringCloud Alibaba的实战. 当然,因为仅仅是为了学习SpringCloud Alibaba,所以对业务进行了大幅度简化,这里只取一个精简版的用户下单业务 ...

  4. python异步编程之asyncio

    python异步编程之asyncio   前言:python由于GIL(全局锁)的存在,不能发挥多核的优势,其性能一直饱受诟病.然而在IO密集型的网络编程里,异步处理比同步处理能提升成百上千倍的效率, ...

  5. celery异步任务体系笔记

    1.异步框架示意图 2.celery 官方文档 http://docs.celeryproject.org/en/latest/index.html 3.启动celery的命令 启动 sender 自 ...

  6. TTC测距算法

    TTC测距算法 输入输出接口 Input:(1)人与车(或车与车)的距离 (2)人与车(或车与车)的相对速度 Output:TTC collision time 算法介绍和设计方案 TTC是Time- ...

  7. CVPR2020论文点评: AdderNet(加法网络)

    CVPR2020论文点评: AdderNet(加法网络) 论文原文链接:https://arxiv.org/pdf/1912.13200.pdf 源码链接:https://github.com/hua ...

  8. eclipse解决中文乱码

    参考链接:https://blog.csdn.net/lzc2644481789/article/details/97244261

  9. 一文搞懂Ajax,附Ajax面试题

    目录 前言 正文 Ajax是什么东西? 实现核心/工作原理:XMLHttpRequest对象 XMLHttpRequest大致用法 创建XMLHttpRequest对象 发送请求 服务器响应 1. r ...

  10. Django(63)drf权限源码分析与自定义权限

    前言 上一篇我们分析了认证的源码,一个请求认证通过以后,第二步就是查看权限了,drf默认是允许所有用户访问 权限源码分析 源码入口:APIView.py文件下的initial方法下的check_per ...