• CSS——margin


    首先要明确以下两点:

    1、元素的显示区域是指:border_left + border_right + paddiing_left + paddiing_right + content ;不包括margion;

    2、margin只是是元素盒子的外边距。用于处理元素之间间隔的属性。

    详见:CSS——盒子模型

    一、基准线的概念:

      基准线或者称为参照线,就像物理中学习的相对运动,物体是向左运动、向右运动亦或是静止,取决于参照物。比如对A、B两个物体进行如下判断:

    a、以A物体为参照物,判断物体B的运动方向、距离;

    b、以B物体为参照物,判断物体A的运动方向、距离;

    在CSS中,我们也可以虚构出基准线这样一个概念。所不同的是,在物理中我们可以随时改变参照物;但是在CSS的具体的情况下,基准线却是不可更改的。

    众所周知margin包括:margin-top 、margin-right、margin-bottom、margin-left四个,这四个外边距的基准线可以分为两大类:

    • 以外物作为基准线的:margin-top、margin-left,影响的是自己的显示位置;
    • 以自身的border为基准线的:margin-right、margin-bottom,影响的是后面兄弟元素的显示位置;

    兄弟元素之间的基准线选择:

    首先定义一个概念:元素的显示区域边界。

    显示区域的左边界按照以下原则的先后顺序进行确认:

    a、有 border_left,则以 border_left 的最左边为显示区域的左边界;

    b、有 paddiing_left, 则以 paddiing_left的最左边为显示区域的左边界;

    c、以content的最左边为显示区域的左边界;

    显示区域的上边界、右边界、下边界与此类似,不在赘述。

    明确显示区域的边界之后再来看基准线:

    1、margin-top的外物基准线的选择:

    a、垂直上面的兄弟元素显示区域的下边界位置;   ???????是没有脱离文档流还是相连时

    b、垂直上面无兄弟元素,并且父亲元素有border-top或者padding-top,则为父元素的 content 的上边位置;

    c、父元素不符合条件,则以父元素垂直上面的兄弟元素的显示区域的下边界为基准线;

    d、依次类推;

    2、margin-left的外物基准线的选择:

    a、水平左边的兄弟元素显示区域的右边界位置;   

    b、水平左边无兄弟元素,则为父元素的 content 的左边位置;

    c、如果父元素没有

    3、margin-right的自身基准线:以自身显示区域的右边界为基准线;

    4、margin-bottom的自身基准线:以自身显示区域的下边界为基准线;

    例子如下: 

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <style type="text/css">
                .back{
                    background-color:greenyellow;
                }
                .margin{
                    margin:  20px;
                    border-color:red ;
                }
                .border{
                    border: solid red 2px;
                }
            </style>
        </head>
        <body>
            <div id="div_1" class="back border" style="height: 50px;">
            div_1
            </div>
            <div id="div_2" class="back">
                <div id="div_2_1" class="back margin border" >
                    我是子元素A
                </div>
                <div id="div_2_2" class="back margin border" >
                    我是兄弟元素B
                </div>
                <div id="div_2_3" class="back border" >
                    我是兄弟元素C
                </div>
            </div>
        </body>
    </html>

    效果如下:

    1、两块黄绿色之间的白色区域的成因:因为元素A(div_2_1)的父元素div_2 即没有border,也没有padding,导致元素A的基准线变成了div_1。所以元素A与div_1之间有了间隔,而div_2 没有将这段间隔纳入显示区域;

    2、为div_2 增加 border 样式,两块黄绿色之间的白色区域会消失:元素A的基准线变成了父元素div_2。间隔的位置存在div_2的border内部,也就是在div_2的显示区域内。而margion是透明的,显示div_2的背景颜色,所以白色消失。 

    3、元素C没有设置 margion,但是元素B 的margion:20px,包含了margion-bottom:20px,所以与兄弟元素B之间有间隔;

     

    二、margin垂直外边距合并:

     在垂直方向上都有外边距margion的时候,两个margion会合并,并取最大的为两者之间的间隔:
    将上面例子中的元素C 设置style属性如下:

    <div id="div_2_3" class="back border" style="margin-top: 40px;" >
        我是兄弟元素C
    </div>

    会发现元素B、C之间的间隔变成了40px,而不是60px;

    三、margin设置值的正负问题:

    对于margion值的正负,表示的意义是截然不同的。以下均以20px大小为例。?????代表了盒子相对于基准线的移动方向:

    1、margin-top:

    正:自基准线起,向下取20px作为margin-top,盒子位置随即向下移动20px;

    负:首先基准线向上移动20px;在新的基准线起向上取20px作为margion-top的区域;盒子位置向上移动20px;

    2、margin-left: 正:向右;负:向左;

    正:自基准线起,向右取20px作为margin-left,盒子位置随即向右移动20px;

    负:首先基准线向左移动20px;在新的基准线起向左取20px作为margin-left的区域;盒子位置向左移动20px;

    3、margin-bottom:正:向上;负:向下;

    正:自基准线起,向上取20px作为margin-bottom,盒子高度随即向上增大20px;

    负:首先基准线向下移动20px;在新的基准线起向下取20px作为margin-bottom的区域;盒子高度随之向下增大20px;

    负值新解释:

    margion是用于元素之间保持一定间隔的属性。

    4、margin-right:正:向左;负:向右;

    正:自基准线起,向左取20px作为margin-right,盒子宽度随之向左增大20px;

    负:首先基准线向右移动20px;在新的基准线起向右取20px作为margin-right的区域;盒子宽度随之向右增大20px;

     

    四、margin对不同元素的作用效果:

    1、对于块级元素可以任意设置,均有效果;

    2、对于可替换元素如:select、input、object、img、button、label、textarea等元素,由于其基本类似于块级元素,因此也可以设置;

    3、对于非可替换内联(行内)元素,只有 margin-left/margin-right 能够起到一定效果。

     

     

     

    详细分析

    下面引入margin的“参考线”的概念,margin的“参考线”W3C中没有严格的规范,但通过我们的实战可以很轻易的总结出一些规律,怿飞的总结,怿飞也对margin做了详细的探究(但有部分观点本人不作认同):

    如上图是一个盒模型(略去内边距),虚线所示即为margin的参考线,讲作margin 移动的基准点可能更好理解,实线所示为border,浅绿色纯色为margin的区域,显然我们可以把margin的参考线分为两类,top 和 left 的参考线属于一类,right 和bottom 的参考线属于另一类,那它们到底各以什么为参考线呢:

    • top 以 containing block 的 content 上边或者垂直上方相连元素 margin 的下边为参考线垂直向下位移;left 以 containing block 的 content 左边或者水平左方相连元素 margin 的右边为参考线水平向右位移。
    • right 以元素本身的 border 右边为参考线水平向右位移;bottom 以元素本身的border 下边为参考线垂直向下位移。

    前面的DEMO1中A的margin-right为-50px,按照“right 以元素本身的 border 右边为参考线水平向右位移”的解释,此时A应该以元素本身的border右边向左位移50px才对(负值与正值的位移方向相反),但要注意!上面讲的位移并不是元素本身的位移,而是自身margin四个方向(top ightottomleft)的具体位置的位移! 而实际上虽然A未发生位移,但B却向左位移了50px,这又是为何?B的margin默认为0,B的margin-left寻找的左边参考线即为A元素的margin-right的具体位置,而此时A的margin-right的具体位置在哪?见下图:

    按照“right 以元素本身的 border 右边为参考线水平向右位移”的规则,这时的margin的right应从图示蓝色线开始位移,如果是正值则向右位移,但现在是负值,于是向左位移,最终绿色的线为A元素margin的right最终的位置,这个位置也将作为它右边紧跟的B元素margin-left的参考线,而DEMO1中B并未设置margin,即margin默认为0,很显然,B元素就出现在绿色线之后,而覆盖上A元素之上则是由于DOM中后面元素比前面元素优先级高的缘故(当然你也可以为A设置”position:relative”而使A覆盖在B之上)。

    来看下DEMO2,A并未设置margin则margin默认为0,B设置了margin-left为-50px,B的margin-left是以A的margin的right的位置为参考线,此时A的margin为0,则B的margin-left即以A的右border为参考线开始位移,如果是正值则是向右位移,现在是负值即向左位移,所以最终也会和DEMO1一样呈现出一样的现象:B覆盖于A之上,位移大小为50px。

    DEMO3中的关系其实是父子元素的关系,根据前面的“left 以 containing block 的 content 左边向右位移”的规则,A设置了margin-left为-50px,本是正值向右位移,现在是负值,则向左位移50px,参考线是包含块的content左侧,来看下图:

    按照“left 以 containing block 的 content 左边向右位移”的规则,这时A的margin的left应从图示蓝色线开始位移,如果是正值则向右位移,但现在是负值,于是向左位移,最终绿 色的线为A元素margin的left最终的位置。

    DEMO4其实和DEMO3是一个性质,由于是父元素本身margin的left发生位移,那么它就会依据DEMO3一样继续去找它的包含块的content左侧,发生了左移也是很好理解的,至于其中的A只是混淆视听罢了,在父元素中,A其实是相对于父元素静止的。

    通过四个DEMO的分析,并加入参考线的概念后大家是否可以理解了呢?不知道各位有没有这样一个疑问:margin-left的时候元素本身发生了位移,但margin-right为何并没有致使本身发生位移?下面谈谈我个人的理解:

    元素之间有个例如DEMO1中的A元素设置了margin-right为-50px,按道理讲应当向右位移50px,但是根据页面排版顺序来讲,必须先渲染左边的元素,渲染完了再渲染右边的元素,那么这时右边元素的位置则依赖于左边的元素,左边元素的margin-right不可能先去找右边元素的参考线,左边元素的margin-right的作用仅仅是提供了右边元素margin-left的参考线。而如果是父子元素的关系,则最左边的子元素的margin-left则依赖于它的包含块。注意了,这里有一个特殊情况,当为元素设置了”float:right”时,元素会脱离布局流,这时如果再为它设定marign-right为-50px时,它本身会发生偏移,因为它依赖于它的包含块。这与怿飞总结的“如果是负的 top 或 left 值会引起 box 的向上或向左位置移动,如果是 bottom 或 right 只会影响下面 box 的显示的参考线”的也是有出入的。

    http://www.hicss.net/i-know-you-do-not-know-the-negative-margin/

    http://www.w3school.com.cn/css/css_margin_collapsing.asp

    http://www.planabc.net/2007/03/18/css_attribute_margin/

    http://www.smallni.com/negative-margin/

    http://www.zhihu.com/question/20116963

    http://www.hicss.net/do-not-tell-me-you-understand-margin/

    http://www.hicss.net/separation-of-powers-model-in-css-design-patterns/

    http://www.cnblogs.com/dolphinX/p/4071725.html

  • 相关阅读:
    cv2 Qt Platform plugin "cocoa" not found error
    开发scrapy web界面(一)
    java2smali python 粘合脚本
    react如何设置代理
    Nginx启动不了失败原因
    前端,后端,服务器如何部署,转载
    匿名函数普通函数和构造函数
    闭包的认识
    各种命名规范,打好基础才能建设高楼
    mongoose常用操作
  • 原文地址:https://www.cnblogs.com/SunBlog/p/4492387.html
Copyright © 2020-2023  润新知