一、前言

在学习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. Sqli-labs-master通关解析(持续更新中。。。)

    大多情况下:SQL注入其实就是构造正确的mysql命令,让网页回显本不应该让我们看到的数据(如用户的账号和密码). 第一关-联合查询注入 查库 // 查看当前页面在的数据库 ?id=-1' union ...

  2. 034.Python的__str__,__repr__,__bool__ ,__add__和__len__魔术方法

    Python的其他方法 1 __str__方法 触发时机: 使用print(对象)或者str(对象)的时候触发 功能: 查看对象信息 参数: 一个self接受当前对象 返回值: 必须返回字符串类型 基 ...

  3. 008.kubernets的调度系统之标签选择器

    一 Kubernetes 调度简介 除了让 kubernetes 集群调度器自动为 pod 资源选择某个节点(默认调度考虑的是资源足够,并且 load 尽量平均),有些情况我们希望能更多地控制 pod ...

  4. Linux进阶之Linux破解密码、yum源配置、防火墙设置及源码包安装

    一.老师语录: 所有要求笔试的公司都是垃圾公司 笔试(是考所有的涉及到的点) 要有自己的卖点.专长(给自己个标签)(至少一个) 生产环境中,尽量使用mv(mv到一个没用的目录下),少使用rm 二.防火 ...

  5. 代码动态更换MeshRenderer的材质Materials

    public class metrailstest : MonoBehaviour { Material[] m; Material i; public Material[] n; int index ...

  6. Wrong——Python

    1.向MySQL中插入时间(年月日时分秒),在时分秒处报错.在年月日与时分秒中间有个空格.解决办法:在sql语句中时间用一个" "包起来就可以了.. 2.在Ubuntu的cront ...

  7. [leetcode] 208. 实现 Trie (前缀树)(Java)

    208. 实现 Trie (前缀树) 实现Trie树,网上教程一大堆,没啥可说的 public class Trie { private class Node { private int dumpli ...

  8. 基于雪花算法生成分布式ID(Java版)

    SnowFlake算法原理介绍 在分布式系统中会将一个业务的系统部署到多台服务器上,用户随机访问其中一台,而之所以引入分布式系统就是为了让整个系统能够承载更大的访问量.诸如订单号这些我们需要它是全局唯 ...

  9. python3操作Kafka

    # -- coding: UTF-8 import datetime import json import time from kafka import KafkaProducer producer= ...

  10. nginx 重定向到系统维护页面

    上周末兄弟项目准备扩展服务器以便提供更好的服务,兄弟项目有一些功能是实时提供到我这边的,需要我这边暂时把对应系统功能屏蔽,因为使用nginx,所以可以直接配置nginx重定向到固定系统维护页面. ng ...