好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

html5教程-CSS 相对/绝对(relative/absolute)定位系列(三)

小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。

&nbs p;

//zxx:直接接上回

一、absolute正业之元素隐藏

元素隐藏与显示是我们在页面制作与交互效果实现中非常常见的,如果您只是使用 display:none 与 display:block/inline 来实现 DOM 元素的显隐控制,那你就out了。就元素的显示与隐藏实现,使用 dis play 在有些时候算是比较糟糕的方法了。

控制元素显隐的方法很多,但是本文不是讲元素显隐控制的,所以,只讲与 absolute 相关的一些方法。

absolute 属性相关的隐藏方法,我 知道 的有三种,分别如下:

.hidden{     pos IT ion:absolute;     top:-9999em; }

.hidden{     position:absolute;     visibility:hidden; }

.hidden{     position:absolute;     clip: rect(1px 1px 1px 1px);  /* IE6, IE7 */      clip: rect(1px, 1px, 1px, 1px); }

使用 absolute 属性控制DOM元素的显隐有三个 关键点 : 页面可用性 , 回流与渲染 , 配合JavaScript的控制 。

① 可用性隐藏
所谓可用性隐藏,就是兼顾屏幕 阅读器 这类 互联网 阅读辅助设备的隐藏方式。Yahoo! 可用性实验室成员Ted Drake就不同隐藏方法下屏幕阅读器的可用性问题作为测试,结果发现下面两种隐藏方式屏幕阅读器是读不了的。

. complete lyhidden {     display:none; }

.visibilityhidden {     visibility:hidden; }

You don’t want to show those hidden panels to any user. Use display:none for the hidden panels.

Screen readers will also ignore sections with visibility:hidden .

所以,从可用性角度而言,像“选项卡内容”,“更多收起展开”这类 元素隐藏 与显示就不推荐使用 display:none , 或者 是 position:absolute + visibility:hidden 。

例如 优酷 网 电影 或视频的简介中“显示详情”的实现就是使用的 display:none ,如下截图:

而 大众点评 网的隐藏层多采用 position:absolute + visibility:hidden 的方法,如下截图:

上述隐藏内容其实都是有用的信息,对于像盲人这类需要借助屏幕阅读器的用户无法知道这些信息了。拿优酷的那个例子,盲人用户就无法知道影片完整的简介。

如果希望隐藏内容能够被辅助阅读设备识别,就不能使用 display:none 以及 visibility:hidden 隐藏元素。可以使用模拟隐藏的隐藏方法,又称可用性隐藏。就是下面两种隐藏方法。

.hidden{     position:absolute;     top:-9999em; }

.hidden{     position:absolute;     clip: rect(1px 1px 1px 1px);  /* IE6, IE7 */      clip: rect(1px, 1px, 1px, 1px); }

但是,如果你是希望完全隐藏的,那就可以使用 display:none 或 visibility:hidden 。

额外说明: 如果隐藏元素含有链接元素或是可获得 焦点 的控件元素,但是又是使用的可用性隐藏。这些隐藏的链接与控件也是可以响应键盘焦点Tab切换的,但是这会让键盘使用用户产生不解与疑惑的。所以,从某种意义说,某些情况下,要兼顾屏幕阅读器用户和键盘用户有时候是不可兼得的。

②回流与渲染
早先时候我曾 翻译 过两篇关于回流与重绘的 文章 ,“最小化浏览器中的回流(reflow)”以及“回流与重绘: CSS 性能让JavaScript变慢?”。

我自己是没测过。 不过 根据上面这两篇文章的说法,以及一位口碑前端前辈的说法,使用absolute隐藏于显示元素是会产生重绘而不会产生强烈的回流。而使用 display:none 不仅会重绘,还会产生回流,DOM影响范围越广,回流越强烈。所以,就JavaScript交互的呈现性能上来讲,使用 absolute 隐藏是要优于 display 相关隐藏的。

③配合JavaScript的控制
说到元素的显示与隐藏,免不了与JavaScript的交互。例如 display 相关的隐藏于显示,就是 display:block/inline/inline-block/ .. . 与 display:none 。
要让元素隐藏,很 简单 ,直接:

dom.style.display = "none";

但是,如果要显示隐藏的元素,咋办呢?因为不同的标签所处的 display 水平是不一样的,于是,我们很难有一个简单的 统一 的显示方法。例如,下面的代码可能使用于 div , p 标签,但是对于span等inline水平的元素,可能就会嗝屁了(原本单行显示结果换行)。

dom.style.display = "block";

况且,随着浏览器的 不断 进步,以后类似于 display:table-cell , display:list -i tem 会越来越多的使用。再想通过display实现通用的显隐方法难度又会增大些。

这就是使用display属性控制元素显隐的局限性。顺带一提的是 jQuery 的显隐方法 show()/hide()/toggle() 就是基于 display 的,其会存储元素先前的 display 属性值,于是元素再显示的时候就可以准确地显示出之前的 display 值了。

您可以狠狠地点击这里: jq uery与display的显隐测试

而使用绝对定位实现的一些元素隐藏方法的控制就相对简单很多的。例如: position:absolute + visibility:hidden 方法,当我们要让元素(原本非绝对定位元素)显示的时候,我们需要设置:

dom.style.position = " stat ic"; dom.style.visibility = "visible";

而类似的 position:absolute + top:-999em 方法,当我们要让元素(原本非绝对定位元素)显示的时候,我们只需要设置:

dom.style.position = "static";

而无需担心原本标签的是 inline 水平还是 block 水平。所以,就显隐的JavaScript控制上来讲, absolute 相关方法要比 display 略胜一筹。

结合上面三点讨论,我们可以看出,当前占据主流的 display:block/none 控制元素显示与隐藏的方法其实是诸多方面有弊端的方法,有拿着鸡毛当令箭的意味。实际上,这种活(元素显隐)交给absolute属性更合适, 控制元素显示与隐藏才是absolute属性的正业所在 。 //zxx: display属性控制元素显隐之所以会控制大 半 壁江山是因为其语义就是“显示(display)”,于是先入为主,再加上人的从众性。

如果您看到下面的文字,可能是由于在其他网站或是RSS中阅读本文,本文原地址:http://www.zhangxinxu .COM /word Press /?p=1528,本文作者:张鑫旭,来自张鑫旭-鑫空间-鑫 生活 ,访问原出处更多优秀技 术 文章。

二、absolute与等高布局

拿简单的两栏布局举例,左栏与右栏有不同的背景色,且中间隔边框线分隔,如何实现?因为随着内容的不同,有可能左侧栏高度较高,也有可能是右侧栏高度较高。所以,要实现无缝的填色,定高不行不通的,置高度不理显然也不行,此时解决方法就是让左右两栏等高。

我较早的时候写过一篇名为“纯CSS实现侧边栏/分栏高度自动相等”的小tip,其 实现原理 如下:

m arg in-bottom:-3000px; padding-bottom:3000px;

后来在“我所知道的 几种 display:table-cell的应用”一文中也提过使用 display:table-cell 实现等高布局。

这里再介绍些如何使用 absolute 实现等高布局。

正如 系列 前篇所述,应用了 position:absolute 的元素无 宽 度,无高度。正好,我们可以 利用 该特性来实现等高布局所需要的效果——如等高的背景色、边框效果等。

您可以狠狠地点击这里:绝对定位与等高布局demo

点击demo页面中的两个按钮就可以看到无论左侧栏高还是右侧栏高,两边 背景颜色 纯纯的,中间的垂直分隔线直直的,如下截图:

其中,实现等高效果的核心CSS代码如下:

.equal_h ei ght{width:100%; height:999em; position:absolute; left:0; top:0;}

同时,满足以下一些条件:

高度 999em 的绝对定位层位于侧栏容器内,侧栏 position 为 relative 该栏实际元素内容用一个与 absolute 绝对定位层为兄弟关系的标签层包裹, position 为 relative , z-index 值 1 或其他 左右栏的父标签需设置 overflow:hidden ,同时为了兼容IE6/7,需设置 position 为 relative

以上条件对应下图标注:

原理很简单:由于绝对定位元素无高度的特性无宽度的特性,我们可以伪造一个高度足够高的绝对定位层(设置背景色,边框等属性),同时设置父标签 溢出隐藏 ,那么其多出来的高度酒不会显示了,也就实现了看上去的等高布局效果了。具体 细节 可参见demo页面中的代码展示,相信很好理解的。

三、absolute属性与IE6/IE7之间的误会

absolute 属性确实存在不少兼容性的问题,首先 absolute 属性定位相关( left / top )的些bug(例如IE6的奇偶bug)这里不予以讨论。

所以,下面所展示的些“误会”都是没有定位属性的(即无 left / top / right / bottom )。

1. mar gin 定位元素绝对定位元素重叠的误会
以前经常碰到的,今天怎么都模拟不出来了,这个先空着,回头补上……

(*^__^*) 嘻嘻……

补充于2011-04-18
很简单,双栏自适应布局中,左侧元素 absolute 绝对定位,右侧的 margin 撑开 距离 定位。可参见“页面重构鑫三无准则 之无宽度准则”一文中 新浪微博 的实例页面中的使用(那里是padding撑开距离)。

为了再现IE6/IE7下的这个 margin 定位元素绝对定位元素重叠的误会,我特地做了个简单的demo页面,您可以狠狠地点击这里:IE6/7下margin与absolute元素重叠demo

可以看到在IE6/7下左侧应用了 absolute 属性的图片与 右边 的自适应的文字内容重叠了,如下图所示(截自IE7):

此问题出现的 原因 与下面浮动与绝对定位元素重叠有着某些类似的原因,因为问题的出现都与绝对定位元素所在的标签水平有关:上述demo中, absolute 属性所在的标签是 div 标签,属于 block 水平的元素。如下截图:

要是我们把这里的 block 水平的 div 元素修改成 inline 水平的 span 标签,则重叠的问题就没有了。如下截图:

您可以狠狠地点击这里:IE6/7下margin与absolute元素重叠问题修复demo

如果您手上的浏览器是即使是IE6/IE7,点击上面的demo页面也不会有重叠的bug了,而此问题的修复是非常简单的将 div 标签换成 span ,如下截图所示:

2. 浮动与绝对定位元素重叠的误会
很简单,前面一个标签是浮动元素,后面的是 block 水平的绝对定位元素,结果IE8+,以及现代浏览器文字与图片重叠;但是IE6/IE7浏览器确是并排显示的。如下截图示意:

您可以狠狠地点击这里:浮动元素绝对定位元素重叠demo

CSS代码如下:

.box{padding:1em; background-color: # f0f3f9; overflow:hidden; _zoom:1;} .l{float:left;} .abs{position:absolute;}

HTML 代码如下:

<div class="box">     < img  class="l" src="mm1. jpg " />     <div class="abs">呦喝,这不是无版权小姐吗?</div> </div>

为何现代浏览器以及IE8+浏览器下浮动的图片与绝对定位的文字会重叠,而IE6/7却是并列显示?这是由于IE6/IE7浏览器将inline水平 标签元素 和block水平的标签元素没有加以区分一视同仁渲染了。我在前面已经多次提到, 应用了绝对定位属性的元素具有包裹性,等同于没有高度与宽度的inline-block元素 。

上面 斜体 加粗 的这个结论实际上说得不够严谨,在IE6/IE7浏览器下,上面的话是没错的;在所有浏览器下,对于inline水平的元素,上面的话也是没错的;但是在现代浏览器下,对于block水平的元素,上面的结论就有商榷之处。实际上,按照正确的绝对定位渲染,像 div , p 这类block水平标签并未完全inline-block化。inline-block化的元素有三大特性:包裹性;高宽可定义;图文混排。然而, div , p 这类标签应用了 position:absolute 后,在非IE6/7浏览器下,只有包裹性和高宽可定义这两个特性,但并不支持图片混排,也就是与图片文字在一起的时候会换行。

下面是举例字,验证上面的结论。首先是这么句话:“对于inline水平的元素,上面的话也是没错的”。这句话的 意思 其实是,如果是inline水平的元素,上面的那个示例就不会有兼容性问题了,于是我们把应用了 abs 类名的 div 标签改成 span ,如下HT ML 代码:

<div class="box">     <img class="l" src="mm1.jpg" />     <span class="abs">呦喝,这不是无版权小姐吗?</span> </div>

结果如下图:

不仅IE8浏览器,Firefox/Ch rom e等先前重叠的现在都并排显示了。

您可以狠狠地点击这里:浮动与inline水平绝对定位元素不重叠demo

下面再来验证这个结论:“现代浏览器下block水平元素absolute化后不支持图片混排”。也是很简单的,我们可以把最上面重叠的那个例子的图片的浮动属性干掉,也就是如下的HTML代码:

<div class="box">     <img src="mm1.jpg" />     <div class="abs">呦喝,这不是无版权小姐吗?</div> </div>

结果如下图:

而在IE6/IE7浏览器下,依旧是并排显示滴,如下图:

OK,现在 应该 很好理解最上面为 何在 现代浏览器下图片文字重叠而IE6/IE7下并排显示了。

在“CSS float浮动的深入研究、详解及拓展”系列中多次阐述了浮动元素的“无高度”特性,所以,当图片应用了 float:left 属性后,图片所占据的高度丢失,于是,原本换行显示在下面的文字就提上去了,于是就形成了重叠,如下图标示:

四、下节看点

下篇讲 relative 属性,内容包括:
relative 的占位性;
relative 最小化影响原则;
relative 在一些bug中的修复功能;
等……

时间仓促,资质有限,文章难免有表述不准确或是理解有误的地方,欢迎指正,不甚感谢。

(本篇完)

觉得 可用,就经常来吧! 欢迎评论哦!  html5教程 ,巧夺天工,精雕玉琢。小宝典献丑了!

总结

以上是 为你收集整理的 html5教程-CSS 相对/绝对(relative/absolute)定位系列(三) 全部内容,希望文章能够帮你解决 html5教程-CSS 相对/绝对(relative/absolute)定位系列(三) 所遇到的问题。

如果觉得 网站内容还不错, 推荐好友。

查看更多关于html5教程-CSS 相对/绝对(relative/absolute)定位系列(三)的详细内容...

  阅读:58次