首页 > margin负值的问题

margin负值的问题

经典的三列布局,俗称双飞燕布局,左右两列宽度固定,中间自适应三列都设置为左浮动,直接上代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
    body{ margin: 0; padding: 0;}
    .left , .right{  height: 300px;   width: 200px; float: left;}
    .right{ margin-left: -200px; background-color: red; }
    .left{ margin-left: -100%;background-color: #080808; }
    .middle{  height: 300px;  width: 100%; float: left; background-color:    blue;}
</style>
</head>
<body>
<div class="middle">middle</div>
<div class="left">left</div>
<div class="right">right</div>
</body>
</html>

一般用float布局,当一列排满的时候,假如其他还有float元素,那么它在碰到其他float元素,会靠在右边,当一行排满,它就会在第二行重新排列,这里middle width=100%,那么leftright 是不是应该排在下一行,但是当你给left设置margin-left:-100%,right设置margin-left:-200px 大于其自身的宽度时,都跑到第一行去了 (一定要设置大于-200px,否则跑到第二行)
这里的疑问就是,当一个float元素他的margin负值大于他的宽度时会发生什么?有哪些奇怪的特性?


我觉得左中右这种布局用FLEX就好,没那么麻烦。


你想的太复杂,其实很简单。只要你理解文档流就行(自上向下,自左向右)。

你可以把middle的宽度设为50%,然后把left的margin-left设为-50%,right的不变。


跟100%的时候除了宽度之外基本一致。
也就是说,100%宽度时,可以把第二行拼在第一行的末尾,当成同一行来看待。当没有设置margin-left时,两者紧紧连在一起,设置-100%之后,left便向左移动了一个窗口的宽度(上面有个回答说错了,百分比始终相对的是父级元素的宽度),所以到了最左上的位置。而由于middle的最右比left的最右更贴近right,所以此时right的margin-left是相对于middle的。
所以就会出现这种效果。


.left 的 -100% 是 .middle 的宽度,
.right 的 -200px 是自己的宽度。

来解释下这个布局:

三个元素都是 float: left, 那么它们三个会根据其代码顺序依次排列:.middle -> .left ->  .right。

浏览器解析时,

先放 .middle, 宽度 100% 已经撑满一行;
再放 .left, 宽度 200px, { 到容器左侧距离 } 为 .middle 宽度 100% , 换行显示到最左边;
最后放 .right, 宽度 200px, { 到容器左侧距离 } 100% + 200px, 换行紧接着 .left 显示。

然后让 .left 显示到第一行最左边:

第一行最左边即 { 到容器左侧距离 } 为 0, 当前 { 到容器左侧距离 }  = 100%, 我们给它减去 100% 即可,因而设置 margin-left: -100%;

最后让 .right 显示到最右:

第一行最右即 { 到容器左侧距离 } 为 100% - 自身宽度, 当前 { 到容器左侧距离 }  = 100%,所以设置 margin-left: -200px 即可。

1.一个元素的宽度为margin+padding+border+内容宽度
2.一个float:left的元素的左外边界必须再其前面出现的float:left元素的右外边界的后面,并且元素的的左边界不能超过其包裹元素的左内边界,右外边界也不能超过包括元素的右内边界
3.一个float:left元素的左外边界必须在其之前的任何一个float:left元素的右外边界的右边

如题中的css的定义及float元素在DOM中的位置
按HTML代码的顺序,首先放middle元素,然后是left,最后是right
1..middle元素首先放置,占据整个父元素的宽度(container_width)
2..left元素接下来放置,其宽度为200px,margin-left:-100%
3..left元素的左外边界必须在middle元素右外边界的右边。margin-left:-100%形成的效果是元素的左外边界在.left元素的左内边界向左100%*container_width处,同时需要满足前面提到的规则,那么形成的效果是.left元素整体向左边移动了100%*container_width,其左内边界和middle的左外边界对齐。.left元素的右外边界位于middle元素的左外边界的的200处。
3..right元素接下来放置,宽度为200px,margin-left:-200px,.right的左外边界在其左内边界向右200px;
4..right元素的左外边界必须在之前出现的float:left右外边界的右边,对之前.left元素和.middle元素的分析,这个位置点就是.middle元素的右外边界;形成的效果就是.right元素左内边界向左移动了200px

如果.right元素的设置margin-left:-100px时,元素宽度为-100+200=100px。如果放在.middle同一行那么其右边界将超过包裹元素的的右内边界,故.right将换行显示,并且左外边距将向右边移动100px,看到的效果是.right元素只有100宽度的内容可见


我来回答一下,是不是题主想要的,请题主自取。

既然题主都写了那么多代码,在试了,为何不自己试试呢?也许是题主秉着要让大伙一起学习的精神,让我们一起参与下^_^。

其实对于标签的这种层级处理,题主可以发挥想象一下。
比如,一个div就是一个区域,我设置为100%,那么肯定就铺满了当前区域,这里我们成为A。
我在来一个div,称之为B,不设置float之前,肯定是放不下的,所有就会放到A的下面(要结合实际想象)。

如果把A和B都设置了float(这里就需要去了解一下float的特性),那么B应该是在A的右边,而不是下边(如果放得下的话,可惜放不下,所有B还在A的下边)。

那么B设置margin-left:-100%呢(你还是要把B当做是在A旁边的,不是下面),你就会发现B到了现在A的位置。

至于有啥浏览器表现很怪异啦,告诉你,也是可能的,所以,最终结果还是以自己尝试为准。
ps:以上内容,纯属瞎扯,信了概不负责!


flex 布局可能会更好用


这样把middle的两边都覆盖了

【热门文章】
【热门文章】