理解并运用 CSS 的负 margin 值
你的网页中,不可能没有使用过 margin。大多数情况下,我们采用的都是正数的 margin 值,可能有时候会用到负的 margin 值。在我们的印象中,负的 margin 值就类似于浏览器的 hack 一样,不被人接受。但是,本文要说明的就是,负的 margin 值并不是 hack,这是正常范围内的写法。
Negative values for margin properties are allowed, but there may be implementation-specific limits. —— W3C
根据 W3C,margin 是能够接受负值的,只是在具体实现上有一些区别。
那么,设置 margin 为负值究竟会是什么样的效果呢?
与设置正值不同,margin 设置负值需要根据设置的方向以及元素是否浮动以及其定位方式来判断最终的行为。
所以,具体行为按照以下几种情况说明。
第一种情况:元素没有设置浮动且没有设置定位或者 position 为 static
如果元素没有设置浮动并且没有设置定位或者 position 属性为 static 的情况下,对元素的 margin 设置负值会有以下的效果:
设置的 margin 的方向为 top 或者 left
当设置负值的 margin 的方向为 top 或者 left 的时候,元素会按照设置的方向移动相应的距离。
比如,设置 margin-left: -100px;。 那么,元素会往左移动 100px。对于设置 margin-top 也是一样的道理。
设置的 margin 的方向为 bottom 或者 right
当设置负值的 margin 的方向为 bottom 或者 right 的时候,元素本身并不会移动,元素后面的其他元素会往该元素的方向移动相应的距离,并且覆盖在该元素上面。
比如,设置 margin-right: -100px;。那么,元素本身并不会移动,后面的元素会向左移动 100px 到该元素上。对于设置 margin-bottom 也是同样的道理。
第二种情况:元素没有设置浮动且 position 为 relative
如果元素没有设置浮动,但是设置了相对定位,设置 margin 为负值的时候,表现如下:
设置的 margin 的方向为 top 或者 left
当设置负值的 margin 的方向为 top 或者 left 的时候,元素也会按照设置的方向移动相应的距离。
设置的 margin 的方向为 bottom 或者 right
当设置 margin-bottom/left 的时候,元素本身也不会移动,元素后面的其他元素也会往该元素的方向移动相应的距离,但是,该元素会覆盖在后面的元素上面 (当然,此处说的情况肯定是后面的元素没有设置定位以及 z-index 的情况)。
第三种情况:元素没有设置浮动且 position 为 absolute
如果元素没有设置浮动,但是设置了绝对定位,设置 margin 为负值的时候,表现如下:
设置的 margin 的方向为 top 或者 left
当设置负值的 margin 的方向为 top 或者 left 的时候,元素也会按照设置的方向移动相应的距离。
设置的 margin 的方向为 bottom 或者 right
由于设置绝对定位的元素已经脱离了标准文档流,所以,设置 margin-right/bottom 对后面的元素并没有影响
第四种情况:元素设置了浮动
肯定没有既设置了浮动又设置绝对定位的情况,那样太荒唐了。
设置了浮动的元素,再设置 postion: relative; 的话,元素的行为和单独设置 float 是一样的。
对于设置了浮动的元素,设置 margin 为负值的时候,表现如下:
.elem {
float: right;
margin-left: -100px;
}
|
该元素则会向右移动 100px。
.elem { float: right; margin-left: -100px; }
|
|
.left 和 .right 都设置了浮动,在 .left 上设置了 margin-right: -300px;,那么,.right 会向左移动 300px,从而覆盖在 .left 上。这种行为与没有既没有设置浮动也没有设置定位的表现类似。
到此,我们把设置负 margin 的各种情况以及在各种情况下的表现都大概了解了一遍。那么,我们真正运用到实际中会是什么样子呢。
半遮挡的标题
两边固定,中间自适应的三列布局
这是一个很老的话题了,以前也有各种实现的方式,比如双飞翼布局,或者圣杯布局。
我们此处就以双飞翼布局来作示例。
其实,这样设置,我们的三列布局就基本完成了。
那么,我们为什么要把 center 放在 left 和 right 之前呢?
这个其实涉及到元素的堆叠顺序的知识 (这里就不详细讲解了,后面有时间的话专门拿一篇文章来讲解吧),此处简单说明一下。
由于我们的三列都设置了浮动,所以,从某种意义上说,它们三个是在同一个平面的 (相当于z-index 相同),那么,这里就不能根据 CSS 来判断堆叠顺序了。所以,此处的 HTML 结构就决定了它们的堆叠顺序:所谓后来居上。
我们要让 left 在 center 之上,所以,肯定需要让 left 元素放在 center 之前。