2012年11月29日星期四

【转】windows下apache的ThreadsPerChild和Win32DisableAcceptEx参数的相关问题

这几天喻名堂的公司有一个用Apache搭建的web服务器老是在早上6点多钟的时候访问不了,就像没有搭建过PHP环境一样的,后来在错误日志里面发现有如下错误:

[Sat May 26 06:32:20 2012] [warn] Server ran out of threads to serve requests. Consider raising theThreadsPerChild setting
[Sat May 26 06:32:43 2012] [warn] (OS 64)指定的网络名不再可用。  : winnt_accept: Asynchronous AcceptEx failed.
[Sat May 26 06:32:43 2012] [warn] (OS 64)指定的网络名不再可用。  : winnt_accept: Asynchronous AcceptEx failed.

第一个错误看字面意思比较好理解,就是线程用完了,建议增加线程数,这就是导致Apache访问不了的问题所在了,但是为什么会有“指定网络名不再可用”这样的错误呢,而且是疯狂的写这样的日志,导致错误日志文件都很大。于是在网上搜索了相关的解决办法,首先当然是要在Apache的httpd.conf文件中配置ThreadsPerChild参数来增加Apache的线程数,然后在Apache的httpd.conf文件中加上Win32DisableAcceptEx参数。具体添加的内容如下:

<IfModule mpm_winnt.c>    

ThreadsPerChild 150    

MaxRequestsPerChild  1000    

Win32DisableAcceptEx    

</IfModule>  

这里对上面的各个参数做一下解释:ThreadsPerChild参数就是设置Apache的线程数,我这里设置的150,为什么要设置为150在后面会有解释;MaxRequestsPerChild参数是设置Apache的是大线程数,当Apache使用的线程超过这个数的时候Apache就会自动重启;设置Win32DisableAcceptEx参数是为了解决“指定的网络名不再可用”的问题的,原因是apache在某些Windows版本上可能兼容性不足,在调用AcceptEx接收请求时可能有问题,只在APAche2.0.49以上版本会有这中问题。 《Apache 2_2 中文版参考手册》上说:“AcceptEx()是一个微软的WinSock2 API ,通过使用BSD风格的accept() API提供了性能改善。一些流行的Windows产品,比如防病毒软件或虚拟专用网络软件,会干扰AcceptEx()的正确操作。如果你遇到类似于如下 的错误:一般的解决办法是关闭 AcceptEx()”。也就是说,可能是 Windows Update 或是防火墙、防毒软件更新了某些网络原件,造成 Microsoft WinSock v2 API 动作不正常,会干扰WinSock2 API,就会影响AcceptEx()的正确操作,就可能出现上面所出现的问题。但是关闭会影响Apache的性能,喻名堂这里设置后的主要表现就是内存的占用量会明显的增加,而且在用F5不断刷新页面的情况下内存的占用量还会飞快的增长,直到Apache的线程数达到最高上限重启。不过经过进一步的搜索和实验,只要把Apache的线程数设置在170以下,这种情况就不会出现,不管怎么刷新网页Apache的内存占用量都会维持在115M左右,停止刷新又会慢慢回到30多M。当然这只是在喻名堂的服务器上的测试结果,并不能代表全部。

另外在网络上搜索到在Apache的配置文件里面添加Win32DisableAcceptEx参数以后还是会出现“指定的网络名不再可用”,网上提供了如下进一步解决办法:

1、网上邻居-;本地连接-;属性-;internet协议(TCP/IP)-;属性-;高级-;wins标签-;去掉启用LMhosts查询前的勾.

2、控制面版-;windows防火墙-;高级标签-;本地连接设置-;服务的标签里勾选安全Web服务器(HTTPS)。

3、然后退出Apache,再打开启动就可以了 ,一定要先停止,在开启即可。

以上进一步解决办法喻名堂也一并用了,因为是今天设置的,所以还不能测试到这样设置到底有没有用,结果只能等到明天才能知道了。请继续关注我的博客,或者订阅我的博客

摘自:http://hi.baidu.com/donever/item/f6df653ec0f503c31a9696e9

【转】xampp中apache最大连接数修改

今天早上突然发现网站打不开,apache像是死了,

且MYSQL数据库中存在大量sleep连接,仔细查了原因,分析出最大可能是网站访问超出APACEH最大连接数。于是按下面方法修改,结果问题解决了。

#vi /opt/lampp/etc/httpd.conf

找到并取消注释下面这行

#Include conf/extra/httpd-mpm.conf

#vi vi /opt/lampp/etc/extra/httpd-mpm.conf

找到


<IfModule mpm_prefork_module>
    StartServers          5
    MinSpareServers       5
    MaxSpareServers      10
    MaxClients          150
    MaxRequestsPerChild   0
</IfModule>

上面是默认参数,下面是我修改后的

<IfModule prefork.c>
ServerLimit 1500
StartServers 10
MinSpareServers 10
MaxSpareServers 15
MaxClients 1000
MaxRequestsPerChild 10000
</IfModule>

 作者: 蔡文卫 Leo@yicike.com

版权所有:亿枝客比较购物搜索网(http://www.yicike.com/

摘自:http://arloe.blog.163.com/blog/static/1229950472009101364034273/

2012年11月27日星期二

【转】PHP stdClass Object转array 函数

//PHP stdClass Object转array
function object_array($array) {
if(is_object($array)) {
$array = (array)$array;
} if(is_array($array)) {
foreach($array as $key=>$value) {
$array[$key] = object_array($value);
}
}
return $array;
}

【转】深入解析IE兼容模式问题

摘自: http://www.jb51.net/css/37778.html

英文原文:http://msdn.microsoft.com/en-us/library/cc288325(VS.85).aspx 
文件兼容性用于定义让IE如何编译你的网页。此文件解释文件兼容性,如何指定你网站的文件兼容性模式以及如何判断一个网页该使用的文件模式。 
前言 
为了帮助确保你的网页在所有未来的IE版本都有一致的外观,IE8引入了文件兼容性。在IE6中引入一个增设的兼容性模式,文件兼容性使你能够在IE呈现你的网页时选择特定编译模式。 
新的IE为了确保网页在未来的版本中都有一支的外观,IE8引入了文件兼容性。当你引入一个增设的兼容性模式, 
此文章说明文件兼容性的必要性,列出现有版本IE能使用的文件兼容性模式并示范如何选择特定的兼容性模式。 
了解文件兼容性的必要性 

每个主要版本IE新增的功能都是为了让浏览器更容易使用、增加安全性及更支持业界标准。以这些作为IE的特色,其中一个风险就是旧版本网站无法正确的显示。 

为了将这个风险降到最低,IE6允许网页开发人员选择IE编译和显示他们网页的方式。"Quirks mode"为预设,这会使页面以旧版本浏览器的视点显示,"Standards mode"(也称为"strict mode")特点是支持业界标准最为完善。然而要利用这个增强的支持功能,网页必须包含恰当的<!DOCTYPE>指令。 

若一个网页没有包含<!DOCTYPE>指令,IE6会将它以quirks mode显示。若网页包含有效的<!DOCTYPE>指令但浏览器无法辨识,IE6会将它以IE6 standards mode显示。因为少数网站已经包含<!DOCTYPE>指令,兼容性模式的切换相当成功。这使网页开发人员能选择将他们的网页转移为standards mode的最佳时机。 

随著时间经过,更多网站开始使用standards mode。它们也开始使用IE6的特性和功能来检测IE。举例来说,IE6不支持universal selector(即css之全局选择器 * {}),一些网站便使用它来针对IE做特定的对应。 

当 IE7增加了对全域选择器的支持,那些依赖IE6特点的网站便无法侦测出这个新版本的浏览器。因此那些针对IE的特定对应无法应用于IE7,造成这些网站便无法如他们预期的显示。由于<!DOCTYPE>只支持两种兼容性模式,受到影响的网站拥有者被迫更新他们的网站使其能支持IE7。 

IE8 比之前的任何版本浏览器都更支持业界标准,因此针对旧版本浏览器设计的网页可能无法如预期般呈现。为了帮助减轻所有问题,IE8引入文件兼容性的概念,使你能选择你的网页设计要对应的特定IE版本。文件兼容性在IE8增加了一些新的模式,这些模式能告诉浏览器如何解析和编译一个网页。若你的网页无法在 ie8正确的显示,你可以更新你的网站使它支持最新的网页标准(优先选项)或在你的页面上新增一个meta元素用于告诉IE8如何依照旧版本浏览器编译你的页面。 

这能让你选择将你的网站更新支持IE8新特点的时机。 


认识文件兼容性模式 

IE8支持几种文件兼容性模式,它们具有不同的特性并影响内容显示的方式。 

•Emulate IE8 mode指示IE使用<!DOCTYPE>指令来决定如何编译内容。Standards mode指令会显示成IE8 Standards mode而quirks mode会显示成IE5 mode。不同于IE8 mode,Emulate IE8 mode重视<!DOCTYPE>指令。 
•Emulate IE7 mode指示IE使用<!DOCTYPE>指令来决定如何编译内容。Standards mode指令会显示成IE7 Standards mode而quirks mode会显示成IE5 mode。不同于IE7 mode,Emulate IE7 mode重视<!DOCTYPE>指令。对于许多网页来说这是最推荐的兼容性模式。 
•IE5 mode 编译内容如同IE7的quirks mode之显示状况,和IE5中显示的非常类似。 
•IE7 mode编译内容如同IE7的standards mode之显示状况,无论网页是否含有<!DOCTYPE>指令。 
•IE8 mode提供对业界标准的最高支持,包含 W3C Cascading Style Sheets Level 2.1 Specification和W3C Selectors API,并有限的支持 W3C Cascading Style Sheets Level 3 Specification (Working Draft)。 
•Edge mode指示IE以目前可用的最高模式显示内容。当使用IE8时其等同于IE8 mode。若(假定)未来放出支持更高兼容性模式的IE,使用Edge mode的页面会使用该版本能支持的最高模式来显示内容。同样的那些页面在使用IE8浏览时仍会照常显示。 

由于edge mode使用该IE版本所能支持的最高模式来显示所浏览的网页内容,建议仅使用于测试页及其他非商用页面。 


指定文件兼容性模式 
要为你的网页指定文件模式,需要在你的网页中使用meta元素放入X-UA-Compatible http-equiv 标头。以下是指定为Emulate IE7 mode 兼容性之范例。 

复制代码
代码如下:

<html> 
<head> 
<!-- Mimic Internet Explorer 7 --> 
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> 
<title>My Web Page</title> 
</head> 
<body> 
<p>Content goes here.</p> 
</body> 
</html> 

其内容随著指定的页面模式而更改,当要模拟IE7时,指定IE=EmulateIE7,指定IE=5, IE=7, 或IE=8来选择其中一种兼容性模式。你也可以指定IE=edge来指示IE8使用它支持的最高模式。 

X-UA-compatible标头没有大小写之分。然而除了title元素及其他的meta元素之外,它必须出现在网页header节其它元素之前的位置, 


设定网站服务器以指定预设兼容性模式 

网站管理员可籍着为网站定义一个自订标头来为他们的网站预设一个特定的文件兼容性模式。这个特定的方法取决于你的网站服务器。举例来说,下列的 web.config文件使Microsoft Internet Information Services (IIS)能定义一个自订标头以自动使用IE7 mode来编译所有网页。 


复制代码
代码如下:

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
<system.webServer> 
<httpProtocol> 
<customHeaders> 
<clear /> 
<add name="X-UA-Compatible" value="IE=EmulateIE7" /> 
</customHeaders> 
</httpProtocol> 
</system.webServer> 
</configuration> 

若你已于网站服务器指定了一个预设的文件兼容性模式,你可以在个别页面上指定不同的文件兼容性模式来盖过它。在网页中指定的模式优先权高于服务器中所指定的模式。 

请查阅你的网站服务器关于指定自订标头的资讯,或看更多资料: 

Implementing the META Switch on Apache 
Implementing the META Switch on IIS 


判定文件兼容性模式 

要判定网页使用IE8浏览时的文件兼容性模式,使用document object(文档对象)的documentMode功能。例如在IE8的网址列输入下列程式码会显示目前页面的文件模式。 

javascript:alert(document.documentMode); 

documentMode功能会回传一个数值对应目前页面的文件兼容性模式,举例来说,若网页指定为支持IE8模式,documentMode便会回传值"8"。 

在IE6引入的compatMode功能不支持在IE8引入的documentMode功能。目前使用compatMode建立的应用程式还能在IE8中作用,但它们必须更新为使用documentMode。 

若你希望使用JavaScript判定一个文件的兼容性模式,引入下面范例的这段程式码可支持旧版本的IE。 



复制代码
代码如下:

engine = null; 
if (window.navigator.appName == "Microsoft Internet Explorer") 

// This is an IE browser. What mode is the engine in? 
if (document.documentMode) // IE8 
engine = document.documentMode; 
else // IE 5-7 

engine = 5; // Assume quirks mode unless proven otherwise 
if (document.compatMode) 

if (document.compatMode == "CSS1Compat") 
engine = 7; // standards mode 


// the engine variable now contains the document compatibility mode. 



认识内容属性值 

内容属性值在接收到异于先前叙述的数值时是具有弹性的。这能使你对于IE如何显示你的网页更有操控性。举例来说,你可以设定内容属性值为IE=7.5。当你这样做的时候,IE尝试将这个值转换为version vector并选择最接近的结果。在这个例子中,IE会将其设定为IE7 mode。下面的范例显示该模式设定为其他值的状况。 



复制代码
代码如下:

<meta http-equiv="X-UA-Compatible" content="IE=4"> <!-- IE5 mode --> 
<meta http-equiv="X-UA-Compatible" content="IE=7.5"> <!-- IE7 mode --> 
<meta http-equiv="X-UA-Compatible" content="IE=100"> <!-- IE8 mode --> 
<meta http-equiv="X-UA-Compatible" content="IE=a"> <!-- IE5 mode --> 

<!-- This header mimics Internet Explorer 7 and uses 
<!DOCTYPE> to determine how to display the Web page --> 
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"> 
注意: 前面的范例显示单独的内容值。实际上IE只会执行网页中第一个X-UA-Compatible标头。 

你也可以使用内容属性来指定复数的文件兼容性模式,这能帮助确保你的网页在未来的浏览器版本都能一致的显示。欲设定复数的文件模式,请设定内容属性以判别你想使用的模式。使用分号来分开各个模式。 

如果一个特定版本的IE支持所要求的兼容性模式多于一种,将�用列于标头内容属性中最高的可用模式。你可以使用这个特性来排除特定的兼容性模式,虽然并不推荐这样做。举例来说,下列标头即会排除IE7 mode。 

<meta http-equiv="X-UA-Compatible" content="IE=5; IE=8" /> 

结论 

兼容性对于网页设计师来说是非常重要的顾虑。虽然最好是可以建立一个完全不需依赖任何网页浏览器特性或功能的网站,有时候这是不可能实现的。文件兼容性模式便能将网页限制在某个特定版本的IE中。 

使用X-UA-Compatible标头来指定你的页面支持的IE版本。使用document.documentMode判定页面的兼容性模式。 

选择支持某个特定版本的IE,你可以确保你的页面在未来的浏览器版本中也能有显示的一致 

【转】一个css中z-index的用法

摘自:http://www.cnblogs.com/gisdream/archive/2010/06/10/1755891.html

CSS教程:彻底掌握Z-index属性

大多数的CSS属性都很容易使用。常常,当您对标记语言的元素使用CSS属性时,产生的结果会随着您刷新页面而立即呈现。而另一些CSS属性,却会有一些复杂,且只能在给定的环境下才会工作。
Z-index属性便属于上面所说的后面的那一组。Z-index无疑的比其他任何属性都会频繁的导致(兼容性)上的混乱和(开发者心理上)的挫败感。但滑稽的是,一旦你真正理解了Z-index,你会发现它却是一个非常容易使用的属性,并且会为解决很多layout方面的挑战提供强有力的帮助。
在这篇文章里,我们会准确的说明究竟什么是Z-index,它为什么会这么不为人所了解,并一起讨论一些关于它的实际使用中的问题。我们同时会描述一些会遇到的浏览器间的差异,那些存在于已有版本的IE及Firefox浏览器中的独特问题。这篇关于Z-index属性的全透视文章将会为那些有着良好基础的开发者在使用Z-index属性时提供强大的自信心及强有力的帮助。
这是什么?
Z-index属性决定了一个HTML元素的层叠级别。元素层叠级别是相对于元素在Z轴上(与X轴Y轴相对照)的位置而言。一个更高的Z-index值意味着这个元素在叠层顺序中会更靠近顶部。这个层叠顺序沿着垂直的线轴被呈现。
为了更清晰的描述Z-index是如何工作的,上面的这张图片夸大展示了层叠元素在视觉位置上的关系。
自然的层叠顺序
在一个HTML页面中,自然的层叠顺序(也就是元素在Z轴上的顺序)是由很多因素决定的。下面的是一个列表,它展示的列表项是处于一个层叠环境(stacking context,暂时未找到合适的汉语翻译,应该是指层叠的元素所处的那个层叠的环境)中,这些项是处于这个层叠环境的底部的。这个列表中的项都没有被赋予Z-index属性。
元素的背景和边框会创建一个stacking context
引用:
・具有负值的stacking contexts元素,按照出现的先后顺序排列(越靠后层级越靠上) 
・没有被定位,没有浮动的块级元素,按照出现的先后顺序排列 
・没有被定位,浮动的元素,按照出现的先后顺序排列 
・内联元素,按照出现的先后顺序排列排列 
・被定位的元素,按照出现的先后顺序排列
Z-index 属性,当被正确使用的时候,会改变自然的层叠顺序。
当然,除非元素已经被定位按照互相交叠的形式展现,否则元素的层叠顺序并不会特别的明显。下面的,负边距的BOX被拿来展示,用以说明自然的层叠顺序。
上面的BOX被定义了不同的背景和边框色,并且后两个是交错的并且定义了负值的顶部边距,所以我们可以看到自然的层叠顺序。灰色的BOX在标记中位于第一位,蓝色的BOX位于第二位,金色的排在第三。应用的负边距明确的表明这个事实:这些元素未被设置Z-index 属性;它们的层叠顺序是自然的,或者是默认的,复合规则的。产生交错的现象都是因为负值的边距。
 
为什么它会产生混乱?
即使Z-index并不是一个难以理解的属性,但它却会因错误的假设而使很多初级的开发人员陷入混乱。混乱发生的原因是因为Z-index只能工作在被明确定义了absolute,fixed或relative 这三个定位属性的元素中。
为了证明Z-index只能工作于被定位了的元素中,这里有同样的三个BOX,它们应用了Z-index属性来尝试打破他们自然的层叠顺序。
灰色的BOX具有“9999”的Z-index值,蓝色的BOX有“500”的Z-index值,金色的有“1”的Z-index值。合乎逻辑的,你会认为这三个BOX的层叠顺序会倒过来。但事实却不是这样,因为这些元素都没被设定position属性。
下面是同样的三个BOX,分别都被设置了position: relative,他们的Z-index值还是按照上面那段设定。
现在的结果是我们所期待的了:这些元素的层叠顺序实现了反向;灰色的BOX覆盖在蓝色之上,蓝色的覆盖在金色之上。
语法

#grey_box {  
    width: 200px;  
    height: 200px;  
    border: solid 1px #ccc;  
    background: #ddd;  
    position: relative;  
    z-index: 9999;  
}  
#blue_box {  
    width: 200px;  
    height: 200px;  
    border: solid 1px #4a7497;  
    background: #8daac3;  
    position: relative;  
    z-index: 500;  
}  
#gold_box {  
    width: 200px;  
    height: 200px;  
    border: solid 1px #8b6125;  
    background: #ba945d;  
    position: relative;  
    z-index: 1;  
}
 
重复一下,Z-index属性只能工作于那些被定义了position属性的元素中。这并没有被足够的重视,尤其是对于那些新手。
 
运用JavaScript
如果你希望通过JavaScript为一个元素动态的加上Z-index 属性,其语法同其他大部分CSS元素能被存取类似,就是使用“驼峰命名法”取代CSS属性中的连字符,就像下面的代码展现的那样。
var myElement = document.getElementById(”gold_box”);  
myElement.style.position = “relative”;  
myElement.style.zIndex = “9999″;
在IE 和 Firefox中的不当解析(兼容性问题)
在某些特定的情况下,关于Z-index 属性的解析会在IE6、IE7以及Firefox2版本中存在一些小小的前后矛盾。
IE中的<select>元素:
IE6中的<select>元素是一个窗口控件,所以它总是出现在层叠顺序的顶部而不会顾及到自然层叠顺序、position属性或者是Z-index。下图展示的就是这个问题。
<select>元素出现在了顶部,它被设置了“相对定位”并且Z-index值为“1”。金色的BOX在这个层叠顺序中排在了第二位,它的Z-index值是“9999”。因为自然层叠顺序及Z-index值的原因,在我们目前所用的所有浏览器中金色的BOX都会排在顶部,但IE6除外。
这个IE6的BUG导致了很多覆盖在<select>元素上的下拉菜单在弹出下拉选项时失败的问题。一个解决办法是使用JavaScript临时隐藏<select>元素,等到下拉菜单的下拉项收回时再将<select>显示出来。其他的办法会涉及到使用<iframe>
IE6/IE7中被定位了的父容器:
因父容器(元素)被定位的缘故,IE6/7会错误的对其stacking context进行重置。为了演示这个多少有些复杂的BUG,我们再一次的放置两个BOX,但这次我们会将第一个BOX放置在一个被定位了的元素里。
灰色BOX的z-index值是“9999”;蓝色BOX的z-index值是“1”,这两个BOX都被设置了position。所以,正确的执行应该是灰色的BOX覆盖在蓝色的之上。
但是在IE6和IE7中,我们却会看到蓝色的BOX处于灰色的之上。这是由灰色BOX外层的父容器也被设置了定位造成的。这两款浏览器错误的将被定位的父容器的stacking context进行了“重置”,但却不应该这样。灰色的BOX拥有一个非常高的Z-index值,它理应因为处在蓝色BOX之上。其他的浏览器对这个问题会进行正确的解析。 
 
Firefox 2中的负值:
在Firefox2版本中,一个负的Z-index值会使元素位于stacking context的后面,而不是位于公认的背景和边框这样的元素stacking context之前。下面的截图展示了这个Firefox 2的BUG。
下面的是上面截图的HTML版本(限于目前博客所限,做不到能够像Smashing Magazine那样的内容部分显示code demo,需要查看原始实例请去原文章查看) ,如果你在Firefox 3或者其他目前正在被使用的浏览器中查看,你会看到正常的解析结果:灰色BOX的背景(元素stacking context的基底)出现在所有实物的下面,并且灰色BOX内部的文字出现在蓝色BOX的上面。
普遍应用的展示
对页面中的元素应用z-index属性可以非常便捷的解决各种各样的layout挑战,同时使得设计者可以在他们的设计中使用层叠的项目进行更多的创造。
交错的滑动门菜单:
一个对这个CSS属性实际应用的案例:CTCOnlineCME 这个网站对“正被点击”的tab使用Z-index属性及清晰交错的PNG图片,创造出非常好的效果。
CSS 气泡:
Z-index 属性还可以用来实现基于CSS的提示气泡,就像下面trentrichardson.com展示的那样
Light Box:
如果不是因为应用了z-index 属性,现在也不会有那么多的品质优秀的Light Box脚本可以免费使用,比如说JQuery的一个插件FancyBox。
Light box 脚本使用半透明的PNG图片来使背景变暗,之后拿来一个新的元素,经常会使用类似窗口的DIV,将之放置在前排。覆盖住屏幕的PNG和之后的DIV都使用Z-index 属性以确保这2个元素会位于页面其他元素之上。
下拉菜单:
类似于Brainjar’s classic Revenge of the Menu Bar的下拉菜单使用Z-index以确保菜单的按钮和他们的下拉项位于层叠的顶部。
画廊效果的图片展示:
将JQuery animation和Z-index组合可以创造出幻灯片或画廊式的卓越效果。usejquery.com 网站中的这个demo向我们展示了这两者的绝妙组合带给我们的惊喜。
Polaroid Photo Gallery by Chris Spooner 采用功能更为强大的CSS3同Z-index配合,创造出了一个当鼠标划过时会重新码放的超cool效果。
Fancy Thumbnail Hover Effect 中Soh Tanaka 使用Query为基础的脚本改变z-index的赋值。
 
Stu Nicholls所做的CSS实验:
Stu Nicholls在他的网站 CSSplay 中阐释了众多的CSS的案例。下面是一些关于z-index属性的作品。
CSS 图片地图
CSS 游戏
CSS模仿框架
增强版的层叠布局:
24 ways 这个网站以Z-index为工具来提升它的模板体验,将年份和日期的长度、宽度延伸到和网站外层容器同等并相互交织,创造出了一个非常有趣的效果。
奇异的网摘栏:
Janko At Warp Speed 这个网站在“奇异的网摘栏”中使用了Z-index。
完美的整页背景图:
Chris Coyier 阐述了这个技术并将之应用到了ringvemedia.com 网站上。在内容容器上应用 z-index 以确保它出现在那个看上去像“背景”其实却不是的图片上。
总结
在CSS中层叠关系是一个复杂的话题。本文并不打算针对这个话题的所有细节进行讨论,而是针对Z-index究竟是如何影响我们网页的层叠顺序进行一次深入的探讨。这里所说的,当被真正的全面理解后,我们会发现这个CSS属性是如此的强大。
初学者现在应该会对这个属性有了非常好的理解,并且会避免很多在对其的使用过程中经常出现的问题。另外,有基础的开发者也会对如何正确使用Z-index来避免很多布局方面的问题有了更为深入的理解,并且为创造出更多的CSS艺术作品打开了大门。

【转】CSS z-index 属性的使用方法和层级树的概念

摘自:http://www.neoease.com/css-z-index-property-and-layering-tree/

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

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

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

目录

顺序规则

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

  <div id="a">A</div>  <div id="b">B</div>

CSS z-index 属性顺序规则的例子

定位规则

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

  <div id="a" style="position:static;">A</div>  <div id="b">B</div>

CSS z-index 属性定位规则的例子, static

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

  <div id="a" style="position:relative;">A</div>  <div id="b">B</div>

CSS z-index 属性定位规则的例子, relative | absolute | fixed

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

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

CSS z-index 属性互相覆盖的例子

上面互相覆盖在什么时候用到这样的实现? 看起来偏门, 其实很常用, 比如说, 电子商务网站侧栏的类目展示列表就可以用这个技巧来实现.

下图是某网站的类目展示区域, 二级类目的悬浮层覆盖一级类目列表外框, 而一级类目的节点覆盖二级类目的悬浮层. 如果使用 CSS 实现展示效果, 一级类目的外框相当于上面例子中的 A, 一级类目的节点相当于 A-1, 二级类目的悬浮层相当于 B.

电子商务网站侧栏的类目展示列表

参与规则

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

  <div id="a" style="z-index:2;">A</div>  <div id="b" style="z-index:1;">B</div>  <div id="c" style="z-index:0;">C</div>

CSS z-index 属性参与规则的例子, 没有明确定位的时候

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>  <div id="b" style="position:relative;z-index:1;">B</div>  <div id="c" style="position:relative;z-index:0;">C</div>

CSS z-index 属性参与规则的例子, 明确定位的节点才能使用 z-index 属性

默认值规则

如果所有节点都定义了 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>

CSS z-index 属性默认值规则的例子

通过检查我们还发现, 当 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>

CSS z-index 属性从父规则的例子, 子节点不设定层级

如果所有节点都定义了 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>

CSS z-index 属性从父规则的例子, 不可逾越的层级

很多人将 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>

CSS z-index 属性层级树规则的例子

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

CSS 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 之前.

CSS z-index 属性参与规则 2 的例子, 所有节点参与层级比较

如果我们将所有父节点的 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, 不参与层级比较.

CSS z-index 属性参与规则 2 的例子, z-index 为 auto 的节点不参与层级比较

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

CSS z-index 属性参与规则 2 的例子, 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 前面.

CSS z-index 属性参与规则 2 的例子, position 为 auto 的节点不参与层级树比较, 但仍参与 DOM 兄弟节点间的层级比较, W3C 浏览器

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

CSS z-index 属性参与规则 2 的例子, position 为 auto 的节点不参与层级树比较, 但仍参与 DOM 兄弟节点间的层级比较, IE6 和 IE7

总结

浏览器节点显示层级是一个费力的活, 今天你觉得 A 区块会永远置顶, 但明天因为需求变动, 突然出现 B 元素需要置顶. 一层一层往上堆砌, 某天回头一看, 发现很多区块交错在一起, 而且他们的值一个比一个大, 根本搞不清头绪. 我觉得在操刀干活之前, 最好先将 position, z-index 和层级的关系搞搞清楚, 以免后患无穷.

另外, 非情非得已, 切勿用 JavaScript 计算 z-index, 并将某个节点的 z-index 设置成所有节点中层级最高.

因为篇幅太长, 本文仅从节点属性角度进行讨论, 没有涉及 select 和 iframe 等特殊页面节点考虑, 如果有机会下次再为大家分享.