有关CSS 定位中的盒装模型、position、z-index的学习心得
开始整体之前我需要说明两个概念:
第一个就是 一切皆为框 也就是说在HTML中的不管是是块级的还是内联的,都可以认为成块的,唯一的区别就是块的会独自占据一行
第二个文档流: 一个网页可以看作是三维立体的一个图形,拥有自己各自的x,y,z轴的坐标。 在左上角是左边原点,横向的是x轴,纵向的是y轴, 垂直界面的是z轴。
第一部分:有关盒装模型定位的理解
先来看一下这个图形,有一个初步的印象
上面的图形形象的表示了margin(外边据) padding(内边距) 各自的概念:
需要掌握的技巧:1)为了用一个margin就可以表示四边的边距:
例子 1
margin:10px 5px 15px 20px;
- 上外边距是 10px
- 右外边距是 5px
- 下外边距是 15px
- 左外边距是 20px
例子 2
margin:10px 5px 15px;
- 上外边距是 10px
- 右外边距和左外边距是 5px
- 下外边距是 15px
例子 3
margin:10px 5px;
- 上外边距和下外边距是 10px
- 右外边距和左外边距是 5px
例子 4
margin:10px;
- 所有 4 个外边距都是 10px
padding也有上面的这几个属性。这样的话就不用各自进行单独的设置了。
2) 需要提的一点就是margin属性的垂直合并的特点。详细在W3C上面有解释。
第二部分:有关position 4个属性值的理解。(就是没良心的富二代)
position有四个属性:absolute fixed relative static 。
absolute: 对定义的那个框框 第一点是脱离了原来的文本流,在z=0这个位置没有立足的地方。换句话说他就成了邪剑仙 六道之外的东西了。他会根据前面距离他最近的并且不会有static定位的那个父框架作为基础进行移位。属性值有 left right top bottom
relative:这个会在原来的z=0的文本流中保留自己的位置。之后所有的移位是根据这个原来的位置为基础进行移位的。属性值有left right top bottom
static:什么也没有改变,还是乖乖的呆在 z=0的文本流根据HTML排版那样,该怎么排位就怎么排位,唯一的区别就是只要有了这个属性的框就变成了vip ,拥有一些其他的特权。这个我会在下面写到。
fixed:这个位置是相对与浏览器的框架来说的,不会在z=0的文本流占有位置。举个例子:Q空间里面右下角的那个点一下就会干到顶部的按钮。就是fixed属性的。
第三部分:z-index的理解
大家应该都已经了解了网页的表现形式应该是一个三维空间。 这样的话就会拥有自己的x ,y, z 坐标了呗。
这里面的就是这个意思。
有关一些z的东西。 越往里面 那么它对应的文档流的indezx就越小(一般不写的就是z=0那个文档流里面的的)z-index这个可以为负数的。 越大的越在最外面了。
对于 这个的理解 这是富二代玩的东西。具体的在下面会有解释
第四部分:有关层级树还有z-index 、position 的理解总结!!!(重要!!!)
顺序规则
如果不对节点设定 position 属性, 位于文档流后面的节点会遮盖前面的节点.
<div id="a">A</div> |

定位规则
如果将 position 设为 static, 位于文档流后面的节点依然会遮盖前面的节点浮动, 所以 position:static 不会影响节点的遮盖关系.
<div id="a" style="position:static;">A</div> |

如果将 position 设为 relative (相对定位), absolute (绝对定位) 或者 fixed (固定定位), 这样的节点会覆盖没有设置 position 属性或者属性值为 static 的节点, 说明前者比后者的默认层级高.
<div id="a" style="position:relative;">A</div> |

在没有 z-index 属性干扰的情况下, 根据这顺序规则和定位规则, 我们可以做出更加复杂的结构. 这里我们对 A 和 B 都不设定 position, 但对 A 的子节点 A-1 设定position:relative. 根据顺序规则, B 会覆盖 A, 又根据定位规则 A' 会覆盖 B.
<div id="a"> |

上面互相覆盖在什么时候用到这样的实现? 看起来偏门, 其实很常用, 比如说, 电子商务网站侧栏的类目展示列表就可以用这个技巧来实现.
下图是某网站的类目展示区域, 二级类目的悬浮层覆盖一级类目列表外框, 而一级类目的节点覆盖二级类目的悬浮层. 如果使用 CSS 实现展示效果, 一级类目的外框相当于上面例子中的 A, 一级类目的节点相当于 A-1, 二级类目的悬浮层相当于 B.

参与规则
我们尝试不用 position 属性, 但为节点加上 z-index 属性. 发现 z-index 对节点没起作用.
<div id="a" style="z-index:2;">A</div> |

W3C 对 z-index 属性的描述中提到 在 z-index 属性仅在节点的 position 属性为 relative, absolute 或者 fixed 时生效.
The z-index property specifies the stack order of an element. Only works on positioned elements(position: absolute;, position: relative; or position: fixed;).
<div id="a" style="z-index:2;">A</div> |

默认值规则
如果所有节点都定义了 position:relative. z-index 为 0 的节点与没有定义 z-index 在同一层级内没有高低之分; 但 z-index 大于等于 1 的节点会遮盖没有定义 z-index 的节点; z-index 的值为负数的节点将被没有定义 z-index 的节点覆盖.
<div id="a" style="position:relative;z-index:1;">A</div> |

通过检查我们还发现, 当 position 设为 relative, absolute 或者 fixed, 而没有设置 z-index 时, IE8 以上和 W3C 浏览器 (下文我们统称为 W3C 浏览器) 的 z-index 默认值是 auto, 但 IE6 和 IE7 是 0.
从父规则
如果 A, B 节点都定义了 position:relative, A 节点的 z-index 比 B 节点大, 那么 A 的子节点必定覆盖在 B 的子节点前面.
<div id="a" style="position:relative;z-index:1;"> |

如果所有节点都定义了 position:relative, A 节点的 z-index 和 B 节点一样大, 但因为顺序规则, B 节点覆盖在 A 节点前面. 就算 A 的子节点 z-index 值比 B 的子节点大, B 的子节点还是会覆盖在 A 的子节点前面.
<div id="a" style="position:relative;z-index:0;"> |

很多人将 z-index 设得很大, 9999 什么的都出来了, 如果不考虑父节点的影响, 设得再大也没用, 那是无法逾越的层级.
层级树规则
可能你会觉得在 DOM 结构中的兄弟节点会拎出来进行比较并确定层级, 其实不然.
<div id="a" style="position:relative;z-index:2;"> |

我们认为同时将 position 设为 relative, absolute 或者 fixed, 并且 z-index 经过整数赋值的节点, 会被放置到一个与 DOM 不一样的层级树里面, 并且在层级树中通过对比 z-index 决定显示的层级. 上面的例子如果用层级树来表示的话, 应该如下图所示.

图中虽然 A-1 (z-index:0) 的值比 B-1 (z-index:1) 小, 但因为在层级树里 A (z-index:2) 和 B-1 在一个层级, 而 A 的值比 B-1 大, 根据从父规则, A-1 显示在 B-1 前面.
参与规则 2
前面提到的参与规则认为只要节点的 position 属性为 relative, absolute 或者 fixed, 即可参与层级比较, 其实不准确. 如果所有节点都定义了 position:relative, 并且将 z-index 设为整数值, 根据从父规则, 父节点的层级决定了子节点所在层级.
<div id="a" style="position:relative;z-index:0;"> |
例子中 A, B-1, C-1-1 作为父节点, z-index 的值相同, 根据顺序规则, C-1-1 在 B-1 之前, B-1 在 A 之前; 又根据从父规则, 无论子节点的 z-index 值是什么, C-1-1-1 在 B-1-1 之前, B-1-1 在 A-1 之前.

如果我们将所有父节点的 z-index 属性去除, 诡异的事情发生了. IE6 和 IE7 浏览器显示效果不变, 而 W3C 浏览器的子节点不再从父, 而是根据自身的 z-index 确定层级.
<div id="a" style="position:relative;"> |
根据默认值规则, IE6 / IE7 和 W3C 浏览器上的元素存在 z-index 默认值的区别. 我们相信, 仅当 position 设为 relative, absolute 或者 fixed, 并且 z-index 赋整数值时, 节点被放置到层级树; 而 z-index 为默认值时, 只在 document 兄弟节点间比较层级. 在 W3C 浏览器中, A, B-1 和 C-1-1 的 z-index 均为 auto, 不参与层级比较.

而在 IE6 和 IE7 中, 因为 z-index 的默认值是 0, 所以也参与了层级比较.

设置了 position 而没有 z-index 的节点虽然不参与层级树的比较, 但还会在 DOM 中与兄弟节点进行层级比较.
<div id="a" style="position:relative;"> |
我们对上个例子改造一下, 将 B-1 的 position 属性删除后, W3C 浏览器显示如下图. 根据定位规则, A 和 C-1-1 会显示在 B-1 的前面; 而根据顺序规则, C-1-1 又显示在 A 前面.

在 IE6 和 IE7 中, 因为 A 和 C-1-1 设置了 position:relative, 而且 z-index 的默认值为 0, 所以也参与层级树比较, 所以有如下效果.

总结
浏览器节点显示层级是一个费力的活, 今天你觉得 A 区块会永远置顶, 但明天因为需求变动, 突然出现 B 元素需要置顶. 一层一层往上堆砌, 某天回头一看, 发现很多区块交错在一起, 而且他们的值一个比一个大, 根本搞不清头绪. 我觉得在操刀干活之前, 最好先将 position, z-index 和层级的关系搞搞清楚, 以免后患无穷.
另外, 非情非得已, 切勿用 JavaScript 计算 z-index, 并将某个节点的 z-index 设置成所有节点中层级最高.
有关CSS 定位中的盒装模型、position、z-index的学习心得的更多相关文章
- css定位中的百分比
----转载自自己在牛人部落中的相关文章--- 在前端css定位中经常面对的一个问题是,百分比定位究竟是针对于谁定位? 一.margin,padding的百分比 首先从css的设计意图说起,在浏览器默 ...
- 深入理解CSS定位中的偏移
× 目录 [1]定位 [2]包含块 [3]偏移属性[4]绝对定位[5]格式化 [6]auto 前面的话 CSS有三种基本的定位机制:普通流.浮动和绝对定位.利用定位,可以准确地定义元素框相对于其正常位 ...
- CSS定位:几种类型的position定位的元素
当人们刚接触布局的时候都比较倾向于使用定位的方式.因为定位的概念看起来好像比较容易掌握.表面上你确切地指定了一个块元素所处的位置那么它就会坐落于那里.可是定位比你刚看到的时候要稍微复杂一点.对于定位来 ...
- 【转】深入理解CSS定位中的偏移
前面的话 CSS有三种基本的定位机制:普通流.浮动和绝对定位.利用定位,可以准确地定义元素框相对于其正常位置应该出现的位置,或者相对于父元素.另一个元素甚至浏览器窗口本身的位置.但元素究竟如何定位,定 ...
- CSS定位中“父相子绝”
一.定位的介绍 定位有三种:相对定位(position:relative).绝对定位(position:absolute).固定定位(position:fixed) 二.三种定位的用法,特点和实例 2 ...
- 深入理解CSS定位中的堆叠z-index
× 目录 [1]定义 [2]堆叠规则 [3]堆叠上下文[4]兼容 前面的话 对于所有定位,最后都不免遇到两个元素试图放在同一位置上的情况.显然,其中一个必须盖住另一个.但,如何控制哪个元素放在上层,这 ...
- java中怎么终止一个线程的执行----个人学习心得
参考了一下两个网站的介绍: ①:http://blog.csdn.net/liuhanhan512/article/details/7077601 ②:http://www.blogjava.net/ ...
- CSS定位(postion)和移动(float)
5.定位和移动:Positioning(定位)CSS定位属性允许你为一个元素定位.它也可以将一个元素放在另一个元素后面,并指定一个元素的内容太大时,应该发生什么. 元素可以使用的顶部,底部,左侧和右侧 ...
- selenium - css 定位
前言: CSS(Cascading Style Sheets)是一种语言,它被用来描述 HTML 和 XML 文档的表现. CSS 使用选择器来为页面元素绑定属性.这些选择器可以被 selenium ...
随机推荐
- 解决右键notepad++打开时提示, ShellExecute failed (2): Is this command correct?
错误如下图: 解决方法: 右键notepad++.exe; 去掉管理员方式
- 第8.26节 重写Python类中的__getattribute__方法实现实例属性访问捕获
一. 引言 在<第7.23节 Python使用property函数定义属性简化属性访问的代码实现>和<第7.26节 Python中的@property装饰器定义属性访问方法gette ...
- PyQt学习随笔:Model/View设计中支持View中展示数据的排序
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在model/view架构中,有两种方法可以实现排序,选择哪种方法依赖于底层Model.如果mode ...
- C++中对一个布尔类型的变量按位取反结果不变
C++中对一个bool类型的变量按位取反是无效的.例如: bool a = true; bool b = ~a; // b的值还是true
- 深入浅出让你理解什么是LLVM
什么是LLVM 转载自https://www.jianshu.com/p/1367dad95445 LLVM项目是模块化.可重用的编译器以及工具链技术的集合. 美国计算机协会 (ACM) 将其2012 ...
- python-列表list和元组tuple
list Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时添加和删除其中的元素. 比如,列出班里所有同学的名字,就可以用一个list表示: >>> ...
- Java程序员需要了解的底层知识(一)
硬件基础知识 - Java相关硬件 汇编语言的执行过程(时钟发生器 寄存器 程序计数器) 计算机启动过程 进程线程纤程的基本概念面试高频 - 纤程的实现 内存管理 进程管理与线程管理(进程与线程 ...
- ASP.NET Log4net数据库日志新增记录客户端ip
LOG4数据库记录器XML配置 1 <appender name="ADONetAppender" type="log4net.Appender.ADONetApp ...
- 中间件面试专题:kafka高频面试问题
- 手写线程池,对照学习ThreadPoolExecutor线程池实现原理!
作者:小傅哥 博客:https://bugstack.cn Github:https://github.com/fuzhengwei/CodeGuide/wiki 沉淀.分享.成长,让自己和他人都能有 ...