標準參考
堆棧級 stack level 概念請參見 CSS 2.1 規範:9.9 Layered presentation 。
'z-index' 特性對 stack level 的影響,請參見 CSS 2.1 規範:9.9.1 Specifying the stack level: the 'z-index' property 。
問題描述
不同瀏覽器中 Flash 與其他元素髮生覆蓋時, Flash 與其他元素的層疊順序有差異。
造成的影響
Flash 被其他元素遮擋,或其他元素被 Flash 遮擋,與期待效果不同。
受影響的瀏覽器
所有瀏覽器 |
---|
問題分析
一般情況下,頁面中會用 OBJECT 與 EMBED 元素來顯示一個 FLASH 動畫。大致代碼如下:
<object type="application/x-shockwave-flash" data="clock.swf
">
<param value="clock.swf
" name="movie"/>
<param value="wmode" name="window"/>
</object>
OBJECT 元素內 PARAM 元素負責爲 Flash 動畫設置相應參數,其中 wmode 參數較爲重要,它決定了 Flash 的渲染方式。
Adobe 公司的 Flash 開發者文檔中有關於 wmode 參數值的詳細說明: Support for WMODE
當 wmode = "transparent" 或 "opaque" 時,Flash 動畫交由頁面渲染引擎負責渲染,此時它在定位流中的位置由 CSS 中的 'z-index' 特性控制。
如果 wmode 沒有設置,他的默認值是 window,這代表 Flash 動畫將在 window 窗口級別渲染,相應元素擁有系統級的窗口句柄,它所在定位流中的 'z-index' 特性將失效,而會處於所有未擁有窗口句柄特性的頁面元素之上,此時用來控制定位流中 Z 軸方向中上下層位置的 'z-index' 特性將會失效。
分析如下代碼:
<body style="margin:40px;">
<object type="application/x-shockwave-flash" data="clock.swf
" style="height:80px; width:80px; position:absolute; top:0; left:0;">
<param value="clock.swf
" name="movie"/>
<param value="wmode" name="window"/>
</object>
<iframe src="http://www.google.com/logos/
" style="width:240px; height:120px;"></iframe>
</body>
頁面中用來播放 Flash 的 OBJECT 元素被設置了絕對定位 position:absolute,使其處於定位流中,'z-index' 特性沒有設置,採用默認值 auto。此時它已不在普通流中佔有位置。
由於其本身已經處於定位流中,頁面中其他元素均處於普通流中,它本身還在窗口級別渲染,其他定位流中元素也無法覆蓋它。因此可以斷定它會遮擋住其後的 IFRAME 元素顯示。
觀看實際情況:
IE6 IE7 IE8 Firefox Safari Opera | Chrome |
---|---|
在 IE6 IE7 IE8 Firefox Safari Opera 瀏覽器中顯示情況均與相關規範吻合。但是 Chrome 中處於普通流中的 IFRAME 元素卻將擁有窗口句柄的定位流中元素覆蓋。
造成這個問題的情況只能有一種,即在 Chrome 中 IFRMAE 元素實際上擁有窗口句柄,雖然這個句柄無法使用 SPY++ 等窗口句柄信息查看工具獲取到。
根據 window 窗口建立的規律,後建立的窗口會擁有更高的堆棧級別,覆蓋於最先建立的窗口上。
我們只需將原始代碼中的 IFRAME 元素放置到 OBJECT 元素之前,使它先被創建,觀察其是否被後創建的 OBJECT 覆蓋,就可以證實這個推測:
<body style="margin:40px;">
<iframe src="http://www.google.com/logos/
" style="width:240px; height:120px;"></iframe>
<object type="application/x-shockwave-flash" data="clock.swf
" style="height:80px; width:80px; position:absolute; top:0; left:0;">
<param value="clock.swf
" name="movie"/>
<param value="wmode" name="window"/>
</object>
</body>
觀看實際情況:
所有瀏覽器 |
---|
根據上表可以看出,實際情況與猜測情況相吻合。
絕對定位元素與 Flash ( wmode = "window" )重疊時,當 'background' 的特性值不是 'transparent' 時, Firefox 中絕對定位元素卻可以遮擋 Flash ,其它瀏覽器都不能遮擋 Flash 。
分析以下代碼:
<!DOCTYPE HTML> <html> <head></head> <body style="margin:40px;"> <object type="application/x-shockwave-flash" data="clock.swf" style="height:80px; width:80px; position:absolute; top:0; left:0;"> <param value="clock.swf" name="movie"/> <param value="wmode" name="window"/> </object> <div style="top:0;position:absolute; left: 0;background: gold;">this is test word this is test word</div> </body> </html>
以上代碼在不同瀏覽器中表現如下:
Firefox | IE6 IE7 IE8 Chrome Safari Opera |
---|---|
絕對定位元素是 iframe 時與 Flash ( wmode = "window" )重疊, IE 和 Chrome 中 iframe 會遮擋 Flash ,而Firefox Safari Opera 中 Flash 會遮擋iframe
分析以下代碼:
<!DOCTYPE HTML> <html> <head></head> <body style="margin:40px;"> <object type="application/x-shockwave-flash" data="clock.swf" style="height:80px; width:80px; position:absolute; top:0; left:0;"> <param value="clock.swf" name="movie"/> <param value="wmode" name="window"/> </object> <iframe src="about:blank" class="cover_iframe" width="200" height="50" frameborder="1" scrolling="no" style="position:absolute; top:0;left:0;"></iframe> </body> </html>
以上代碼在不同瀏覽器中表現如下:
IE Chrome | Firefox Safari Opera |
---|---|
有沒有辦法讓 iframe 元素在所有瀏覽器下都可以遮擋 Flash呢?
分析以下代碼:
<!DOCTYPE HTML> <html> <head></head> <body style="margin:40px;"> <embed type="application/x-shockwave-flash" src="clock.swf" style="height:80px; width:80px; position:absolute; top:0; left:0;" wmode="transparent"> </embed> <iframe src="about:blank" width="200" height="40" frameborder="1" scrolling="no" style="position:absolute;top:0px;left:0px;background: gold;"></iframe> </body> </html>
以上代碼在不同瀏覽器中表現如下:
IE | Firefox Chrome Safari Opera |
---|---|
解決方案
若有頁面需求是要求其他元素遮擋 Flash
- 1.使用 EMBED 引入Flash 。
- 2.wmode的值使用 'transparent' 或 'opaque' 。
- 3.使用的 iframe 需要設置背景色(設置爲白色)。
注意:當wmode的值不是window時,Flash中有可能無法切換輸入法,該問題爲插件問題,期待插件廠商修復。關於 IE 和非IE瀏覽器背景色不同的問題請參見RC3001: IE6 IE7(Q) IE8(Q) 中 IFRAME 元素 'background-color' 特性默認值不是 transparent