margin负值-内秀篇
zccst整理
- margin系列之布局篇
- margin系列之bug巡演(三)
- margin系列之bug巡演(二)
- margin系列之内秀篇(二)
- margin系列之bug巡演
- margin系列之内秀篇
- margin系列之外边距折叠
- margin系列之与相对偏移的异同
- margin系列之百分比
- margin系列之keyword auto
一样东西在不同的场景,不同的人手里,所能做的事会有很大不同。我深切的以为 margin
绝对是 CSS 中最有能力的利器之一,不知大家以为然否?
前面几篇文章大概的讲了一些关于 margin
的特性,所以本篇会聊聊 margin
的实际应用场景,也算让自己休息一下,不用再讲知识点。
有个很典型的需求
相信接下来这个需求,你十有八九实现过,甚至实现过多次,来看 图一
:
我们看到这个图中,有个列表,每个列表项下面都有一条线,但最后一项没有。我们预期的代码是:
<div id="demo">
<h3>标题列表</h3>
<ul>
<li>» 有点累想歇一下好长一个标题</li>
<li>» 有点累想歇一下好长一个标题</li>
<li>» 有点累想歇一下好长一个标题</li>
<li>» 有点累想歇一下好长一个标题</li>
<li>» 有点累想歇一下好长一个标题</li>
</ul>
</div>
如果每项都有条底线,我们可以很简单的做到,如下:
#demo li{
border-bottom: 1px solid #ccc;
}
然而为了处理最后一项,事情就变得有点纠结了。我知道肯定有人要说,我们有 :first-child
, :nth-last-child(n)
, :nth-last-of-type(n)
之类的CSS3选择符,要处理这个,太easy了。恩,我也不得不承认,CSS3确认让事情变得简单多了。但我们可能需要面对一些国情,因为需要照顾一些弱小者,比如IE6-8,它们离CSS3的世界太远。
传说中的first/last解决方案
所以我们需要找别的方法,于是这样的代码,相信你见过无数遍了:
<div id="demo">
<h3>标题列表</h3>
<ul>
<li>» 有点累想歇一下好长一个标题</li>
<li>» 有点累想歇一下好长一个标题</li>
<li>» 有点累想歇一下好长一个标题</li>
<li>» 有点累想歇一下好长一个标题</li>
<li class="last">» 有点累想歇一下好长一个标题</li>
</ul>
</div>
我没乱说,你肯定见到类似的代码千百遍了?是的,它确实能够解决我们的问题,请看 DEMO1
传说中的first/last解决方案,代码如下:
#demo .last{
border-bottom: 0 none;
}
使用特殊的class来单独处理这项,但我不是很喜欢这样的code,原因大致有:
- 需单独定义一个差异化的class;
- 不利于数据循环输出,因为还得判断是否最后一项;
margin的神来之笔
基于以上的原因,肯定会有其它的解决方案出现,这时margin无疑是非常不错的选择,来看代码:
#demo{
overflow:hidden;
}
#demo ul{
margin-bottom: -1px;
}
CSS代码如上,HTML代码当时使用开篇时的那段,结果请看:DEMO2
margin解决方案
是不是很Cool,完全避免了上述的问题,并且代码量很小。至于为什么可以这样实现,前几篇文章里有说过,margin是互动的,能影响其上下文的布局。本例中,当 ul margin-bottom:-1px
,其本身的高并不会被改变,但其相邻的元素则会往上 1px
,这时相邻的元素即其包含块 #demo,所以给 #demo overflow:hidden
,就直接将那 1px 的边框给裁剪掉了。
再来个相似的需求
看看下述的 图二
,这应该也是一种非常常见的图片列表需求:
只关注图片之间的间隙,我们发现3张图片,却只有2个间隙。不论你是用 margin-left
或者说是margin-right
,都无法直接达成这个需求。
当然,可以像 DEMO1
那样给第一个或者最后一个添加一个特殊类 first/last 来解决。但这种方式刚被说不喜欢,所以想想用 margin
方式吧,思路应该说是和 DEMO2
毫无二致。来看代码:
CSS
#demo{
overflow:hidden;
}
#demo ul{
margin-right:-10px;
}
HTML
<div id="demo">
<h3>图片列表</h3>
<ul>
<li><img src="data:images/1.jpg" alt="" /></li>
<li><img src="data:images/2.jpg" alt="" /></li>
<li><img src="data:images/1.jpg" alt="" /></li>
</ul>
</div>
恩,就这么简单,很美妙。效果可移步 DEMO3
margin处理图片列表间隙解决方案
我知道不少人还会使用给图片列表容器加宽度的方式来进行处理,当然,它很OK,不过不够灵活,因为在不同场景下,宽度可能不一样,这样的code无法被提取为公用样式,复用性不强。
而 margin
的方式完全不care几乎任何场景,都可以使用,因为在大多数情况,我们这样一个图片模块都是自适应宽度的,因为它会处于某个layout下,宽度完全取决于layout,所以其实在真实场景下 #demo 的overflow
并不是必须的,也就是说 margin-right
的负值理论上可以预设成一个很大的值。
CSS
#demo ul{
margin-right:-100px; /* 这个可以设置得比li的间隙更大,所以理论上可以写一次而适用于真实场景的任何情况 */
}
看我们简单还原的真实场景使用方式:DEMO4
模拟真实场景:margin处理图片列表间隙解决方案。恩,就这样,灵活性和可扩展性爆棚,不是么?
缩进实例
依然先贴个图,以下是 图三
:
貌似是个好常见的需求场景,当然,要实现这样的效果,对于大家来说都不过是信手拈来,再容易不过。
HTML
<div>
<strong>简介:</strong>
<p>该写点什么好呢?好头痛,一个能把value念成“哇柳”的中老年人,猛然觉得没文化好可怕。</p>
</div>
你可能随手就会写下 float + margin/padding
,float + bfc
,absolute + margin/padding
,flex
等方案中的随意一个,恩,都很Cool,我也常这么干。
只是有的时候在一个小场景下,希望能比较轻量的出来这样的缩进,可能不想有浮动,绝对定位,清除浮动之类的,怎么破?
margin依然是你很好的选择
你想到了吗?是的,用margin。
HTML
<p><strong>简介:</strong>该写点什么好呢?好头痛,一个能把value念成“哇柳”的中老年人,猛然觉得没文化好可怕。</p>
CSS
p{
padding-left:45px;
}
strong{
margin-left:-45px;
}
看起来很简单,没有浮动,没有绝对定位,没有其它重布局,很清凉有木有?
甚至 HTML
也可以更简单,因为无需对后面那长段做任何处理,所以不需要再加包裹。来看看具体例子吧。DEMO5
margin缩进实例。我想这样的轻量方式,在一定时候还是有使用价值的,不是么?
视觉欺骗伪等高
等高布局在一段时间内好似挺火,方案也涌现过不少,如 图四
:
该图要求,不论是主栏还是侧栏,总是以最高的那列为基准高度。核心代码:
CSS
#doc{
overflow:hidden;
}
#main,#aside{
margin-bottom:-999px;
padding-bottom:999px;
}
HTML
<div id="doc">
<div id="main">主内容栏<br />占位内容</div>
<div id="aside">侧边栏</div>
</div>
先看看结果:DEMO6
margin伪等高布局
效果和我们的要求一致,达到了等高布局。需要提醒的是,这其实只是视觉欺骗,做到的了伪高等高。主栏和侧栏的实际高度其实并不相等,之所以可以达成这样的效果,其原因在于负 margin
值。我们前文中有提到过,margin
会影响其上下文布局,当我们将 margin-bottom
设置为负值时,其相邻的包含块元素,底部会自动上去其负值的高度,直到最高的那列底部边缘为止,然后裁剪。但该列本身的高度并不会发生变化,同时因为有 padding-bottom
向下扩展,颜色被填充满padding区域,于是达到视觉上的等高。
描述的貌似有点复杂,没文化好可怕。差不多就这样,不能接着往下写了,要不收不住。
作为 CSS 的重要属性 margin
有很多可被挖掘的潜力,需要更多的是想法。enjoy it.
可挖掘性
之前已经写过一篇关于 margin
应用场景的文章:margin系列之内秀篇,当然,它的应用场景会远大于文中所述,无法一一列举。
所以本篇权当是对此的补遗好了,各位客官如有比较Cool的想法都可以留言给我,我会视情况补丁进来。
1像素圆角
这有什么好聊的吗?border-radius
瞬间可将之秒杀。恩,有的时候你不得不承认CSS3真是一把大杀器。不过当年我们是怎么做的?(会暴露年龄么?)
先看看我们要做什么,图一
:
(图一)
如上图一,我们会这样写:
HTML
<div id="demo">
<a href="?"><span>1px圆角</span></a>
<a href="?"><span>确定</span></a>
<a href="?"><span>取消</span></a>
</div>
CSS
#demo a,#demo span{
display:inline-block;
vertical-align:top;
}
#demo span{
margin:1px -1px; /* 关键规则 */
}
一条CSS规则我们就可以实现1px圆角,你信吗?来看DEMO1
:margin实现1px圆角
看到DEMO1
的结果后,你会发现我们确实做到了1px圆角,很简单,有木有?在没有 border-radius
的年代,我们也很欢乐。
看到Code后,我想应该不用太解释为什么可以实现?
BTW,多像素圆角也可以参考这种方式来实现,如果你实在不想用图片的话。
已知宽高元素水平垂直居中
必须说,这是一个非常典型的 margin
应用,虽然如今看起来貌似使用场景不是太大,但还是好多人喜欢在面试时对人问起,我偶尔也会,但不多。
假设一个宽300px,高300px的盒子要在整个页面中水平垂直居中,我们可以这样做:
HTML
<div id="demo">这是一个水平垂直居中的容器</div>
CSS
#demo{
position:absolute;
top:50%;
left:50%;
width:300px;
height:300px;
margin-top:-150px;
margin-left:-150px;
}
恩,是的,借助绝对定位。我们先来看看 DEMO2
:margin实现已知宽高元素水平垂直居中
先通过 top/left
将 #demo
的绝对定位流起始位置设置为当前屏的中心点,此时 #demo
的左上角这个点其实已经是相对于页面水平垂直居中了,由于它的宽度和高度都是300px,所以从起始位置向右下各延伸300px后才是整个 #demo
的真正位置。此时整个 #demo
其实并不是水平垂直居中的,除非我们将 #demo
的中心点放在当前屏的中心点上。怎么做?
这时我们就需要使用 margin
了,在 margin系列之与相对偏移的异同 这篇文章里,我们就说过 margin
是以自身作为参照物进行位置偏移的。所以我们只需要将 #demo
相对自身向上偏移150px,向左偏移150px,就能够实现将自身的中心点放在当前屏的中心点上,也就实现了自身在当前屏的水平垂直居中。
为什么代码里是 -150px
?好吧,如果用 margin-top
来实现向上偏移,必须是负值,不是么?如果是正值的话,就是向下偏移了,其实也相当于是 margin-bottom
的正值, margin-left
亦然,我们在margin系列之与相对偏移的异同 文章最后同样说过这个。基础知识很重要,有木有?
tabstrip底边线重合
先上个需求,如 图二
:
(图二)
看到 图二
,我想大家可能知道可能知道要做什么了。
对,我们要做的就是 tab 项与底边线重合,这应该是我们常见的场景了,margin
仍然是最佳选择。先来看代码:
HTML
<div id="demo">
<a href="?">分类一</a>
<a href="?" class="on">分类二</a>
<a href="?">分类三</a>
<a href="?">分类四</a>
</div>
CSS
#demo{
border-bottom:1px solid #aaa;
}
#demo a{
display:inline-block;
margin-bottom:-1px;
border:1px solid #aaa;
}
#demo .on{
border-bottom-color:#fff;
}
要实现 tab
中各项与包含块的底边线重合,重点在于将包含块的底边线向上偏移1px,这样就与 tab
各项的底部重合在一起。
怎样可以做到让包含块底边线向上偏移1px?恩,margin
是那么的顺其自然。我们只需要将 tab
各项的margin-bottom
设置为 -1px 即可,其本身高度不变,但包含块底部会向上1px。
来看看具体实现的例子 DEMO3
:tabstrip底边线重合
双重边线
实际场景可能比这会稍复杂一些,我们看个大概即可,主要是拓宽一下思路,来看 图三
:
(图三)
从图三中,我们可以看到每行都会有一个双色的边线,这就是我们要做的,HTML代码大约是这样:
HTML
<div id="demo">
<ul>
<li>这是一个双重边线的示例</li>
<li>这是一个双重边线的示例</li>
<li>这是一个双重边线的示例</li>
<li>这是一个双重边线的示例</li>
</ul>
</div>
怎么做?恩,我们可以用常规的方式来解决,比如完全使用 border
:
CSS Case1
#demo li{
border-top:1px solid #fff;
border-bottom:1px solid #ccc;
}
结果出来后,我们会发现最顶部多出了一条线,同时最底部又少了一条线。当然,这都可以被解决,我们可以让 ul
来辅助完成,例如让其 负margin-top + border-bottom,不过如果 ul
或者其父元素有垂直方向padding
的话,处理起来可能会稍显蛋疼。
还有其他解?当然,会有的,来看:
CSS Case2
#demo ul{
overflow:hidden;
background:#fff;
}
#demo li{
margin-bottom:1px;
border-bottom:1px solid #ccc;
background:#eee;
}
是的,选择 margin
作为实现手段。以 ul
的底色配合 margin
模拟出线条的外观,这其实也挺讨人喜欢的,不是么?看具体实现 DEMO4
:双重边线
margin
模拟边线还可以做什么?比如做个表格神马的,看看 DEMO5
:margin模拟表格边线
margin负值-内秀篇的更多相关文章
- margin系列之内秀篇(二)
本系列摘自 飘零雾雨的博客 可挖掘性 之前已经写过一篇关于 margin 应用场景的文章:margin系列之内秀篇,当然,它的应用场景会远大于文中所述,无法一一列举. 所以本篇权当是对此的补遗好了, ...
- margin负值 – 一个秘密武器
CSS盒模型中,margin是我们老熟悉的一个属性了, 它的负值你用过吗? 你知道 margin负值的秘密武器吗?我们一起看看吧! 1.带竖线分隔的横向列表(例如:网站底部栏目) 传统的分隔符是使用 ...
- 左侧固定,右侧自适应的布局方式理解margin负值理论
一.浮动布局 1.先让固定宽度的div浮动!使其脱离文档流.2.margin-left的值等于固定div的宽度相等. .aside{ float: left; width: 200px; backgr ...
- 深入理解CSS中的margin负值
前面的话 margin属性在实际中非常常用,也是平时踩坑较多的地方.margin折叠部分相信不少人都因为这样那样的原因中过招.margin负值也是很常用的功能,很多特殊的布局方法都依赖于它.它看似简单 ...
- 几个常见的布局的多种实现方式及margin负值总结
第一部分:几个常见的布局实现方式 一.左右两边固定, center中间自适应未知 html代码中 center 部分首先要放在box的最前部分.然后是left,right 圣杯布局: <div ...
- margin负值的几种妙用
1:定位+margin负值实现元素水平垂直居中 div{ position: absolute; z-index: 1; left: 50%; margin-left: -50px; width: 1 ...
- 微吧里的各种margin负值
直在做各种项目接各种需求,但你的代码能力得到提高了吗?不停的项目经历虽然能够增加你的代码行数,但不一定能提升你的代码质量,所以除了构建阶段的代码细扣,项目之后的代码总结是至关重要的. 微吧中除了模块化 ...
- margin负值的使用
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 理解margin负值
效果 上和左方的margin负值使元素向上和左方向移动,如果该元素position不是absolute或fixed,这还会导致之后的元素也向上,左移 下和右方的margin负值会缩小下和右方的空间,使 ...
随机推荐
- Hibernate 系列教程5-双向多对一
主要讲解inverse和cascade的用法 cascade定义的是关系两端对象到对象的级联关系: 而inverse定义的是关系和对象的级联关系(管理外键的值). inverse 属性默认是false ...
- VS2010 自定义向导
最近在学OpenGL,不想使用OpenGL的GLUT工具,自己写了一个初始化OpenGL的类,并在win32中使用,每次都要新建一个win32项目,然后将OpenGL初始化类拷贝到项目,然后进行各种初 ...
- JavaScript(1)——变量、函数声明及作用域
这是我的第一篇博客文章,本人不才,文笔也不好,所以可能写的有点凌乱.有什么不对的地方还望见谅.不过每天进步一小步,总有一天会迈出那一大步.以下内容是我对变量.函数声明及函数表达式.作用域的理解. [变 ...
- Android与路由器连接服务
界面UI: package my.work.Library; import java.util.Timer; import java.util.TimerTask; import java.util. ...
- Python基础学习6---存储器
Python提供一个标准的模块,称为 pickle .使用它你可以在一个文件中储存任何Python对象,之后你又可以把它完整无缺地取出来.这被称为 持久地 储存对象.还有另一个模块称为 cPickle ...
- Node.js学习 - Install and Configure
平台:Windows 官网:https://nodejs.org/en/ 下载安装 CMD中运行 1 交互模式 2 命令模式 模块安装 - NPM npm install express #当前目录安 ...
- Dev之ChartControl控件(一)
ChartControl控件主要包括Chart Title,Legend,Annotations,Diagram,Series五部分:如图: 1. 用RangeControl控件控制ChartCon ...
- PAT (Advanced Level) 1104. Sum of Number Segments (20)
简单题. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #in ...
- HDU 1814 Peaceful Commission
2-SAT,输出字典序最小的解,白书模板. //TwoSAT输出字典序最小的解的模板 //注意:0,1是一组,1,2是一组..... #include<cstdio> #include&l ...
- VBS脚本随笔
1.定时运行程序与关闭程序的VBS处理方法: do set ws=createobject("wscript.shell") ws.run"你要运行的程序的路径(比如说d ...