margin系列之内秀篇
本系列摘自 飘零雾雨的博客
最Cool的利器
一样东西在不同的场景,不同的人手里,所能做的事会有很大不同。我深切的以为 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; }
#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>
<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的间隙更大,所以理论上可以写一次而适用于真实场景的任何情况 */ }
#demo ul{ margin-right:-100px; /* 这个可以设置得比li的间隙更大,所以理论上可以写一次而适用于真实场景的任何情况 */ }
看我们简单还原的真实场景使用方式:DEMO4
模拟真实场景:margin处理图片列表间隙解决方案。恩,就这样,灵活性和可扩展性爆棚,不是么?
缩进实例
依然先贴个图,以下是 图三
:
貌似是个好常见的需求场景,当然,要实现这样的效果,对于大家来说都不过是信手拈来,再容易不过。
HTML
<div> <strong>简介:</strong> <p>该写点什么好呢?好头痛,一个能把value念成“哇柳”的中老年人,猛然觉得没文化好可怕。</p> </div>
<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>
<p><strong>简介:</strong>该写点什么好呢?好头痛,一个能把value念成“哇柳”的中老年人,猛然觉得没文化好可怕。</p>
CSS
p{ padding-left:45px; } strong{ margin-left:-45px; }
p{ padding-left:45px; } strong{ margin-left:-45px; }
看起来很简单,没有浮动,没有绝对定位,没有其它重布局,很清凉有木有?
甚至 HTML
也可以更简单,因为无需对后面那长段做任何处理,所以不需要再加包裹。来看看具体例子吧。DEMO5
margin缩进实例。我想这样的轻量方式,在一定时候还是有使用价值的,不是么?
视觉欺骗伪等高
等高布局在一段时间内好似挺火,方案也涌现过不少,如 图四
:
该图要求,不论是主栏还是侧栏,总是以最高的那列为基准高度。核心代码:
CSS
#doc{ overflow:hidden; } #main,#aside{ margin-bottom:-999px; padding-bottom:999px; }
#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>
<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系列之内秀篇(二)
本系列摘自 飘零雾雨的博客 可挖掘性 之前已经写过一篇关于 margin 应用场景的文章:margin系列之内秀篇,当然,它的应用场景会远大于文中所述,无法一一列举. 所以本篇权当是对此的补遗好了, ...
- margin负值-内秀篇
zccst整理 margin系列之布局篇 margin系列之bug巡演(三) margin系列之bug巡演(二) margin系列之内秀篇(二) margin系列之bug巡演 margin系列之内秀篇 ...
- openlayers5-webpack 入门开发系列一初探篇(附源码下载)
前言 openlayers5-webpack 入门开发系列环境知识点了解: node 安装包下载webpack 打包管理工具需要依赖 node 环境,所以 node 安装包必须安装,上面链接是官网下载 ...
- javascript面向对象系列第三篇——实现继承的3种形式
× 目录 [1]原型继承 [2]伪类继承 [3]组合继承 前面的话 学习如何创建对象是理解面向对象编程的第一步,第二步是理解继承.本文是javascript面向对象系列第三篇——实现继承的3种形式 [ ...
- 【Windows编程】系列第五篇:GDI图形绘制
上两篇我们学习了文本字符输出以及Unicode编写程序,知道如何用常见Win32输出文本字符串,这一篇我们来学习Windows编程中另一个非常重要的部分GDI图形绘图.Windows的GDI函数包含数 ...
- 【Windows编程】系列第三篇:文本字符输出
上一篇我们展示了如何使用Windows SDK创建基本控件,本篇来讨论如何输出文本字符. 在使用Win32编程时,我们常常要输出文本到窗口上,Windows所有的文本字符或者图形输出都是通过图形设备接 ...
- 深入理解javascript函数系列第三篇——属性和方法
× 目录 [1]属性 [2]方法 前面的话 函数是javascript中的特殊的对象,可以拥有属性和方法,就像普通的对象拥有属性和方法一样.甚至可以用Function()构造函数来创建新的函数对象.本 ...
- 深入理解javascript作用域系列第四篇——块作用域
× 目录 [1]let [2]const [3]try 前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用 ...
- 深入理解javascript作用域系列第三篇——声明提升(hoisting)
× 目录 [1]变量 [2]函数 [3]优先 前面的话 一般认为,javascript代码在执行时是由上到下一行一行执行的.但实际上这并不完全正确,主要是因为声明提升的存在.本文是深入理解javasc ...
随机推荐
- SQLite 入门教程(三)好多约束 Constraints(转)
转于: SQLite 入门教程(三)好多约束 Constraints 一.约束 Constraints 在上一篇随笔的结尾,我提到了约束, 但是在那里我把它翻译成了限定符,不太准确,这里先更正一下,应 ...
- 你真的知道C#的TryParse吗?
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:你真的知道C#的TryParse吗?.
- JBPM学习(六):详解流程图
概念: 流程图的组成: a. 活动 Activity / 节点 Node b. 流转 Transition / 连线(单向箭头) c. 事件 1.流转(Transition) a) 一般情况一个活动中 ...
- POJ 2553 The Bottom of a Graph TarJan算法题解
本题分两步: 1 使用Tarjan算法求全部最大子强连通图.而且标志出来 2 然后遍历这些节点看是否有出射的边,没有的顶点所在的子强连通图的全部点,都是解集. Tarjan算法就是模板算法了. 这里使 ...
- C socket demo
一.服务端-server.c #include <stdio.h> #include <sys/socket.h> #include <arpa/inet.h> # ...
- js返回上一页方法区别
history.back(-1):直接返回当前页的上一页,数据全部消息,是个新页面 history.go(-1):也是返回当前页的上一页,不过表单里的数据全部还在
- careercup-数学与概率
7.3 给定直角坐标系上的两条线,确定这两条线会不会相交. 解法: 此题有很多不确定的地方:两条线的格式是什么?两条线实为同一条怎么处理?这些含糊不清的地方最好跟面试官讨论一下. 下面将做出以下假设: ...
- 标准I/O之实现细节
在UNIX系统中,标准I/O库最终都要调用文件I/O(read.write等).每个标准I/O流都有一个与其相关联的文件描述符,可以对一个流调用fileno函数以获得其描述符. 注意,fileno不是 ...
- 安装tensorflow
官网:http://tensorflow.org/安装步骤:1.sudo apt-get install python-pip python-dev python-virtualenv 3 co ...
- javascript 中的new操作符的理解
new 操作符 在有上面的基础概念的介绍之后,在加上new操作符,我们就能完成传统面向对象的class + new的方式创建对象,在Javascript中,我们将这类方式成为Pseudoclassic ...