index鲜为人知的政工,index堆成堆法规

没人告诉你关于z-index的一些事

2015/07/23 · CSS · z-index

原文出处: Philip Walton   译文出处:HelKyle(@Helkyle)   

关于z-index的问题是很多程序员都不知道它是如何起作用的。说起来不难,但是大部分人并没有花时间去看规范,这往往会照成严重的后果。

你不信?那就一起来看看下面的问题。

z-index堆叠规则,z-index堆叠

关于z-index很少有人去深入的了解它,因为它看起来一点儿也不复杂,不就是谁的数字大,谁就显示在前面吗?然而今天所摘录的这篇博文,让我震惊了。我承认我从来没有花时间去看具体的z-index相关文档,所以我因此忽略了关于z-index的一些重要的信息。

<style type="text/css"></style>
<link href="public.css" rel="stylesheet" type="text/css"/>

问题

在下面的HTML我们写了3<div>元素,然后每个<div>元素里面都有一个元素,每个元素都有个背景色,并且使用absolute定位,为了能更清楚地看到z-index的效果,我们写了一些其他的样式。第一个`元素的z-index值为1`,其他两个没有设置。

代码如下:

XHTML

<div> <span class="red">Red</span> </div> <div> <span class="green">Green</span> </div> <div> <span class="blue">Blue</span> </div> .red, .green, .blue { position: absolute; } .red { background: red; z-index: 1; } .green { background: green; } .blue { background: blue; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div>
  <span class="red">Red</span>
</div>
<div>
  <span class="green">Green</span>
</div>
<div>
  <span class="blue">Blue</span>
</div>
 
.red, .green, .blue {
  position: absolute;
}
.red {
  background: red;
  z-index: 1;
}
.green {
  background: green;
}
.blue {
  background: blue;
}

See the Pen Stacking Order (problem) by Philip Walton (@philipwalton) on CodePen.

然后挑战来了: 尝试把红色的``元素放到其他两个元素后面,但是必须遵守下面的规则:

  • 不能修改HTML的内容
  • 不能增加或修改任何元素的z-index属性
  • 不能增加或修改任何元素的position属性

想挑战一些的话,就点击上面Codepen的Edit按钮去尝试一下吧。如果你不能做到,那就接着看下去。

一、z-index

z-index用来控制元素重叠时堆叠顺序。

适用于:已经定位的元素(即position:relative/absolute/fixed)。

一般理解就是数值越高越靠上,好像很简单,但是当z-index应用于复杂的HTML元素层次结构,其行为可能很难理解甚至不可预测。因为z-index的堆叠规则很复杂,下面一一道来。

首先解释一个名词:

stacking context:翻译就是“堆叠上下文”。每个元素仅属于一个堆叠上下文,元素的z-index描述元素在相同堆叠上下文中“z轴”的呈现顺序。

z-index取值:

默认值auto:

当页面新生成一个box时,它默认的z-index值为auto,意味着该box不会自己产生一个新的local stacking context,而是处于和父box相同的堆叠上下文中。

正/负整数

这个整数就是当前box的z-index值。z-index值为0也会生成一个local stacking context,这样该box父box的z-index就不会和其子box做比较,相当于隔离了父box的z-index和子box的z-index。

接下来从最简单的不使用z-index的情况开始将,循序渐进。

不相信我吗?好吧,看看你能否解决下面这个问题:

优先级 <span style="color:red;"></span> 越接近元素的css属性优先级越高

解决方案

See the Pen Stacking Order (problem) by Philip Walton (@philipwalton) on CodePen.

解决方案很简单,你只需要给红色的`标签增加一个opacity小于1`,像下面这样:

XHTML

div:first-child { opacity: .99; }

1
2
3
div:first-child {
  opacity: .99;
}

如果你觉得不可思议了,不相信透明度会影响叠加顺序,那么恭喜你,即将学习新的技能,一开始看到我也不信。

接下来让我们来摸索一番。

二、不使用 z-index时堆叠顺序

不使用z-index的情况,也是默认的情况,即所有元素都不用z-index时,堆叠顺序如下(从下到上)

  • 根元素(即HTML元素)的background和borders
  • 正常流中非定位后代元素(这些元素顺序按照HTML文档出现顺序)
  • 已定位后代元素(这些元素顺序按照HTML文档出现顺序)

解释一下后两条规则:

  • 正常流中非positoned element元素,总是先于positioned element元素渲染,所以表现就是在positioned element下方,跟它在HTML中出现的顺序无关。
  • 没有指定z-index值的positioned element,他们的堆叠顺序取决于在HTML文档中的顺序,越靠后出现的元素,位置越高,和position属性无关。

例子:

图片 1<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Stacking without z-index</title> <style type="text/css"> div { font: 12px Arial; text-align: center; } .bold { font-weight: bold; } .opacity{opacity: 0.7;} #normdiv { height: 70px; border: 1px dashed #999966; background-color: #ffffcc; margin: 0px 50px 0px 50px; } #reldiv1 { height: 100px; position: relative; top: 30px; border: 1px dashed #669966; background-color: #ccffcc; margin: 0px 50px 0px 50px; } #reldiv2 { height: 100px; position: relative; top: 15px; left: 20px; border: 1px dashed #669966; background-color: #ccffcc; margin: 0px 50px 0px 50px; } #absdiv1 { position: absolute; width: 150px; height: 350px; top: 10px; left: 10px; border: 1px dashed #990000; background-color: #ffdddd; } #absdiv2 { position: absolute; width: 150px; height: 350px; top: 10px; right: 10px; border: 1px dashed #990000; background-color: #ffdddd; } </style> </head> <body> <br /><br /> <div id="absdiv1" class="opacity"> <br /><span class="bold">DIV #1</span> <br />position: absolute; </div> <div id="reldiv1" class="opacity"> <br /><span class="bold">DIV #2</span> <br />position: relative; </div> <div id="reldiv2" class="opacity"> <br /><span class="bold">DIV #3</span> <br />position: relative; </div> <div id="absdiv2" class="opacity"> <br /><span class="bold">DIV #4</span> <br />position: absolute; </div> <div id="normdiv"> <br /><span class="bold">DIV #5</span> <br />no positioning </div> </body> </html> View Code

有图有真相:

图片 2

 分析:

#5没有定位,处于正常流,所以根据以上规则,先于#1,#2,#3,#4这些已定位元素渲染,在最下方。

#1,#2,#3,#4都是已定位元素,且未设置z-index,所以根据其在文档中出现的顺序依次被渲染,可以去掉apacity查看清晰效果。

问题:

在 接下来的HTML里 有三个<div>元素,并且每个<div>里包含一个<span>元素。每 个<span>被分别给定一个背景颜色:红、绿、蓝。每个<span>被放置到文档的左上角附近,部分重叠着其他 的<span>元素,这样你就可以看到哪些是被堆叠在前面。第一个<span>有一个z-index的值为1,而其他两个没有任 何z-index值。

以下就是这个HTML和它的基本CSS。

HTML代码

<div>
  Red
</div>
<div>
  Green
</div>
<div>
  Blue
</div>

CSS代码:

.red, .green, .blue {
  position: absolute;
  /*其它样式省略*/
}
.red {
  background: red;
  z-index: 1;
}
.green {
  background: green;
}
.blue {
  background: blue;
}

看起来的效果图应当是这样子的:

图片 3

 

 

选择器优先级
行内style >ID选择器 > class类选择器>html标签选择器
.new ul li a.blue{color:blue;}> a:hover{color:red;} > .white{color:white;}

堆叠顺序

z-index看上去很简单,z-index值大的元素在z-index值小的元素前面,对吧?但其实这只是z-index的一部分用法。很多程序猿都觉得很简单,没有花太多时间去认真阅读规则。

HTML中的每一元素都是在其他元素的前面或者后面。这是众所周知的堆叠顺序(Stacking Order),这条规则在w3c规范里面说的很清楚,但我前面提到过了,大部分程序猿并不真正理解。

如果没有涉及z-indexposition属性的话,那规则很简单,堆叠顺序就是元素在HTML中出现的顺序。(当然如果你对行内元素使用负margin的话,可能情况会复杂一些。)

加上position属性的话,就是所有定位了得元素在没有被定位的元素前面。(一个元素被定位的意思这里指的是它有一个position属性,但是不是static,而是relative,absolute等)

再加上z-index属性,事情就变得有点诡异。首先z-index值越大,越靠前。但是z-index属性只作用在被定位了的元素上。所以如果你在一个没被定位的元素上使用z-index的话,是不会有效果的。还有就是z-index会创建一个堆叠的上下文(Stacking Contexts),我们可以理解为一个层。

三、浮动堆叠顺序

浮动元素z-index位置介于非定位元素和定位元素之间。(从下到上)

  • 根元素(即HTML元素)的背景和border
  • 正常流中非定位后代元素(这些元素顺序按照HTML文档出现顺序)
  • 浮动元素(浮动元素之间是不会出现z-index重叠的)
  • 正常流中inline后代元素
  • 已定位后代元素(这些元素顺序按照HTML文档出现顺序)

 non-positioned元素的背景和边界没有被浮动元素影响,但是元素中的内容受影响(浮动布局特性)

举例:

图片 4<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Stacking and float</title> <style type="text/css"> div { font: 12px Arial; text-align: center; } .bold { font-weight: bold; } .opacity{ opacity: 0.7;} #absdiv1 { position: absolute; width: 150px; height: 200px; top: 10px; right: 140px; border: 1px dashed #990000; background-color: #ffdddd; } #normdiv { /* opacity: 0.7; */ height: 100px; border: 1px dashed #999966; background-color: #ffffcc; margin: 0px 10px 0px 10px; text-align: left; } #flodiv1 { margin: 0px 10px 0px 20px; float: left; width: 150px; height: 200px; border: 1px dashed #009900; background-color: #ccffcc; } #flodiv2 { margin: 0px 20px 0px 10px; float: right; width: 150px; height: 200px; border: 1px dashed #009900; background-color: #ccffcc; } #absdiv2 { position: absolute; width: 150px; height: 100px; top: 130px; left: 100px; border: 1px dashed #990000; background-color: #ffdddd; } </style> </head> <body> <br /><br /> <div id="absdiv1" class="opacity"> <br /><span class="bold">DIV #1</span> <br />position: absolute; </div> <div id="flodiv1" class="opacity"> <br /><span class="bold">DIV #2</span> <br />float: left; </div> <div id="flodiv2" class="opacity"> <br /><span class="bold">DIV #3</span> <br />float: right; </div> <br /> <div id="normdiv"> <br /><span class="bold">DIV #4</span> <br />no positioning </div> <div id="absdiv2" class="opacity"> <br /><span class="bold">DIV #5</span> <br />position: absolute; </div> </body> </html> View Code

图片 5

分析:

#4是正常流中非定位的元素,所以先被渲染,在最底层。

#2 #3一个左浮动,一个右浮动,接着被渲染。彼此不会因为z-index值被覆盖。见下图。

#1 #5为已定位的元素,最后被渲染,当浏览器窗口变小时,#5在#1上面,因为HTML文档中#5在#1后面。见下图。

 图片 6

挑战:

尝试使红色<span>元素堆在蓝色和绿色<span>的后面,不要打破以下规则:

  • 不要以任何方式改变HTML标记
  • 不要添加/修改任何元素的z-index属性
  • 不要添加/修改任何元素的position属性

如果你找到了答案,那么它应该像下面这样:

图片 7

<span style="">优先级最高</span>

堆叠上下文

同一个父元素下面的元素会受父元素的堆叠顺序影响,所以堆叠上下文是我们理解z-index和堆叠顺序的关键。(下面为了简化,我们称堆叠上下文为层。)

每一个层都有唯一的根节点。当一个元素创建一个层,那么它的所有子元素都会受到父元素的堆叠顺序影响。意味着如果一个元素位于一个最低位置的层,那你z-index设置得再大,它也不会出现在其它层元素的上面。

现在我们来说说什么情况下会产生新的层:

  • 当一个元素位于HTML文档的最外层(<html>元素)
  • 当一个元素被定位了并且拥有一个z-index值(不为auto)
  • 当一个元素被设置了opacitytransformsfilterscss-regionspaged media等属性。

一二条规则,Web开发者都知道,虽然他们不一定知道怎么描述

最后一条,是很多非w3c规范里面的文章很少提到的。通常来讲,如果一个CSS属性需要做一些特效的话,它都会创建一个新的层。

影响堆叠顺序的因素有很多,我推荐你去看w3c规范,这篇文章我们主要探讨关于层的内容。

四、z-index

默认的堆叠顺序上面说了,要想改变 元素的堆叠顺序就得用到z-index。

Note:前两种情况中,虽然有元素之间的重叠覆盖,但是它们都是处在同一个z-layer的。因为没有设置z-index属性,默认的渲染层就是layer 0。所以要注意,不同层中元素之间覆盖是理所当然的,但是同一层中的元素也会发送覆盖。

z-index只适用于已经定位的元素(即position:relative/absolute/fixed)。

举例:

图片 8<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Stacking without z-index</title> <style type="text/css"> div { font: 12px Arial; text-align: center; opacity: 0.7; } .bold { font-weight: bold; } #normdiv { z-index: 8; height: 70px; border: 1px dashed #999966; background-color: #ffffcc; margin: 0px 50px 0px 50px; } #reldiv1 { z-index: 3; height: 100px; position: relative; top: 30px; border: 1px dashed #669966; background-color: #ccffcc; margin: 0px 50px 0px 50px; } #reldiv2 { z-index: 2; height: 100px; position: relative; top: 15px; left: 20px; border: 1px dashed #669966; background-color: #ccffcc; margin: 0px 50px 0px 50px; } #absdiv1 { z-index: 5; position: absolute; width: 150px; height: 350px; top: 10px; left: 10px; border: 1px dashed #990000; background-color: #ffdddd; } #absdiv2 { z-index: 1; position: absolute; width: 150px; height: 350px; top: 10px; right: 10px; border: 1px dashed #990000; background-color: #ffdddd; } </style> </head> <body> <br /><br /> <div id="absdiv1"> <br /><span class="bold">DIV #1</span> <br />position: absolute; <br />z-index: 5; </div> <div id="reldiv1"> <br /><span class="bold">DIV #2</span> <br />position: relative; <br />z-index: 3; </div> <div id="reldiv2"> <br /><span class="bold">DIV #3</span> <br />position: relative; <br />z-index: 2; </div> <div id="absdiv2"> <br /><span class="bold">DIV #4</span> <br />position: absolute; <br />z-index: 1; </div> <div id="normdiv"> <br /><span class="bold">DIV #5</span> <br />no positioning <br />z-index: 8; </div> </body> </html> View Code

图片 9

解决方案:

这个解决方法是在第一个<div>里(红色<span>的父节点)添加一个小于1的opacity属性值。下面就是被添加的CSS的例子:

div:first-child {
  opacity: .99;
}

如果你现在很震惊,但是仍然百思不得其解,并且不相信opacity能决定哪个元素堆在前面,那么是时候看看关于样式的文档了。当第一次在这个问题上被困扰时我同样很震惊。

希望接下来的内容能够让你对这个问题更清楚些。

(2)多个选择器的优先级计算
假设,用1代表标签选择器,10代表类选择器,100代表ID选择器,1000代表行内样式
H2{color:#FF0000} 优先级 1
.news h2{color:#0000FF} 优先级 11
div.news h2{color:#00FF00} 优先级 12
div#news h2{color:#FFFF00} 优先级 102

同一层里面的堆叠顺序

下面是同一层里面的堆叠顺序(从后到前):

  • 层的根元素
  • 被定位了得元素并且z-index值为负,相同z-index的情况下,按照HTML元素的书写顺序排列,下面相同。
  • 没有被定位的元素
  • 被定位的元素,并且z-index值为auto
  • 被定位了的元素并且z-index值为正。

注意:z-index值为负的元素比较特殊,他们会先被绘制,意味着他们可以出现在其他元素的后面,甚至出现在它的父元素后面。但是必要条件是该元素必须与父元素处于同一层,并且父元素不是这个层的根元素。一个很好的例子

理解了如何和什么时候会产生一个新的层,那么下次如果你遇到z-index值设了很大,但是不起作用的话就去看看它的祖先是否产生了一个新的层。

五、stacking context

为什么上个例子中元素的堆叠顺序受z-index的影响呢?因为这些元素有些特殊的属性触发它们生存堆叠上下文(stacking context)。

问题来了,什么样的元素会生成堆叠上下文呢?符合下面规则之一的:

  • 根元素(即HTML元素)
  • 已定位元素(即绝对定位或相对定位)并且z-index不是默认的auto。
  • a flex item with a z-index value other than "auto",
  • 元素opacity属性不为1(See the specification for opacity)
  • 元素transform不为none
  • 元素min-blend-mode不为normal
  • 元素filter属性不为none
  • 元素isolation属性为isolate
  • on mobile WebKit and Chrome 22 , position: fixed always creates a new stacking context, even when z-index is "auto" (See this post)
  • specifing any attribute above in will-change even you don't write themselves directly (See this post)
  • elements with -webkit-overflow-scrolling set to "touch"

在堆叠上下文(stacking context)中 ,子元素的堆叠顺序还是按照上述规则。重点是,子元素的z-index值只在父元素范围内有效。子堆叠上下文被看做是父堆叠上下文中一个独立的模块,相邻的堆叠上下文完全没关系。

总结几句:

渲染的时候,先确定小的stacking context中的顺序,一个小的stacking context确定了以后再将其放在父stacking context中堆叠。有种由内而外,由小及大的感觉。

举例:HTML结果如下,最外层是HTML元素,包含#1 #2 #3,#3中又包含着#4,#5,#6。

Root(HTML)

  • DIV #1
  • DIV #2
  • DIV #3
    • DIV #4
    • DIV #5
    • DIV #6

图片 10<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "; <html xmlns="" xml:lang="en"> <head> <title>Understanding CSS z-index: The Stacking Context: Example Source</title> <style type="text/css"> * { margin: 0; } html { padding: 20px; font: 12px/20px Arial, sans-serif; } div { opacity: 0.7; position: relative; } h1 { font: inherit; font-weight: bold; } #div1, #div2 { border: 1px solid #696; padding: 10px; background-color: #cfc; } #div1 { z-index: 5; margin-bottom: 190px; } #div2 { z-index: 2; } #div3 { z-index: 4; opacity: 1; position: absolute; top: 40px; left: 180px; width: 330px; border: 1px solid #900; background-color: #fdd; padding: 40px 20px 20px; } #div4, #div5 { border: 1px solid #996; background-color: #ffc; } #div4 { z-index: 6; margin-bottom: 15px; padding: 25px 10px 5px; } #div5 { z-index: 1; margin-top: 15px; padding: 5px 10px; } #div6 { z-index: 3; position: absolute; top: 20px; left: 180px; width: 150px; height: 125px; border: 1px solid #009; padding-top: 125px; background-color: #ddf; text-align: center; } </style> </head> <body> <div id="div1"> <h1>Division Element #1</h1> <code>position: relative;<br/> z-index: 5;</code> </div> <div id="div2"> <h1>Division Element #2</h1> <code>position: relative;<br/> z-index: 2;</code> </div> <div id="div3"> <div id="div4"> <h1>Division Element #4</h1> <code>position: relative;<br/> z-index: 6;</code> </div> <h1>Division Element #3</h1> <code>position: absolute;<br/> z-index: 4;</code> <div id="div5"> <h1>Division Element #5</h1> <code>position: relative;<br/> z-index: 1;</code> </div> <div id="div6"> <h1>Division Element #6</h1> <code>position: absolute;<br/> z-index: 3;</code> </div> </div> </body> </html> View Code

效果:

图片 11 

 分析一下:

1、因为设置了div {opacity: 0.7; position: relative;},所以#1~#6的z-index都是有效的。

2、为什么#4的z-index比#1高,但是却在#1下面?因为#4的z-index虽然值大,但它的作用域在包含块#3内,而#1的z-index的作用域在html内,和#3同属html,而#3的z-index小于#1。

3、为什么#2的z-index值比#5的大,还在下面?同上。

4、#3的z-index是4,但该值和#4,#5,#6的z-index不具有可比性,它们不在一个上下文环境。

5、如何轻易的判断两个元素的堆叠顺序?

z-index对堆叠顺序的控制类似于排版时候一大章下几个小节的样子,或者版本号中一个大的版本号跟着小版本号。

Root-z-index值为默认auto,即0

  • DIV #2 - z-index 值为2
  • DIV #3 - z-index 值为4
    • DIV #5 - z-index值为 1,其父元素z-index值 4,所以最终值为4.1
    • DIV #6 - z-index值为 3,其父元素z-index值 4,所以最终值为4.3
    • DIV #4 - z-index值为 6,其父元素z-index值 4,所以最终值为4.6
  • DIV #1 - z-index 值为5

想看更多例子,可参考文章最后的资源链接。

堆栈顺序

Z-index看上去如此简单:高的z-index堆在低的z-index的前面,对吗?这实际上是错的,是z-index问题的一部分。它看上去如此的简单,以至于很多开发者没有花相应的时间去读相关的规则。

每一个在HTML文档中的元素既可以在其他元素的前面,也可以在其他元素的后面。这就是所谓的堆栈顺序。决定这个顺序的规则被十分清楚的定义在说明文档中,但是就像之前我已经提到过,这些文档没有被大多数开发者们完全弄明白。

当z-index和position属性不被包括在内时,这些规则相当简单:基本上,堆栈顺序和元素在HTML中出现的顺序一样。(好吧,其实是有一点复杂的,但是只要你不使用压缩边界来重叠行内元素,你可能不会遇到边界问题。)

当你把位置属性也包括在内介绍时,任何定位元素(和他们的子元素)都在非定位元素前被显示出来。(说一个元素被“定位”意思是它有一个不同于静态的位置值,例如相对的,绝对的,等等。)

最 后,当z-index被提及时,事情变的有点儿复杂。最初,很自然的假设带有高z-index值的元素会在带有低z-index值的元素前面,但是后来发 现没那么简单。首先,z-index只对定位元素起作用。如果你尝试对非定位元素设定一个z-index值,那么肯定不起作用。其次,z-index值能 创建堆栈上下文环境,并且突然发现看似简单的东西变的更加复杂了。

 

总结

说了这么多,我们来给之前的代码加上堆叠顺序。

XHTML

<div><!-- 1 --> <span class="red"><!-- 6 --></span> </div> <div><!-- 2 --> <span class="green"><!-- 4 --><span> </div> <div><!-- 3 --> <span class="blue"><!-- 5 --></span> </div>

1
2
3
4
5
6
7
8
9
<div><!-- 1 -->
  <span class="red"><!-- 6 --></span>
</div>
<div><!-- 2 -->
  <span class="green"><!-- 4 --><span>
</div>
<div><!-- 3 -->
  <span class="blue"><!-- 5 --></span>
</div>

当我们设置了opacity之后变成下面这样。

XHTML

<div><!-- 1 --> <span class="red"><!-- 1.1 --></span> </div> <div><!-- 2 --> <span class="green"><!-- 4 --><span> </div> <div><!-- 3 --> <span class="blue"><!-- 5 --></span> </div>

1
2
3
4
5
6
7
8
9
<div><!-- 1 -->
  <span class="red"><!-- 1.1 --></span>
</div>
<div><!-- 2 -->
  <span class="green"><!-- 4 --><span>
</div>
<div><!-- 3 -->
  <span class="blue"><!-- 5 --></span>
</div>

红色的`从6变成1.1`,我用’.’来标记它是新生成的层里面的第一个元素。

最后我们来总结一下为什么红色的会去到下面: 一开始有两个层,一个由根节点产生,一个由设置了`z-index:1`并且`position:absolute`的红色产生。当我们设置了opacity时,产生了第三个层,并且第三个层把红色`产生的层包裹了,意味着刚开始的z-index的作用域只在第三个层里面。而所有的

`都没有定位或者z-index,所以他们的堆叠顺序按照HTML出现顺序排列,于是第三个层就去到下面。

六、 合理使用z-index数值

如果现有三个堆叠的层,从上到下分别为:DIV3,DIV2,DIV1,设置时以100为间隔,设置DIV1的z-index为0,DIV2的z-index为100,设置DIV3的z-index为200。这样后期如果需要在DIV1和DIV2之间加入一些层的话,以10为间隔,设置z-index为10,20等。再需要向z-index0和z-index10之间加入一层的话以5为间隔。这样的写法可以方便后期扩展添加内容。

尽量避免给z-index使用负值。当然不是绝对的,比如在做图文替换的时候可以使用负值。

堆栈上下文

一组具有共同双亲的元素,按照堆栈顺序一起向前或向后移动构成了所谓的堆栈上下文。充分理解堆栈上下文是真正掌握z-index和堆栈顺序工作原理的关键。

每 一个堆栈上下文都有一个HTML元素作为它的根元素。当一个新的堆栈上下文在一个元素上形成,那么这个堆栈上下文会限制所有的子元素以堆栈的顺序存储在一 个特别的地方。那意味着一旦一个元素被包含在处于底部堆栈顺序的堆栈上下文中,那么就没有办法先出现于其他处于更高的堆栈顺序的不同堆栈上下文元素,就算 z-index值是十亿也不行!

现在,堆栈上下文有三种方法可以在一个元素上形成:

  • 当一个元素是文档的根元素时(<html>元素)
  • 当一个元素有一个position值而不是static,有一个z-index值而不是auto
  • 当一个元素有一个opacity值小于1

前两种形成堆栈上下文的方法具有很大意义并且被广大Web开发者所理解(即使他们不知道这些被叫做什么)。第三种方法(opacity)几乎从来没在w3c说明文档之外被提及过。

*{font-size:12px;} //通用选择器 ie6不支持,少用
h1{font-size:12px;} // 标签选择器
<div class=""></div> //类样式 【使用最多】
<div id=""></div> // id 选择器 【多用于js调用,id唯一】

推荐阅读

  • Elaborate description of Stacking Contexts
  • The stacking context
  • The Z-Index CSS Property: A Comprehensive Look

    1 赞 3 收藏 评论

图片 12

七、资源链接

MDN z-index

understanding css z-index

w3c z-index

 

一、z-index z-index用来控制元素重叠时堆叠顺序。 适用于 :已经定位的元素(即position:relative/absolute/fixed)。 一...

用堆栈顺序决定一个元素的位置

实际上,为一个页面上的所有元素决定全局堆栈顺序(包括边界、背景、文本节点、等等)是极度复杂的,并且远远超越了本文讲述的范围(再一次,参考文档)。但是我们最大的目的,就是基本了解这个顺序,它能够在很长一段时间内帮助我们提高CSS开发的可预测性。所以,让我们打破顺序,分解为独立的堆栈上下文。

多元素选择器
h1,h2{color:red;}

在同样的堆栈上下文里的堆栈顺序

下面是几条基本的规则,来决定在一个单独的堆栈上下文里的堆栈顺序(从后向前):

  1. 堆栈上下文的根元素
  2. 定位元素(和他们的子元素)带着负数的z-index值(高的值被堆叠在低值的前面;相同值的元素按照在HTML中出现的顺序堆叠)
  3. 非定位元素(按照在HTML中出现的顺序排序)
  4. 定位元素(和他们的子元素)带着auto的z-index值(按照在HTML中出现的顺序排序)
  5. 定位元素(和他们的子元素)带着正z-index值(高的值被堆叠在低值的前面;相同值的元素按照在HTML中出现的顺序堆叠)

注 解:定位元素带有负的z-index值被在一个堆栈上下文中先排序,这意味着他们出现在所有其他元素的后面。正因如此,它使一个元素出现在自己父元素之后 成为可能,这以前通常是不可能的事。当然,这局限于它的父元素与它在同一个堆栈上下文,并且不是那个堆栈上下文的根元素。一个伟大的例子如Nicolas Gallagher的CSS不用图像降低阴影。

后代元素选择器
子元素选择器

全局堆栈顺序

坚定的理解了为什么/什么时候新的堆栈上下文形成,同时掌握了同一个堆栈上下文的堆栈顺序,现在让你来找出一个特定元素将出现在全局堆栈里的顺序不是那么糟糕了吧?

避免错误的关键是能够发现新的堆栈上下文什么时候形成。如果你对一个元素设置了z-index值为十亿但是它没有在堆栈顺序中向前移动,检查一下它的祖先树,看是否它的父节点形成了堆栈上下文。如果是那样的话,你的z-index值即使有十亿也不会给你带来好处。

.new li{border:1px solid #ccc;} 后代所有元素【特别哦】
.new > .title{color:red;} 子代元素 【只有一代】【少用】
<div class="new">
<div class="title">title</div>
<div class="content">
<li>公司成立</li>
</div>
</div>

包扎救治

回到之前的原始问题,我已经重建了这个HTML的结构,添加了一些注释,每一个标签指明了它在堆栈里的顺序。这个顺序是假设最初的CSS。

<div><!-- 1 -->
  <!-- 6 -->
</div>
<div><!-- 2 -->
  <!-- 4 -->
</div>
<div><!-- 3 -->
  <!-- 5 -->
</div>

这是我们熟知的,所以结果在我们的意料之中,但当我们添加opacity到第一个<div>,堆栈顺序像下面这样改变:

<div><!-- 1 -->
  <!-- 1.1 -->
</div>
<div><!-- 2 -->
  <!-- 4 -->
</div>
<div><!-- 3 -->
  <!-- 5 -->
</div>

span.red曾经的顺序是6,但现在改为1.1。我已经使用“.”来标注一个新的上下文环境的形成。span.red现在是那个新的上下文的第一个元素。

现 在似乎更清晰了,关于为什么红色盒子跑到其他盒子的后面。原始的例子只包含两个堆栈上下文,根元素和形成span.red的那个。当我们添加 opacity到span.red的父节点上,形成了第三个堆栈上下文,结果显示在span.red上的z-index值只能应用在那个新的堆栈上下文 中。因为第一个<div>(应用opacity的那个)和它的兄弟元素没有position或者z-index值的集合,他们的堆栈顺序是由 他们在HTML里的源顺序决定的,也就是说第一个<div>,和它的堆栈上下文里的所有元素被第二个和第三个<div>元素分 离。

注:以上请在chrome浏览器下测试!

来源:关于z-index的那些事儿

div.box class="box" 的 div
div#header id="header"的div

任何html元素都有 width height padding margin border background

body{font:bold italic 24px 黑体;} 简写的形式
letter-spacing: 字间距
line-height:150% 行高1.5倍

padding:0px 0px 1px; 上 左右 下
单行文本上下居中li{height:30px; line-height:30px;}
li{list-style-type:none; }

伪类选择器 <a>
a:link,a:visited{text-decoration:none;}
a:hover{text-decoration:underline;}

a.a1:link{color:red;} [厉害哦]

<li><a>xx</a></li>
<li><a class="a1">xxxxx</a></li>

background-color
background-image
background-attachment 移动滚动条时,背景固定fix 还是滚动 scroll

<style type="text/css">
body,div,li{padding:0; margin:0;}
ul,li{list-style:none;}
li{
padding-left:30px;
background-repeat:no-repeat;
background-image:url();
background-position:left center;} li背景图片水平左对齐 垂直居中对齐
</style>

行内元素 span a img 

行内元素的大小由内容决定,设置 width 和 height是看不到效果的

行内元素转块元素

<span style="float:left;"></span> 变成了块元素

a span{display:block;} //行内元素转成块元素

div{display:inline;} //块元素转行内元素

行内元素,经过什么操作,可以变成“块元素”?
浮动、display:block、固定定位、绝对定位

<span style="float:right;">右对齐
float元素不占空间,不占px

任何元素都可以浮动 float
所有图片float:left; 只要宽度不够,就会自动换行,就有如下效果
<ul><li><img src=""/></li></ul>
图片1 图片2
图片3 图片4

p{width:580px; padding:20px 10px;} 宽就是600px了,添加padding margin 要减小width

每个div都定义高度
li{float:left;}
font-weight:bold;

<div class="class1 class2"></div> 加两个样式

一行两个东西,一个float:left;一个float:right;

css定位
position: static(静态定位) fixed(固定定位) relative 相对定位 absolute 绝对定位
left 设置元素距离左边多远
right top bottom

任何元素,默认是静态定位
固定定位:相对于浏览器窗口(在线QQ) 固定元素,脱离文档,不占空间,是”块元素“
相对定位:是相对于”它原来的自己“来进行的偏移,所占空间保留(淘宝图片新品标志)
position:relative;
right:-100px; //用负数

绝对定位:相对于它的祖先(上级或者上上级,最终是<body>)定位,不占空间

组合使用
上级相对 position:relative;
具体那个元素 position:absolute; top:-10px; right:-30px;

CSS HACK 实在解决不了兼容性问题,可以试试使用css hack
CSS HACK,针对不同浏览器IE6 IE7 IE8 火狐,编辑不同的CSS代码的过程,就叫CSS HACK。
(1)CSS属性的HACK:
div{
background-color:red; //所有浏览器都支持 其他 显示 red
*background-color:green; //ie6和IE7支持 ie7 显示 green
_background-color:blue; //IE6认识 最终 ie6 显示 blue

 

下面的css hack  未验证

CSS Hack的实现方式:

         (1)IE条件语句:只在IE9-有效

                   <!--[if IE]> 小于IE10的浏览器会看到此句<![endif]-->

                   <!--[if IE 6]> IE6看到此句<![endif]-->

                   <!--[if lt IE 8]> 小于IE8的浏览器会看到此句 <![endif]-->

                   <!--[if lte IE 8]> 小于等于IE8的浏览器会看到此句 <![endif]-->

                   上述条件语句中可以放置任何CSS/HTML/JS语句。

         (2)选择器前缀

                   <style>

                            .content{ }        所有浏览器都能理解的选择器

                            *html  .content{}                      只有IE6能理解的选择器

                            * html     .content{}                   只有IE7能理解的选择器

                   </style>

         (3)属性前缀

                   <style>

                            .content{

                                     -webkit-animation: anim1  3s;      

                                     -moz-animation: anim1  3s;

                                     -o-animation: anim1  3s;

                                     background: red;               /*所有浏览器都能识别*/

                                     *background:green;         /*IE6/IE7能识别*/

                                     _background:blue;            /*IE6/IE7能识别*/

                                     background:yellow;        /*IE能识别*/

                                     background: yellow9\0; /*IE9 能识别*/

                                     background: pink !important;  /*IE6无法识别*/

}

                   </style>

css 优化

页面访问速度优化

         (0)硬件/网络优化

         (1)数据库优化

         (2)服务器优化

         (3)前端优化: HTML优化、CSS优化、JS优化

  CSS优化方案:

         优化原则:尽可能减少HTTP请求数量;尽可能减少每次请求的数据大小

         优化方法:

         (1)CSS Sprites:背景图滑动门、把很多的小背景图拼接为一副大图——百度“CSS Sprites在线”可以找到很多这样的工具

         (2)把CSS放到页面顶部,多用<link href=”x.css”/>代替@import url(x.css)

         (3)避免使用CSS表达式

         (4)避免空的src和href值

         (5)巧用浏览器缓存,把CSS放在尽可能少的HTML外部文件

         (6)首页中尽量不用外部CSS

         (7)不要在HTML中缩放图像

         (8)对JavaScript文件和CSS文件进行压缩(剔除空白/换行/注释等),减小文件大小。可使用类似YUI Compressor等工具    Yahoo UI Libary

 

本文由星彩网app下载发布于前端技术,转载请注明出处:index鲜为人知的政工,index堆成堆法规

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。