实用的margin负值

评审侠
• 阅读 8042

无论是在介绍前端知识的书籍还是谈论盒模型的文章,margin 都是最重要的属性之一,然而它的负值用法却极少被提到。其实 margin 负值是一个相当实用的属性,可以被应用于日常前端开发当中的不少场景。

margin 负值初体验

与正值的 margin 一样,margin 的负值同样可以被用于上下左右四个方向,我把它所起到的效果总结为:

上和左方的 margin 负值使该元素向上和左方向移动。

下和右方的 margin 负值使该元素下方、右方的元素被拉向该元素。

我们通过几个简单的小例子去理解。传送门......

在例子当中一个大的正方形包裹着两个分别是蓝色和黄色的正方形,分别对蓝色的正方形使用上、下、左、右四个方向的 margin 负值。

结果我们可以看到,使用margin-top: -50pxmargin-left: -50px 的例子,蓝色正方形分别向上方和左方移动了50个像素。

实用的margin负值

实用的margin负值

而使用 margin-bottom: -50pxmargin-right: -50px 的例子,位于下方和右方的黄色正方形向蓝色正方形方向移动了50个像素,覆盖了蓝色正方形的一部分。

实用的margin负值

实用的margin负值

原理浅析

产生上述两种情况的差异是由于 margin 在上、左方和下、右方解析逻辑有所不同。这里引用怿飞博客《由浅入深漫谈margin属性》 中参考线的概念。

实用的margin负值

产生上述两种情况的差异是由于 margin 在上、左方和下、右方解析逻辑有所不同。这里引用怿飞博客《由浅入深漫谈margin属性》 中参考线的概念。

简单来说就是上、左方和下、右方参考线的不同导致的。

margin 上方负值以包含块(Containing block) 内容区域的上边或者上方相连元素 margin 的下边为参考线

margin 左方负值以包含块(Containing block) 内容区域的左边或者左方相连元素 margin 的右边为参考线

margin 下方负值以元素本身 border 的下边为参考线

margin 右方负值以元素本身 border 的右边为参考线

所以使用 margin 上、左方负值时可以理解为与参考线的距离减少,导致元素产生位移;使用使用 margin 下、右方负值时可以理解为参考线向上、右方移动。

深入理解可以看《由浅入深漫谈margin属性》。另外,关于包含块( Containing block )

margin 负值在实际当中的应用

margin 负值虽然不是常常被提起,但是在实际当中已经有相当广泛的应用。现在来看几个实例。

大众点评团购城市列表

http://t.dianping.com/citylist

上图每一个城市之间都有一条浅灰色竖线作为分割符,查看源码我们可以发现它其实是每个li元素的左边界,然而通常使用border来完成类似需求时我们不希望第一个(或最后一个)li 元素出现border,因此我们通常会在第一个(或最后一个)li 元素添加 frist-item(或 last-item) 的 class 使他们不显示,而这里的城市列表用了一个更加简单的方法:每一个li 元素添加一个像素左方向的 margin 负值。

.list li .cityes li {
    border-left: 1px solid #ccc;
    margin: 17px 0 0 -1px;
    /* 省略其余代码 */
}

第一个城市的左方 border 就这样被隐藏了。

实用的margin负值

segmentfault 首页tab

http://segmentfault.com/

实用的margin负值

完成类似的tab效果,我们需要分别给各个 tab 元素和其父元素添加 border,这个时候会出现双边框的情况。segmentfault 的解决方法是给每一个tab元素添加一像素下方的 margin 负值。

另外,为了类似上一个例子中的城市列表,这里的元素添加了一个像素的右方的 margin 负值,tab 元素之间不会出现双边框的情况。

.nav-tabs {
    border-bottom: 1px solid #ddd;
    /* 父元素ul */
}
.nav-tabs > li {
    margin-bottom: -1px;
    /* 省略其余代码 */
}
.nav-tabs-zen > li > a {
    margin-right: 1px;
    border: 1px solid #ddd;
    /* 省略其余代码 */
}

Bootstrap 网格系统

在 Bootstrap 的网格系统当中,每一个使用 col-**-* 类的列元素都应该包裹在 row 类的元素当中。为了使页面美观每个 col-**-* 的类都设置了左、右15个像素的补白 padding,这样会导致一个结果,第一个和最后一个元素会离开容器15个像素的距离。为此,Bootstrap在 row 类当中分别定义了左、右方向15个像素的 margin 负值来抵消第一列和最后一列产生的左右补白。

实用的margin负值

.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, 
.col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, 
.col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, 
.col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, 
.col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, 
.col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, 
.col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, 
.col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, 
.col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, 
.col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, 
.col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, 
.col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
  position: relative;
  min-height: 1px;
  padding-right: 15px;
  padding-left: 15px;
}

.row {
  margin-right: -15px;
  margin-left: -15px;
}

左右并排布局

在做左右并排布局时候,除了可以使用 float 或者 inline-block 之外,还可以尝试使用 margin 负值。

直接上例子

最后

利用 margin 负值可以简单直接的解决某些我们日常开发当中遇到的问题,margin 负值还有很多其余的使用实例,这里不一一叙述,只要平时多看看别人写的代码,就会发现 margin 负值的应用其实无处不在。

感谢您的阅读,有不足之处请在评论为我指出。

参考

  1. 由浅入深漫谈margin属性

  2. 我知道你不知道的负Margin

  3. Bootstrap框架的网格系统工作原理

本文同步于我的个人博客 http://blog.acwong.org/2014/12/06/negative-margins/

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
风花雪月 风花雪月
2年前
html加css样式,不用js实现切换内容,直接上测试代码!
/清样式,如果是项目中,不推荐使用通配符来清样式,建议使用标签清样式,通配符清样式会增加页面压力/margin:0;padding:0;/宽度为屏宽的一半,高度为屏高的一半,然后居中/.boxwidth:50vw;height:50vh;margin:0a
Nick16 Nick16
4年前
前端面试题全覆盖整理
本篇文章整理总结了一些前端面试题,涵盖面很广,并且面的都是知名大厂,所以这些题还是很有代表性的,都掌握以后一面基础面应该没什么问题,二面也能应付大半,奉上:css相关1.万能居中1.margin:0auto;水平2.textalign:center;水平3.行高,垂直4.表格
Stella981 Stella981
3年前
Boost(1.69.0) windows入门(译)
<head<title缩进2字符</title<styletype"text/css".yindent,.yblock{padding:1em1em01em;marginright:0;}.yindent{margin:0.7em2em;border:mediumoutset;}.yblock{margin
Wesley13 Wesley13
3年前
Java Scheduler ScheduledExecutorService ScheduledThreadPoolExecutor Example(ScheduledThreadPoolEx...
<divclass"entrycontent"itemprop"text"<!QuickAdsenseWordPressPlugin:http://quickadsense.com/<divstyle"float:none;margin:10px010px0;textalign:center;"<di
Wesley13 Wesley13
3年前
QQ空间说说生成器
index.html<html<head<metaname"viewport"content"widthdevicewidth,initialscale1,userscalableno"<stylebody{margin:0;padding:
Stella981 Stella981
3年前
CSS外边距合并导致margin越界的问题
外边距合并其实经常会遇到,这里稍微总结一下,以及一些相关的术语一、什么是外边距合并?(折叠外边距)外边距合并指的是当两个垂直外边距相遇时,它们将形成一个外边距。合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者;而左右外边距不合并。在CSS当中,相邻的两个盒子(可能是兄弟关系也可能是祖先关系)的外边距可以结合成一个单独的外
PyTorch已为我们实现了大多数常用的非线性激活函数
PyTorch已为我们实现了大多数常用的非线性激活函数,我们可以像使用任何其他的层那样使用它们。让我们快速看一个在PyTorch中使用ReLU激活函数的例子:在上面这个例子中,输入是包含两个正值、两个负值的张量,对其调用ReLU函数,负值将取为0,正值则保持不变。现在我们已经了解了构建神经网络架构的大部分细节,我们来构建一个可用于解决真实问题的深度学习架构。
PyTorch已为我们实现了大多数常用的非线性激活函数
PyTorch已为我们实现了大多数常用的非线性激活函数,我们可以像使用任何其他的层那样使用它们。让我们快速看一个在PyTorch中使用ReLU激活函数的例子:在上面这个例子中,输入是包含两个正值、两个负值的张量,对其调用ReLU函数,负值将取为0,正值则保持不变。现在我们已经了解了构建神经网络架构的大部分细节,我们来构建一个可用于解决真实问题的深度学习架构。
linbojue linbojue
1年前
html--心花怒放
代码Canvas绘制一个❤html,bodyheight:100%;padding:0;margin:0;canvasposition:absolute;width:100%;height:100%;CanvasNotSupport/Settings/va