资讯专栏INFORMATION COLUMN

理解并运用 CSS 的负 margin 值

Alan / 1155人阅读

摘要:大多数情况下,我们采用的都是正数的值,可能有时候会用到负的值。但是,本文要说明的就是,负的值并不是,这是正常范围内的写法。所以,具体行为按照以下几种情况说明。我们为设置了两个的负值,分别是,以及。

本文样式代码采用 SCSS。

浏览器兼容性为 IE6+。

你的网页中,不可能没有使用过 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 设置负值需要根据设置的方向以及元素是否浮动以及其定位方式来判断最终的行为。

所以,具体行为按照以下几种情况说明。

第一种情况:元素没有设置浮动且没有设置定位或者 positionstatic

如果元素没有设置浮动并且没有设置定位或者 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 也是同样的道理。

同时,在元素不指定宽度的情况下,如果设置 margin-left 或者 margin-right 为负值的话,会在元素对应的方向上增加其宽度。效果就和设置 padding-left 或者 padding-right 一样。

第二种情况:元素没有设置浮动且 positionrelative

如果元素没有设置浮动,但是设置了相对定位,设置 margin 为负值的时候,表现如下:

设置的 margin 的方向为 top 或者 left

当设置负值的 margin 的方向为 top 或者 left 的时候,元素也会按照设置的方向移动相应的距离。

设置的 margin 的方向为 bottom 或者 right

当设置 margin-bottom/left 的时候,元素本身也不会移动,元素后面的其他元素也会往该元素的方向移动相应的距离,但是,该元素会覆盖在后面的元素上面 (当然,此处说的情况肯定是后面的元素没有设置定位以及 z-index 的情况)。

第三种情况:元素没有设置浮动且 positionabsolute

如果元素没有设置浮动,但是设置了绝对定位,设置 margin 为负值的时候,表现如下:

设置的 margin 的方向为 top 或者 left

当设置负值的 margin 的方向为 top 或者 left 的时候,元素也会按照设置的方向移动相应的距离。

设置的 margin 的方向为 bottom 或者 right

由于设置绝对定位的元素已经脱离了标准文档流,所以,设置 margin-right/bottom 对后面的元素并没有影响。

第四种情况:元素设置了浮动

肯定没有既设置了浮动又设置绝对定位的情况,那样太荒唐了。
设置了浮动的元素,再设置 postion: relative; 的话,元素的行为和多带带设置 float 是一样的。

对于设置了浮动的元素,设置 margin 为负值的时候,表现如下:

如果设置的 margin 的方向与浮动的方向相同,那么,元素会往对应的方向移动对应的距离。

比如:

.elem {
    float: right;
    margin-right: -100px;
}

该元素则会向右移动 100px。

如果设置 margin 的方向与浮动的方向相反,则元素本身不动,元素之前或者之后的元素会向钙元素的方向移动相应的距离。

比如:

.elem {
    float: right;
    margin-left: -100px;
}

位于该元素左边的元素则会向右移动 100px,同时覆盖在该元素上。

如果后面的元素也设置了浮动的话,我们以一个具体的例子来说明。

.container {
    min-height: 300px;
    margin: 30px auto;
    overflow: hidden;
    border: 1px solid #000000;
   
    .left {
        float: left;
        width: 400px;
        height: 200px;
        margin-right: -300px;
        background: purple;
    }
    
    .right {
        float: left;
        width: 300px;
        height: 200px;
        background: #cccccc;
    }
}

.left.right 都设置了浮动,在 .left 上设置了 margin-right: -300px;,那么,.right 会向左移动 300px,从而覆盖在 .left 上。这种行为与没有既没有设置浮动也没有设置定位的表现类似。

到此,我们把设置负 margin 的各种情况以及在各种情况下的表现都大概了解了一遍。那么,我们真正运用到实际中会是什么样子呢。

半遮挡的标题

原谅我措辞不好,大概就是下图的效果:

按照一般的思想,肯定是直接给 title 设置绝对定位,然后再将其调整过去。

但是,按照我们现在所说的,其实很简单就能实现这个效果。

这里只写了主要部分的代码。

Hey This is title!
Hah! This is content.
.title {
    position: relative;
    width: 200px;
    height: 60px;
    margin-bottom: -30px;
    margin-left: -20px;
    background: #000000;
}

.content {
    max-width: 800px;
    height: 400px;
    padding: 0 50px;
    background: yellow;
}

我们为 title 设置了两个 margin 的负值,分别是 margin-bottom: -30px;,以及 margin-left: -20px;

设置 margin-bottom 是为了让 content 向上移动,设置 margin-left 是为了让 title 向左移动一小段距离。

还有个需要注意的地方就是,需要给 title 设置 position: relative;,根据我们的第二种情况所说的,这样,才能保证 title 覆盖在 content 之上。

简单的一列定宽的两列流式布局

根据我们的最后一种情况,通过设置 margin 为负值,我们可以很容易的实现一列定宽的两列流式布局。

.left {
    float: left;
    width: 100%;
    height: 200px;
    margin-right: -300px;
    background: purple;
}
.right {
    float: left;
    width: 300px;
    height: 200px;
    background: #cccccc;
}

唯一需要注意的地方就是设置了 100% 宽度的元素上的 margin 负值的绝对值一定要和定宽的元素的宽度相同。

两边固定,中间自适应的三列布局

这是一个很老的话题了,以前也有各种实现的方式,比如双飞翼布局,或者圣杯布局。

我们此处就以双飞翼布局来作示例。

先设置页面结构:

此处我们没有把 center 放在中间,具体原因后面会解释。

然后,我们设置这三列都浮动:

.left,
.right,
.center {
    float: left;
    height: 500px;
}

同时为他们指定宽度:

.left {
    width: 300px;
    background: #000000;
}

.right {
    width: 400px;
    background: #00FFFF;
}

.center {
    width: 100%;
    background: #93c759;
}

现在我们要让 left 在左边,相当于就是让它覆盖在 center 的上面,所以,只需要这样一句:

margin-left: -100%;

同时,要让 right 在右边,同理,这样设置:

margin-left: -400px;

注意,此处的 margin 值的绝对值与 right 的宽度值相同。

其实,这样设置,我们的三列布局就基本完成了。

那么,我们为什么要把 center 放在 left 和 right 之前呢?

这个其实涉及到元素的堆叠顺序的知识 (这里就不详细讲解了,后面有时间的话专门拿一篇文章来讲解吧),此处简单说明一下。

由于我们的三列都设置了浮动,所以,从某种意义上说,它们三个是在同一个平面的 (相当于 z-index 相同),那么,这里就不能根据 CSS 来判断堆叠顺序了。所以,此处的 HTML 结构就决定了它们的堆叠顺序:所谓后来居上。

我们要让 left 在 center 之上,所以,肯定需要让 left 元素放在 center 之前。

所以,三列布局完整的 SCSS 代码如下:

.container {
    overflow: hidden;
    
    .left,
    .right,
    .center {
        float: left;
        height: 500px;
    }
    
    .left {
        width: 300px;
        margin-left: -100%;
        background: #000000;
    }
    
    .right {
        width: 400px;
        margin-left: -400px;
        background: #00FFFF;
    }
    
    .center {
        width: 100%;
        background: #93c759;
    }
}
References

margin-properties | W3C

The Definitive Guide to Using Negative Margins

双飞翼布局和圣杯布局的对比

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/111640.html

相关文章

  • CSS的负边距

    摘要:之后仔细的百度了一下,发现了这么一个叫做内外补丁负值法的东西。在这个解决方案中,又涉及到了传说中的负。深入研究之后又发现了圣杯布局双飞翼布局等很多示例,确实要好好研究负边距这个东西了。相关推荐那些年,奇妙的圣杯与双飞翼,还有负边距 2015-04-22 时候写的老文,因为希望引用所以拿了出来。 那天被一个同学问了一个问题,三列的div,要求父div的高度和三个div的高度都和三个中字数...

    cocopeak 评论0 收藏0
  • margin详解

    摘要:属性指定了盒的区的宽度。简写属性一次性设置四周的,而其它属性只设置它们各侧的。 margin属性指定了盒的margin区的宽度。margin简写属性一次性设置四周的margin,而其它margin属性只设置它们各侧的。这些属性适用于所有元素,但非替换行内元素上的竖直margin将不会产生任何效果 margin与容器尺寸 margin与可视尺寸 margin与可视尺寸 只适用于没有设定...

    stonezhu 评论0 收藏0
  • CSS布局十八般武艺都在这里了

    摘要:清单一些说明注意文档的书写顺序,先写两侧栏,再写主面板,更换后则侧栏会被挤到下一列圣杯布局和双飞翼布局都会用到。可以通过设置的属性或使用双飞翼布局避免问题。双飞翼布局不用设置相对布局,以及对应的和值。 本文首发于知乎专栏:前端指南 CSS布局 布局是CSS中一个重要部分,本文总结了CSS布局中的常用技巧,包括常用的水平居中、垂直居中方法,以及单列布局、多列布局的多种实现方式(包括传统的...

    includecmath 评论0 收藏0
  • CSS概念【记录】

    摘要:语法规则注释层叠优先级继承值块格式化上下文盒模型层叠上下文可替换元素外边距合并包含块视觉格式化模型布局模式语法属性值声明声明块规则规则集规则规则一个语句定义样式表使用的字符集告诉引擎引入一个外部样式表嵌套规则如果满足媒介查询的条件则条件规则 1、CSS语法 2、@规则 3、注释 4、层叠 5、优先级 6、继承 7、值 8、块格式化上下文 9、盒模型 10、层叠上下文 11、可替换元素 12、...

    番茄西红柿 评论0 收藏0
  • CSS 外边距(margin)重叠及防止方法

    摘要:结果的边界宽度是相邻边界宽度中最大的值。但是边界的重叠也有例外情况水平边距永远不会重合。外边距重叠示例外边距重叠是指两个垂直相邻的块级元素,当上下两个边距相遇时,起外边距会产生重叠现象,且重叠后的外边距,等于其中较大者。边距重叠解决方案(BFC) 首先要明确BFC是什么意思,其全英文拼写为 Block Formatting Context 直译为块级格式化上下文   两个或多个块级盒子的垂直...

    刘东 评论0 收藏0

发表评论

0条评论

Alan

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<