这篇文章发布于 2010年12月26日,星期日,21:09,归类于 CSS相关。 阅读 162451 次, 今日 3 次 37 条评论
by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=1330
//zxx:直接接上回
一、常见absolute布局的替代实现方案
absolute属性配合left/top/right/bottom属性具有极强的定位性。这种功能特性是如此的明显与强烈,可能会让页面重构人员很单纯的被这一特性“捕获”,而产生迷失。
一板一眼的描述可能难以理解,举个通俗点的例子吧:
一个脸蛋不错身材超好的姑娘穿上超PP的衣服后是如此的光艳动人,对于我们这类常年困居于深宅大院的光棍男来讲,这种美艳是如此的迷人,以至于我们的精力多集中在这沉鱼落雁的美貌上,而忽略了其他一些东西,例如知性,善良,贤惠等。很容易的,我们以后一想到此女子,第一反应就是“美貌”,至于其他,在如此美貌下已经不重要了。
此道理反映在web上就是,我们极易先入为主地认为absolute
的价值就是借助left
/top
属性来进行定位的。说句不严谨的话,目前估计超过90%的普通布局中的absolute
属性都是用在定位上了。恩,这个回头再说,这里还是看看一些常见的absolute
布局如何通过使用其他属性完成同样的布局效果。既然absolute
属性是拿来定位,我们只要使用其他属性定位就可以了。此时,自然而然想到了CSS中另外一个更加低调全能的定位属性margin
,下面的前两个例子都是使用margin
代替absolute
及相关属性。
京东商城首页标价定位
首先拿京东商城首页的一个标价样式举例,见下截图:
用小bug一看其code实现,果然是绝对定位+定位属性://zxx:小bug时我对firebug的昵称
要是我来实现,就不会使用absolute
属性,会使用margin
实现扩展性容错性更强的布局。
不管怎样,先看对比实现效果,您可以狠狠地点击这里:absolute/margin定位布局对比demo
下图为在IE7浏览器下的上下实现方式对比截图(默认):
可见使用margin
,可以实现与absolute
布局一样的效果,且CSS属性使用量折半,更为关键的是,布局的扩展性与容错性大大增强了。
在demo页面上的底部有两个测试布局扩展性与容错性的按钮,如下图,第一个按钮是改变标签的宽度,第二个按钮是改变父标签的position
属性值为static
:
我们点击第一个按钮改变dl
父标签的宽度后,结果absolute
定位的标价已经和图片远离了,而使用margin
定位的橙红色背景标价依旧坚挺地呆在原来的位置上,如下图所示:
点击第二个按钮改变父标签的position
属性为static
后,结果使用absolute
绝对定位的标价没有了束缚,直接跑到浏览器窗口的右下角去了,而margin
定位没有丝毫影响(如下图所示,截自Firefox3.6):
从上面两个简单的测试可以看出两种实现方式见扩展性和容错性方面的差异。
下面简单讲下相关布局的实现,以下是原来absolute
实现的HTML部分代码:
<dl> <dt class="p-img"> <a href="##"><img width="130" height="130" src="http://img10.360buyimg.com/n3/834/11752677-6197-4ffa-b4c0-e66d02640bad.jpg" /></a> <div class="p-price">¥999.00</div> </dt> <dd class="p-name"> <a href="##">LG GD580 3G手机 300万像素 999返100元券!</a> </dd> </dl>
类名为”p-price”标签核心样式如下:
.p-price { position: absolute; bottom: 10px; right: 50px; ......
京东商城的实现,中规中矩,想这种带有覆盖效果的定位,使用absolute
定位估计是大部分页面重构人员的首选。但是,绝对定位之“绝对”一词本身就意味着其在扩展性方面的表现受限。如果我们要求更高,可以使用CSS代码量更少,扩展性更强的margin
布局。
其实现代码如下:
首先HTML部分需要添加一层block
水平的标签(其实可以不用加,只要让img
外面的a
标签block
水平显示即可),让标价与图片不会在一个line box中显示,同时将标价外面的div
标签改为inline水平元素的标签方便inline-block
化,于是,最后的HTML代码如下:
<dl> <dt class="p-img"> <a href="##"><img width="130" height="130" src="http://img10.360buyimg.com/n3/834/11752677-6197-4ffa-b4c0-e66d02640bad.jpg" /></a> <div class="new-price-x"><span class="new-price">¥999.00</span></div> </dt> <dd class="p-name"> <a href="##">LG GD580 3G手机 300万像素 999返100元券!</a> </dd> </dl>
相关的核心的CSS代码如下:
.new-price-x { margin: -28px 0 0 74px; } .new-price { display: inline-block; ...... }
淘宝首页示例
下面再看另外一个例子,就是淘宝首页的滚动播放效果,使用是absolute
定位,通过改变top
属性值实现上下的滚动切换,如下图:
实际上,完全可以使用margin-top
属性代替这里的relative
+absolute
+top
属性组合。
您可以狠狠地点击这里:淘宝首页margin下的滚动播放demo
使用小bug一看demo页面的定位属性,啊,是margin-top
,如下截图所示:
就效果来说,margin-top
与绝对定位的切换是一样的,优点在于省了一点点的CSS代码量。但是,相对absolute
的动画切换,margin-top
值的改变会产生更强的回流(reflow
),就性能上而言,要比absolute
属性低。
究竟使用哪个,看您自己如何取舍了。
新浪微博示例
最后,拿新浪微博页面的主导航示例。
首先来看看为什么新浪微博的主导航要使用绝对定位。我想主要原因可能是半透明的纯色背景吧。
而IE浏览器下药实现opacity
效果需要使用filter
滤镜,然而opacity
属性的半透明效果不仅会影响到当前元素,所有的子元素也会跟着半透明,此时,如果导航内元素放在半透明化的div
内部显然容易死翘翘。所以,半透明背景层,与导航内容层不是父子关系,而是兄弟关系,导航内容覆盖于半透明背景上,就避免了导航内容被半透明化的危险。
而覆盖定位一般都离不开absolute
属性,所以,新浪微博的主导航使用了绝对定位。然而,这里的绝对定位使用我必须称赞一下,因为很难得的,这里的absolute
使用主要是利用了absolute
属性的破坏性(高宽占据空间为0
的特性),而不是利用其定位性(借助left
/top
等属性的定位)。
至于这里如何利用absolute
属性的破坏性实现自适应的布局,不想讲。有微博的自己用小bug看看,没微博的注册个。
就这里绝对定位的使用来讲,除了莫名的top
/right
属性外,还是不错的。然而,问题在于这里非要使用绝对定位吗?兼容性的半透明纯色效果非要用并行的两个标签错开重叠定位吗?父子关系不行吗?有句成语叫做“与时俱进”,要是几年前,可能还真得这么搞。但是现在,什么绝对定位啊,重叠啊,计算啊什么乱七八糟的东西完全不需要。就当没有什么半透明效果写,同样可以实现一样的效果。
同样的,关于这里的替代方法,我做了个demo,您可以狠狠地点击这里:新浪微博主导航无absolute实现demo
使用opacity
属性或是IE filter
半透明滤镜会让子元素跟着半透明。实际上对于半透明的纯色背景,有更佳的实现方法。下面是demo页面的替换实现方法的CSS代码:
.newheader .menu_c { background-color: rgba(0, 0, 0, .25); filter: progid:DXImageTransform.Microsoft.Gradient(startColorStr=#40000000,endColorStr=#40000000); }
现代浏览器使用CSS3 rgba
实现半透明背景色,IE浏览器使用渐变滤镜实现半透明。
HTML方面,原来的绝对定位的半透明div层直接删掉,此时相关的relative
属性等也可以一并去掉。HTML结构变得简单有层次,维护也更加方便了。
关于实现兼容性的半透明背景色,您可以参考我之前的“RGBA颜色与兼容性的半透明背景色”一文。所以具体使用,细节等这里就不多说,下图为前后两种半透明背景实现方式效果对比图:
二、absolute可以一个人战斗
如果在CSS的世界中没有left
/top
/right
/bottom
属性,absolute
的潜力估计会挖得深得多。
我们需要意识到,一个应用的position:absolut
e的元素,其实就只是个非常普通的元素,我感觉与应用了float:left
的差异仅仅在于宽度的缺失。为说明此观点,我做了个很简单的demo.
您可以狠狠地点击这里:absolute元素只是个普通的货demo
此demo默认如下图,可以看到浮动的高度缺失造成的塌陷:
点击示意的按钮后,可以发现图片还是那个图片,还在那个位置,还是那么的安静与优雅。唯一变化的就是文字们有的跑到它的下面了(宽度缺失)。
由此可见,absolute
属性只是个很普通的属性,跟float:left
是个近亲。一个是陨落凡间的恶魔,一个是天空中的恶魔。所以,很多时候,我们在普通布局中使用absolute
时候,只要设置position:absolute
就可以了,至于left
/top
之类的都是浮云,定位什么的就当作普通元素,使用margin
定位一样有着刮目的表现的。
三、absolute与left/top等属性之间的关系
单纯应用了absolute
属性的元素就是个普通元素,跟变身前的美少女战士一样。left
/top
等属性是具有变身性质的东西,是恶魔absolute
元素的翅膀。absolute
元素一旦应用了left
/top
等属性,就具有了飞翔的能力,奔向天空自由驰骋,如果没有relative
属性的限制,其会一直飞到天空的边缘(浏览器窗口),并且具有非常明确的方向性。
四、body标签是absolute元素自由的天空
来首小诗调节一下吧:
生命成可贵,
爱情价更高。
若为自由故,
两者皆可抛。
知道《美少女战士》吧,知道主人公水冰月(月野兔)吧,因为人家牛叉,所以为了保护地球,保护未来而战斗。知道《火影忍者》吧,你说要是把鸣人就限制在火影村,帮助老太太抓抓猫,帮助欧巴桑照看孩子,能有大成吗?人家是注定要肩负起忍者世界和平的职责的。
同样的,要是把绝对定位属性用在很深的DOM tree中,再用relative
限制住。其实就是把鸣人当作看孩子的人使用,虽然用的时候觉得很好用,但是实际上是埋没了绝对定位元素的才能。没有限制,给予足够的自由,广阔的天空才是绝对定位元素大放异彩,拯救人类的舞台。
一般而言,在web页面上,最宽广的天空莫过于body
标签,所以,在我看来,把绝对定位元素直接放在body标签下才是王道,才能最大限度的发挥绝对定位元素的才能。举个例子,淘宝首页顶部小横条上的下拉。
此下拉就是使用的绝对定位,但是却是深深地嵌入到DOM中的,如下图:
这种方法的好处在于简单,对于非IE6浏览器直接使用CSS就可以实现效果了。然而,将默认隐藏的绝对定位元素被relative
限制在很深的DOM节点中,弊处相当多:首先增加了DOM的复杂度,不利于维护;越深的DOM元素,造成了回流越强;因为父标签需要relative
限制,增加了CSS代码的消耗量;隐藏元素头部加载,延迟了页面的呈现速度;每个下拉几乎都要重新定位,其重用性受限。
如果是我,一定会把这些隐藏的绝对定位元素放在在body
标签内部,且最底部加载,以提高页面的呈现速度,甚至根本就不加载。此做法就是mtime时光网下拉导航的做法,是推荐的做法。绝对元素的定位不是通过当前触发元素的relative
限制,而是在body
大环境中,直接通过触发元素的偏移值设定位置,是最直接最高效的做法。
在body
标签下自由驰骋,这才是绝对定位元素真正应该呆的地方。真正有才华的元素应该放在更大的舞台上,限制在蹩脚的角落里注定要埋没的。我之前写过一个名为”powerFloat“的万能浮动插件,就是希望通过降低使用的学习成本,让大家都把绝对定位元素解放到body标签下。
于是乎,我们不用担心什么层级错乱的破问题,不会再看到密密麻麻错乱的HTML代码。做页面重构的,本来就应该是每天喝喝咖啡,跟美女前台打情骂俏的工作,现在却搞那么辛苦,太不应该了。
absolute
元素犹如有翅膀的小鸟,你是把它限制在鸟笼中,还是把它放飞到天空中自由的飞翔?我想,一切不言而喻。
下集看点:
下篇还是关于absolute
属性的(relative
属性以及z-index
还在其后),内容大致有,
absolute
与reflow
回流及应用;
IE6/7下行高与absolute
元素间的误会;
IE6/7下haslayout与absolute
元素间的误会;
等……
本文为原创文章,转载请注明来自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]
本文地址:http://www.zhangxinxu.com/wordpress/?p=1330
(本篇完)
- CSS 相对/绝对(relative/absolute)定位系列(四) (0.519)
- absolute绝对定位的非绝对定位用法 (0.430)
- CSS 相对|绝对(relative/absolute)定位系列(一) (0.375)
- CSS相对定位|绝对定位(五)之z-index篇 (0.375)
- 对html与body的一些研究与理解 (0.289)
- 小tips: 点击页面出现富强、民主这类文字动画效果 (0.289)
- 更好的纯CSS滚动指示器技术实现 (0.289)
- CSS 相对/绝对(relative/absolute)定位系列(三) (0.272)
- MooTools下简易自定义滚动条小插件 (0.247)
- jQuery powerFloat万能浮动层下拉层插件 (0.231)
- 小tip: 微博新版查看大图前后浏览的另外一种实现 (RANDOM - 0.055)
一边看着文章里强调轮播图使用margin属性,一边看着右侧广告用绝对定位实现的轮播图,还是挺喜感的。
7年前的博客。。
absolute的不依赖relative方法并不适用于移动端啊
如果是我,一定会把这些隐藏的绝对定位元素放在在body标签内部,且最底部加载,以提高页面的呈现速度,甚至根本就不加载。此做法就是mtime时光网下拉导航的做法,是推荐的做法。绝对元素的定位不是通过当前触发元素的relative限制,而是在body大环境中,直接通过触发元素的偏移值设定位置,是最直接最高效的做法。
引用博主的这段话,希望博主能够给大家展示一个例子好吗?多谢啦~很喜欢看您的博文~学习不少东西
现在想法变了没
定位在body里,那不是lef,top根据网页左上角来确定的了,不是更麻烦了,如果我只想把绝对定位元素放到某个元素的旁边
jd那个例子 我觉得不是 position的问题,关键是 .p-price的parent p-img没有设 width, 只要把p-img设定一个width就没问题了
楼主分享的不错。不过CSS3 rgba实现半透明背景色,在IE6中颜色出不来,我用的是ietester测试,是这个原因吗?
soga 你真行!
呃~错了~是margin-top,margin-bottom负值是不是无效
楼主您好,京东的那个demo,价钱的那里,我线下直接用¥999这样写,结果不能实现,margin-top:-30px只能向上去一点点,并不是预期到效果,我想请教楼主的是:块级元素display:inline-block之后,margin-top,margin-bottom是不是就没什么效果了?自己写了demo,但是还是不怎么确定
价格改动这个确实改得漂亮,但淘宝下拉那个例子,如果把定位的元素都放到body里面,个人觉得有点不妥。特别是样式的不可用的时候,结构是否还会完整。如果真想减少下载时间,也可以考虑用js去喷。
如果把地球比作body,北极熊比作一个absolute,那么北极熊怎么也不可能跑到南极去玩,它还是在北级那块区域内。对于它来说,北极那块儿地方就是它的天空。
个人看法
真是的,花这么多时间写这些东西有用吗?!
不得不说,你真是有很多时间可以用来闲扯啊!!!
我觉得还挺有用的,时隔九年,那您觉得呢?
position:absolute而不设置left和top时,left和top还是存在的,只是值会变成auto而已,
而auto的意思就还是元素相对于实际的relative元素的坐标而已,所以看起来位置没有变化
而只是脱离了流,其他的非定位元素会在一个流中布局而已。
你没有真正理解吧????
很好的思维方式。但是记得在XHTML的嵌套规则里面,DT里面只能嵌套inline。
我认同13楼的观点,对于float和absolute我觉得文章里面说“我感觉与应用了float:left的差异仅仅在于宽度的缺失”,可是事实上的缺失还是很高的,absolute直接把DOM从文档流里面抽出了,而float还是嵌入文档流的。不仅仅是宽度、高度也是缺失的。博主试试IE9再截图下那个例子就明显额。
博主很牛 啊 谢谢
博主分析的很到位啊
还有,楼主不觉的应该对页面进行些优化么,网站打开速度很慢啊…
每个人有每个人的写作习惯,我认为代码应该根据实际情况随机应变,不必要强调各种规则,甚至于可以写些不规范的代码,这并无什么不可
我还是喜欢margin,而且我写的那些代码中基本上都是margin
牛人牛人 来学习 呵呵~~
关于淘宝网首页顶部导航,放在那里也许是有他的原因的,比如
1.是为了禁用了CSS的浏览器或者对CSS支持不够统一的手机浏览器,如果直接绝对定位在body开始或者结束就会使上下文关联性变弱甚至混乱,从“玉伯”对淘宝商城首页栏目的col-main,col-sub,col-extra布局就可见一斑,侧重点不同就会导致设计时的差异
2.规范性和可重用性,首先,不得不承认powerFloat的强大与好用,但是如果淘宝网菜单子项的布局使用了absolute,那么就势必要有javascript的配合,不管是整合在kissy中还是放在页面中,这都无形的增加了一条羁绊。
但是我还是很支持你的,因为在现在的情况下,能够让自己节省时间的方法才是最好的方法。
我觉得这个可以学学。。
木木推荐过来看看
其它不说,博主您网站首页的那个“进入我的博客”按钮,在ie8下严重不协调。。。长久以来都没修正。
@135956 这个问题到现在还真没有人跟我提过,现已修复,多谢提醒。
margin容错性高吗?不见得哦
我觉得用position要比margin来的快,因为很多时候margin并不兼容
关于淘宝那个,现行的浏览器并不会太受这个的影响。而且在大型项目中,分工是很明细的,
页面颗粒+模块混着一起,今天你在body中加一段,明天我再加一段,样式表又是大家分开管。时间长了对项目的风险远大于这个小小的改动带来的改进
关于那个什么京东商城,用margin方法也是有问题。当图片未加载到时,你的方法设置的价格标签已经跑出窗外了。
赞了!站长非常的用心研究这些问题!
这,这。。。不是张含韵就是美少女。。。。
你好。从上往下数第四章图上的一句话“的relative属性为static:”和从上往下数第五张图上面的那句“点击第二个按钮改变父标签的position属性为static后”。我想大概后者是正确的吧。
多谢分享!
@Zz 多谢提醒。
太精彩了,正在学习!
笔者的文章分析很到位,也为我扫清了许多盲区。期待着笔者对 z-index 和相对定位, 绝对定位的纠缠更深入的分析。