多次在项目中遇到html页面元素的非期待重叠错误,多数还是position定位情况下z-index的问题。其实每次解决类似问题思路大致都是一样的,说到底还是对z-index的理解比较模糊,可以解决问题却不大了解其原因,导致重复出错......于是决定把重叠问题弄清下,把z-index理顺下。

经过一番查找对比实践理解,下面就从元素重叠的背景常识及可能原因说起,浅谈下position定位元素的z-index顺序。总结下我目前的理解,希望也能对遇到过类似问题有同样疑惑的你有一点帮助或启发。

1.元素位置重叠的背景常识

(x)html文档中的元素默认处于普通流(normal flow)中,也就是说其顺序由元素在文档中的先后位置决定,此时一般不会产生重叠(但指定负边距可能产生重叠)。当我们用css为某个元素指定float浮动或者position定位后,元素的定位将会依情况发生如下改变:

1. 指定float值left/right

行内元素也会隐形变成块元素,元素会脱离文档的普通流,向左或右浮动,直到其外边缘碰到包含框或另一个浮动框。

2. 指定position值relative

可以相对于其在普通流中的位置偏移,原本所占的空间仍保留。

3. 指定position值absolute

行内元素也会隐形变成块元素,元素会脱离文档的普通流,相对于最近的已定位祖先元素偏移,如果元素没有已定位的祖先元素,那么它的位置相对于最初的包含块偏移。

4. 指定position值fixed

元素会脱离文档的普通流,相对于浏览器窗口偏移,固定在浏览器的某个位置。

以上四种情况下,文档中的元素都将可能被浮动/定位元素覆盖产生重叠。

2.元素位置重叠的可能原因

1. 负边距/float浮动

margin为负值时元素会依参考线向外偏移。margin-left/margin-top的参考线为左边的元素/上面的元素(如无兄弟元素则为父元素的左内侧/上内侧),margin-right和margin-bottom的参考线为元素本身的border右侧/border下侧。一般可以利用负边距来就行布局,但没有计算好的话就可能造成元素重叠。堆叠顺序由元素在文档中的先后位置决定,后出现的会在上面。

浮动元素会脱离文档的普通流,有可能覆盖或遮挡掉文档中的元素。

2. position的relative/absolute/fixed定位

当为元素设置position值为relative/absolute/fixed后,元素发生的偏移可能产生重叠,且z-index属性被激活。z-index值可以控制定位元素在垂直于显示屏方向(Z 轴)上的堆叠顺序(stack order),值大的元素发生重叠时会在值小的元素上面。

3. window窗口元素引发的重叠

浏览器解析页面时,先判断元素的类型:窗口元素优于非窗口元素显示(也就是窗口元素会覆盖在其它非窗口元素之上),同为非窗口类型才能在激活z-index属性控制堆叠顺序。

Flash元素属于window窗口元素

所以如果页面上flash元素和其他元素发生重叠,需要先将flash嵌入的wmode属性的window(窗口,默认的会造成上面所说的问题)改为非窗口模式:opaque(非窗口不透明)或者 transparent(非窗口透明)。

ie6下select属于window类型控件

同理,它也产生窗口元素的遮挡问题。解决方法使用iframe(原理:ie6下普通元素无法覆盖select,iframe可以覆盖select,普通元素可以覆盖iframe)/用div模拟实现select的效果。我一般会为被select遮挡的div在内部追加(appendChild)一个空的子iframe,设置position:absolute脱离文档流空间、width:100%;height:100%;覆盖整个父div、z-index:-1;确保值要小于父div的z-index值让父div覆盖显示在iframe上面,借助这个iframe来覆盖select。

3.浅说position定位及z-index使用

使用前提

z-index只能在position属性值为relative或absolute或fixed的元素上有效。

基本原理

z-index值可以控制定位元素在垂直于显示屏方向(Z 轴)上的堆叠顺序(stack order),值大的元素发生重叠时会在值小的元素上面。

使用的相对性

z-index值只决定同一父元素中的同级子元素的堆叠顺序。父元素的z-index值(如果有)为子元素定义了堆叠顺序(css版堆叠“拼爹”)。向上追溯找不到含有z-index值的父元素的情况下,则可以视为自由的z-index元素,它可以与父元素的同级兄弟定位元素或其他自由的定位元素来比较z-index的值,决定其堆叠顺序。同级元素的z-index值如果相同,则堆叠顺序由元素在文档中的先后位置决定,后出现的会在上面。

所以如果当你发现一个z-index值较大的元素被值较小的元素遮挡了,请先检查它们之间的dom结点关系,多半是因为其父结点含有激活并设置了z-index值的position定位元素。

也因为这个相对性,还会引发浏览器表现不一致出现兼容问题。原因是ie6、7下面position值为非static的元素在未设置z-index值的情况下都会被隐含添加z-index:0,而Firefox/Chrome等现代浏览器会遵循标准默认z-index:auto不会产生值。

还有一点需要注意,负值的z-index也依照大小比较的原理,但一般来说负值的z-index会被透明的body覆盖导致点击等事件响应出现问题,请谨慎使用。

百说不如一例,举个例子来简单说明下z-index

html:

<div class="pr" id="one">
#one相对定位
<div class="pa pa1">#one的子元素pa1,相对#one绝对定位,#one是它的父元素,与.pa2为同级兄弟元素</div>
<div class="pa pa2">#one的子元素pa2,相对#one绝对定位,#one是它的父元素,与.pa1为同级兄弟元素</div>
</div>
<div class="pa" id="two">#two绝对定位,与#one为同级元素</div>

默认

均未加z-index值

css:

.pr{position:relative;}
.pa{position:absolute;}
div{width:200px;height:200px;border:1px solid #ccc;color:#fff;font:bold 14px \5fae\8f6f\96c5\9ed1;}
#one{background:#39f;}
#one .pa1{background:#096;top:25px;left:20px;}
#one .pa2{background:#969;top:90px;left:40px;}
#two{background:#669;top:165px;left:70px;}

表现及解析

定位后依照元素在文档中的先后位置,后出现的会在上面。

相对性试验

为#one加上z-index:1;#one .pa1加上z-index:30;#one .pa2加上z-index:20;#two加上z-index:9;

css:

.pr{position:relative;}
.pa{position:absolute;}
div{width:200px;height:200px;border:1px solid #ccc;color:#fff;font:bold 14px \5fae\8f6f\96c5\9ed1;}
#one{background:#39f; z-index:;}
#one .pa1{background:#096;top:25px;left:20px; z-index:;}
#one .pa2{background:#969;top:90px;left:40px; z-index:;}
#two{background:#669;top:165px;left:70px; z-index:;}

表现及解析

因为父辈同级元素的z-index值#one<#two,所以#one决定了其子元素.pa1和.pa2的z-index值不论有多大都会被#two所覆盖;作为同级兄弟元素的.pa1和.pa2则比较其z-index值,较大的.pa1显示在上面。

ie6、7兼容性试验

为#one .pa1加上z-index:10;#two加上z-index:1;

css:

.pr{position:relative;}
.pa{position:absolute;}
div{width:200px;height:200px;border:1px solid #ccc;color:#fff;font:bold 14px \5fae\8f6f\96c5\9ed1;}
#one{background:#39f;}
#one .pa1{background:#096;top:25px;left:20px; z-index:;}
#one .pa2{background:#969;top:90px;left:40px;}
#two{background:#669;top:165px;left:70px;z-index:;}

表现及解析

Firefox/Chrome等现代浏览器(包括ie8+)下,父元素#one未设置z-index值,则默认为auto,此时的#one .pa1为自由的定位元素,因此z-index较大的#one .pa1显示在较小的#two上面。如果把#two的z-index值去掉,情况也会是一样的,设置了较大z-index值的#one .pa1会显示在未设置z-index的元素上面。

ie6/7下,差异在于#one .pa1显示在了#two的下面。因为对于ie6/7父元素#one未设置z-index值,会被隐含设置了z-index:0;此时z-index值#one的0要与#two的1比较,而#two比较大,所以#one的子元素无论z-index如何的大也会被#two遮挡。如果把#two的z-index值去掉,情况依旧,因为未设置z-index值的#one和#two都会被默认加上z-index:0;有了值就可以比较,值相同的情况下堆叠顺序由元素在文档中的先后位置决定,出现在后面的#two会在上面,结果#one的子元素无论z-index如何的大还是会被#two遮挡。

4.简单总结及建议(关键!)

普通元素的堆叠顺序由元素在文档中的先后位置决定,后出现的会在上面,请小心计算好浮动和负边距布局,注意窗口元素的特殊性;非同级关系和非父子关系定位元素之间的堆叠顺序,要向上追溯到其为兄弟关系的父元素上,先比较其z-index值,只有父辈元素中的z-index值较大的后代子元素才能超过z-index值较小的父辈元素及其子孙元素。

为了在编码时就减少z-index值判断的复杂性,我建议对于一般页面内容类定位元素的z-index设置小于99的值(如非必要不使用负值),广告类定位元素的z-index设置100~500的值,公告提示等弹出类定位元素的z-index设置大于500的值;对于比较复杂定位嵌套页面,为了避免ie6/7的显示差异,请为父辈类定位元素显性加上z-index:0或其他值。

以上是我目前网络搜寻书籍参考结合实践后的理解总结,如有错误,请不吝赐教;如有疑问,欢迎讨论;如有帮助,万分荣幸;如有雷同,握个手吧~

浅析z-index(覆盖顺序)和定位的更多相关文章

  1. css样式加载顺序及覆盖顺序深入理解

    注:内容转载 很多的新手朋友们对css样式加载顺序和覆盖顺序的理解有所偏差,下面用示例为大家详细的介绍下,感兴趣的朋友不要错过 { height: 100%; width: 200; position ...

  2. Z路径覆盖

    Z路径覆盖是路径覆盖的一个变体.路径覆盖是白盒测试最为典型的问题.着眼于路径分析的测试可称为路径测试.完成路径测试的理想情况是做到路径覆盖.对于比较简单的小程序实现路径覆盖是可能做到的.但是如果程序中 ...

  3. Android - FrameLayout覆盖顺序

    FrameLayout覆盖顺序 本文地址: http://blog.csdn.net/caroline_wendy FrameLayout: Child views are drawn in a st ...

  4. 排序并获取index的顺序

    //排序并获取index的顺序:4,7,2,9-->9,7,4,2-->4,2,1,3 Array.prototype.getIndex=function(){ var orderLeng ...

  5. 浅析CSS——元素重叠及position定位的z-index顺序

    多次在项目中遇到html页面元素的非期待重叠错误,多数还是position定位情况下z-index的问题.其实每次解决类似问题思路大致都是一样的,说到底还是对z-index的理解比较模糊,可以解决问题 ...

  6. (转)浅析CSS——元素重叠及position定位的z-index顺序

    多次在项目中遇到html页面元素的非期待重叠错误,多数还是position定位情况下z-index的问题.其实每次解决类似问题思路大致都是一样的,说到底还是对z-index的理解比较模糊,可以解决问题 ...

  7. 内联元素于与块元素的转换 相对定位、绝对定位以及fixed定位 Z轴覆盖

    今天上午学习了内联元素于与块元素的转换     个人觉的display:none将元素非常好用,可以配合当鼠标放到这里会出现. 转换成行内元素display: inline;  转换成块元素displ ...

  8. Elasticsearch——禁止Body中的index覆盖Url中的index参数

    本篇继续一下Elasticsearch日常使用的技巧翻译. 在Elasticsearch有很多的api支持在body中指定_index等信息,比如mget或者msearch以及bulk. 默认的情况下 ...

  9. CSS样式覆盖顺序

    有时候在写CSS的过程中,某些限制总是不起作用,这就涉及了CSS样式覆盖的问题,如下 Css代码   #navigator { height: 100%; width: 200; position:  ...

随机推荐

  1. dedecms搜索框写法

    <div class="bg_search"> <form id="forms" name="formsearch" ac ...

  2. 矩阵快速幂 HDU 4565 So Easy!(简单?才怪!)

    题目链接 题意: 思路: 直接拿别人的图,自己写太麻烦了~ 然后就可以用矩阵快速幂套模板求递推式啦~ 另外: 这题想不到或者不会矩阵快速幂,根本没法做,还是2013年长沙邀请赛水题,也是2008年Go ...

  3. kindeditor-4.1.3工具使用技巧:如何在编辑区上传图片并保存绝对路径

    MVC项目开中用到了KindEditor图片上传工具,需要在编辑区内上传图片,并将图片的URL保存为符合如下格式地址,如http://192.168.0.111/uploadImg/imgName.j ...

  4. PHP_SELF、 SCRIPT_NAME、 REQUEST_URI区别

    $_SERVER[PHP_SELF], $_SERVER[SCRIPT_NAME], $_SERVER['REQUEST_URI'] 在用法上是非常相似的,他们返回的都是与当前正在使用的页面地址有关的 ...

  5. CSS Tip

    硬件加速 CSS will-change 属性

  6. web.xml配置错误导致applicationContext.xml配置重复加载

    web.xml相关配置 <context-param><param-name>log4jRefreshInterval</param-name><param- ...

  7. JS /JQuery 获取变量为数字时 容易出错 可能不是数字类型

    Javascript内置函数,原型为parseInt ( String s , [ int radix ] ),用于解析一个字符串,并返回一个整数. var $prod_kucun=$(this).n ...

  8. [ios]新手笔记-。-UIPickerView 关于伪造循环效果和延时滚动效果

    查找了网上资料,循环效果绝大部分都是增加行数来制造循环的错觉,延时滚动就是利用NSTimer间隔出发滚动事件来制造滚动效果. 代码: #import <UIKit/UIKit.h>#imp ...

  9. javascript 执行上下文的理解

    首先,为什么某些函数以及变量在没有被声明以前就可以被使用,javascript引擎内部在执行代码以前到底做了些什么?这里,想信大家都会想到,变量声明提前这个概念: 但是,以下我要讲的是,声明提前的这个 ...

  10. go中安装Beego不成功笔记

    在go.Git等等之类的相关软件安装好了之后,便可以安装Beego. 1.开始的时候是由于网络限制,不能访问Github,这个还好说找VPNFQ... 2.之后的问题,在git Bash中输入go g ...