您的位置:首页 > Web前端 > CSS

css定位

2015-11-01 20:31 429 查看
本周作业用到很多定位 就上网看了一些资料,发现我果断是浮动流,绝对相对驾驭不了,z-index为什么正值似乎没用呀。

下面是一些资料分享

绝对定位 的元素基于最近的
position
relative/absolute/fixed
祖先元素进行定位。如果没有找到
position
relative/absolute/fixed
的元素,则基于是以整个 canvas (渲染内容的空间) 的坐标原点(左上)为基准,以 viewport (也就是浏览器视窗内渲染 HTML 的空间)为大小的矩形进行定位, 并不是基于根元素定位 。

固定定位 的元素基于viewport(浏览器视窗)进行定位。

1. 绝对定位 和 固定定位 的元素若没有设置
top/right/left/bottom
的值。其位置为原来在文档流中的位置。其他文档流元素会占据其原来位置。

要使绝对定位或固定定位的元素水平居中,需要设置其
width
为固定值,并且
left: 0; right: 0;


2. 绝对定位 和 固定定位 的元素,若其宽度
width
或高度
height
的单位为 百分比 ,宽度和高度值是相对于其基于定位的元素计算的。(在使用一些stick插件时尤其要注意这点)。

CSS 中的 z-index 属性用于设置节点的堆叠顺序, 拥有更高堆叠顺序的节点将显示在堆叠顺序较低的节点前面, 这是我们对 z-index 属性普遍的认识. 与此同时, 我们总是对堆叠顺序捉摸不透, 将 z-index 的值设得很大也未必能将节点显示在最前面. 本文将通过一些例子对 z-index 的使用方法进行分析, 并且为各位带入 z-index 层级树的概念.

这个星期我们团队做了一次内部的技术分享, 南瓜小米粥为我们分享了他对 CSS z-index 的理解和引入层级树这个概念. 这个分享的现场效果很好, 所以我也将 z-index 和层级树话题搬到博客来谈一谈.

本文谈及多个影响节点显示层级的规则, 其中用到的所有例子全部罗列在《position 属性和 z-index 属性对页面节点层级影响的例子》中.

如果不对节点设定 position 属性, 位于文档流后面的节点会遮盖前面的节点.

如果将 position 设为 static, 位于文档流后面的节点依然会遮盖前面的节点浮动, 所以
position:static
不会影响节点的遮盖关系.

如果将 position 设为 relative (相对定位), absolute (绝对定位) 或者 fixed (固定定位), 这样的节点会覆盖没有设置 position 属性或者属性值为 static 的节点, 说明前者比后者的默认层级高.

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

我们尝试不用 position 属性, 但为节点加上 z-index 属性. 发现 z-index 对节点没起作用.

W3C 对 z-index 属性的描述中提到 在 z-index 属性仅在节点的 position 属性为 relative, absolute 或者 fixed 时生效.

如果所有节点都定义了 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>
<div id="b" style="position:relative;z-index:0;">B</div>
<div id="c" style="position:relative;">C</div>
<div id="d" style="position:relative;z-index:0;">D</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;">
<div id="a-1">A-1</div>
</div>

<div id="b" style="position:relative;z-index:0;">
<div id="b-1">B-1</div>
</div>



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

<div id="a" style="position:relative;z-index:0;">
<div id="a-1" style="position:relative;z-index:2;">A-1</div>
</div>

<div id="b" style="position:relative;z-index:0;">
<div id="b-1" style="position:relative;z-index:1;">B-1</div>
</div>



很多人将 z-index 设得很大, 9999 什么的都出来了, 如果不考虑父节点的影响, 设得再大也没用, 那是无法逾越的层级.

层级树规则

可能你会觉得在 DOM 结构中的兄弟节点会拎出来进行比较并确定层级, 其实不然.

<div id="a" style="position:relative;z-index:2;">
<div id="a-1" style="position:relative;z-index:0;">A-1</div>
</div>

<div id="b">
<div id="b-1" style="position:relative;z-index:1;">B-1</div>
</div>



我们认为同时将 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;">
<div id="a-1" style="position:relative;z-index:100;">A-1</div>
</div>

<div id="b">
<div id="b-1" style="position:relative;z-index:0;">
<div id="b-1-1" style="position:relative;z-index:10;">B-1-1</div>
</div>
</div>

<div id="c" style="position:relative;z-index:0;">
<div id="c-1">
<div id="c-1-1">
<div id="c-1-1-1" style="position:relative;z-index:1;">C-1-1-1</div>
</div>
</div>
</div>

例子中 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;">
<div id="a-1" style="position:relative;z-index:100;">A-1</div>
</div>

<div id="b">
<div id="b-1" style="position:relative;">
<div id="b-1-1" style="position:relative;z-index:10;">B-1-1</div>
</div>
</div>

<div id="c" style="position:relative;">
<div id="c-1">
<div id="c-1-1">
<div id="c-1-1-1" style="position:relative;z-index:1;">C-1-1-1</div>
</div>
</div>
</div>

根据默认值规则, 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;">
<div id="a-1" style="position:relative;z-index:100;">A-1</div>
</div>

<div id="b">
<div id="b-1">
<div id="b-1-1" style="position:relative;z-index:10;">B-1-1</div>
</div>
</div>

<div id="c" style="position:relative;">
<div id="c-1">
<div id="c-1-1">
<div id="c-1-1-1" style="position:relative;z-index:1;">C-1-1-1</div>
</div>
</div>
</div>

我们对上个例子改造一下, 将 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, 所以也参与层级树比较, 所以有如下效果.

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: