css 理解margin负值对浮动元素的影响

在学习三栏布局的时候,很多地方都有用到margin的负值。但《css 权威指南》却没有提到有关浮动元素使用margin负值的内容,索性自己整理总结一下。若无特殊说明,本文的盒模型都是基于content-box模式下的,并且只针对宽度进行讨论。

涉及的概念有点多,理解原理就好懂了,希望能对你有所帮助。

预备知识 

盒模型

一般来说,盒模型包括 margin、border、padding、content 四个部分,而《css权威指南》为了方便解释一些概念,它加上了内边界和外边界,分别指代上图内外两个虚线框位置(估计可忽略)。

盒子的内容区域/可见区域/总体区域

顾名思义,盒子的内容区域就是除去边框边距后的内容部分。而可见区域就是盒子(设置背景颜色后)的非透明的部分,总体区域则还包括了透明的margin部分,所以有如下定义:

  • 盒子的可见区域 = 盒子在页面占据的大小,即 内容区域 + padding + border。
  • 盒子的总体区域 = 盒子可见区域 + margin,即 内容区域 + padding + border + margin
  • 盒子的内容区域,看接着下面的解释。

举个例子,下面两张图分别是浏览器查看元素时普通展示元素时的效果。

       

盒子的box-sizing

默认情况下,盒子的box-sizing为content-box。

  • 当box-sizing为content-box时,盒子可见宽度 = css设置的width(内容区域宽度) + 左右padding + 左右border,即随着padding、border的增大,盒子可见宽度增大,css设置的width(内容区域宽度)不变。
  • 当box-sizing为border-box时,盒子可见宽度 = css设置的width(包含内容区域宽度 + 左右padding + 左右border),即随着padding、border的增大,盒子可见宽度不变,css设置的width(内容区域宽度)变小。
  • 当box-sizing为border-box时,如果padding和border占据的不断增大,会挤占内容区域宽度至0,且使得盒子的可见宽度增大,但此时盒子已经没有内容区域了,空有padding和boder。
  • 本文重点非讨论border-box模式,仅做比较。

由此可见,无论是哪种模式,盒子可见宽度并非一定等于css设置的width。

下图展示的是同样的样式时,分别在content-box和border-box模式下浏览器查看元素时的效果。

    div {
      width: 100px;
      height: 100px;
      padding: 20px;
    }

         

总结一句,box-sizing决定width从何处算起,不同的模式,width的实际内涵不一样。


margin负值对浮动元素的影响

由上述内容可知,盒子总体宽度 = css设置的width(内容区域宽度)+ 左右padding + 左右border + 左右margin。

一般情况下,这些值都是正值,但当浮动元素的margin为负的时候,会有什么效果呢?(注意,padding和border没有负值)

代码及图示如下(已去多余样式),有两个左浮动的盒子,我们尝试给下方绿盒子添加负值 margin。

  <div class="outer">
    <div class="inner1">上</div>
    <div class="inner2">下</div>
  </div>
    .outer {
      width: 300px;
      height: 300px;
    }

    .inner1 {
      float: left;
      height: 100px;
      width: 180px;
    }

    .inner2 {
      float: left;
      height: 100px;
      width: 150px;
    }

 初始状态

           

当 margin-left = -29px时

此时,绿盒子向左移动了29px。

当 margin-left = -30px 时

此时,绿盒子跑到了第一行,并且与红盒子的右端重合了30px,为什么呢?

初始状态时,第一行的右边只剩下120px,已经装不下绿盒子了,所以绿盒子被挤到第二行。

已知,盒子的总体宽度 = 内容宽度 + 左右padding + 左右border + 左右margin,所以当给绿盒子设置margin-left = -30px时,绿盒子的总体宽度为 150px + (0 + 0) + (0 + 0)+(- 30px + 0 )= 120px,所以刚刚好能够浮动上第一行的右边。

可以这么理解,就像浮动元素会浮在标准流元素上方以及z-index更高的定位元素会覆盖到其他定位元素上

因为给绿盒子设置了margin-left = -30px,所以绿盒子的左边30px宽度的区域“浮”得更高了,对于红盒子来说,这绿盒子左端这30px相当于没有了。或者,还可以想象为绿盒子左端30px的z坐标轴上的值更大了,这30px已经不占这层页面的宽度了,所以我们看到绿盒子与红盒子重叠30px。

     

当 margin-left = -180px 时

相当于在 margin-left = -30px的基础上,再加上margin-left = -150px,即继续向左移动150px。

此时绿盒子的左端与红盒子的左端刚刚好重叠。

     

当 margin-left = -330px 时

由于现在已经是第一行,所以绿盒子不会继续往上一行走了,只会继续向左移动。

此时,绿盒子刚刚离开父盒子,而且右端与父盒子左端重叠。

    

当 margin-right = -29px 时

绿盒子的总体宽度为 150px + (0 + 0) + (0 + 0)+(0 - 29px)= 121px,此时绿盒子总体宽度大于第一行剩余宽度120px,所以还不能移动上第一行。

当 margin-right = -30px 时

我们知道当 margin-left = -30px 时,绿盒子可以移动到第一行上去,那当 margin-right = -30px 时呢?答案也是肯定的。

当给绿盒子设置margin-right = -30px时,绿盒子的总体宽度为 150px + (0 + 0) + (0 + 0)+(0 - 30px)= 120px,所以刚刚好能够浮动上第一行的右边。

但 margin-left = -30px 和 margin-right = -30px 的不同之处在于,前者是与红盒子重叠了30px且没有溢出父盒子,后者是没有与红盒子重叠但溢出了父盒子右侧30px。

可以这么理解,虽然给绿盒子设置了margin-right = -30px,绿盒子的右边30px宽度的区域“浮”得更高了,但是左边的部分依旧是实打实占据了120px宽度的,并没有“浮”起来。只是因为绿盒子总体宽度刚好为120px,所以才会上到第一行上去,所以并不能像margin-left = -30px的情况一样与红盒子重叠。

    

当 margin-right = -150px 时

当给绿盒子设置margin-right = -150px时,绿盒子的总体宽度为 150px + (0 + 0) + (0 + 0)+(0 - 150px)= 0px,按道理说此时绿盒子总体宽度已经为0,整体已经没有“实际”占据的宽度了,为什么没有覆盖到红盒子上方呢?甚至 设置margin-right = -180px,-300px....都是一样的结果。

有博客说是margin-right负值持续变大之后,元素向右移动与左浮动的效果抵消了(勉强解释)。

这种左浮动+右负外边距或者右浮动+左负外边距特殊情况暂且先记忆一下吧,如果有了解的可以告知一声(捂脸)。

后记

  • 右浮动的各种情况自行类比。
  • 左浮动右负外边距 或者 右浮动左负外边距 的特殊情况记住就好(捂脸)。
  • 标准流的负margin中,margin-right比较特殊,在没有设置盒子宽度时候,设置负值margin-right会让盒子向右变长(如下图);在有盒子宽度时候,设置负值margin-right一般没有任何效果。
  • 标准流的其他负margin,可以简单概括为与正值margin效果相反。
  • 启发:https://blog.csdn.net/Liu_yunzhao/article/details/103976547

 

 

 

  • 12
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值