推薦深入理解css中的position定位和z-index屬性_經驗交流

來源:互聯網
上載者:User
作者:Cutsin
原文地址:http://www.moonless.net/blog/2007/09/csspositionz-index.html

註:本文僅供交流使用,如有不當之處歡迎批評指正,但請註明詳由,謝謝!

由於平時不太用到,所以過去寫css的時候對於position屬性的absolute、relative值理解比較模糊,對於z-index的層疊更是摸不著頭腦,除了理解的因素外,各個瀏覽器的不同解析結果也是一個大問題。今天仔細閱讀了一下css文檔,總算是對盒模型的浮動、定位有了比較深刻的理解。

我們在實踐中很有可能遇到這樣的問題:
1、做一個橫嚮導航,然後滑鼠經過之後出現下拉式功能表,那麼這個下拉式功能表的位置控制就是一個關鍵;
2、我們想在一個正常的頁面配置中放入幾個浮在頁面上的氣泡提示,這時既不想讓氣泡提示破壞正常的文檔布局,又不想氣泡提示的定位在不同的瀏覽器中到處亂飄。
3、當我們在一句正常的文本中插入一個小表徵圖的話,一般會使用標籤,而這時它的垂直置中問題又是讓人困惑,無論你使用html屬性absmiddle、或是使用css屬性vertical-align、抑或是使用父物件的heigh + line-height,在不同的瀏覽器中總會看起來不同。

嗯,上面幾個問題你是否也遇到過呢?如果你至今還沒有一個很好的解決辦法,不妨繼續閱讀此文,或許能對你有所協助:)
我們先看一下position屬性的幾個取值定義:
position: static、absolute、relative

static : 預設值。如果沒有指定position屬性,支援position屬性的html對象都是預設為static,可以這麼理解:把html頁面看作一個文檔流,原始碼中各個標籤的先後位置就是它們所對應的對象的呈現次序,所有取值為static的對象都按照你所編寫的html標籤的順序依次呈現。
如所示,這是一個常見的指定了float:left;的橫嚮導航:
screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" alt="" src="http://lh6.google.com/cutsin/RuUJqZ6TMOI/AAAAAAAABuo/v0kyBUwGxOk/s400/css_position_1.gif" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" border=0>

relative: 相對定位。這個屬性值保持對象所在文檔流中的位置,也就是說它具有和static相同的呈現方式,它同樣佔有在文檔流中的固定位置,後面的對象不會侵佔或覆蓋;與static屬性值不同的是,設定了relative的對象,可以通過top, left, right, bottom屬性設定自己的新顯示位置,這4個屬性的取值是相對於文檔流的前一個對象的,你可以自由設定這4個屬性位移到新的位置而不對文檔流中的其他對象產生任何影響,原來的頁面呈現仍然會我行我素:
screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" alt="" src="http://lh6.google.com/cutsin/RuUJqZ6TMPI/AAAAAAAABuw/OM-PVJXVubU/s400/css_position_2.gif" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" border=0>

absolute: 絕對位置。和relative不同的是,這個屬性值會將當前對象拖出文檔流,後面的對象會佔有原來的位置,也就是說,當前對象的呈現是獨立顯示的,但是它的位置在指定top, left, right, bottom任一屬性之前仍是有繼承性的,這時的4個屬性的取值是相對於瀏覽器的,和文檔流無關了。如果把樣本中的B地區設定為absolute而不指定4個位置屬性,通過設定margin來改變它的相對位置,用這個方法可以解決前面提到的問題2。
screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" alt="" src="http://lh6.google.com/cutsin/RuUJqZ6TMQI/AAAAAAAABu4/vIRRliN-coI/s400/css_position_3.gif" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" border=0>

提示a: 蘇昱的css2.0手冊中提到relative和absolute定位的捲軸區別不是絕對的,至少在firefox、opera和safari中捲軸該出現還是會出現。

提示b: 屬性值為absolute對象的z-index屬性可以設定層疊顯示的次序,它是直接有效;
而屬性值為relative對象的z-index屬性在設定時要小心,把當前對象的z-index設定為-1是不行的,在firefox中它會無法顯示(注意,不是說瀏覽器有誤,而是指如果父物件是根項目body,那麼z-index是無效的,任何z-index設定都不會顯示在根項目之後,除了IE的解析bug,感謝#19提示),必須設定為0以上,我們如果想讓別的對象擋住它,只有將其他對象也設定position為relative,並將z-index屬性取一個比它大的值即可。

上面的表述不知道也許不是很清晰,具體的理解還是要自己親自動手操作一下。

這樣看來,前面的問題就有解了,問題3我們可以根據設計的要求將其設定為相對或絕對位置;
問題1的解決方案也有很多,個人推薦使用有語義的dl, dt, dd來實現,而且這個方法在不同瀏覽器中的表現基本相同(已在ie, firefox, opera, safari中測試),僅在top的屬性上有幾像素的差異,由於時間關係我只能給出自己測試時的代碼以供參考:
screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open(this.src);}" alt="" src="http://lh5.google.com/cutsin/RuUXtJ6TMRI/AAAAAAAABvA/qI7EOQ8e2nU/s800/css_position_4.gif" onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" border=0>
body { color:#fff; font-size:12px; } ul li { float:left; height:30px; background-color:#99CC99; margin:0 10px; padding:0; border:1px solid #c30; width:100px; } ul li div { border:1px solid #f00; background-color:#996666; width:100px; height:100px; position:absolute; margin-top:15px; margin-left:-1px; *margin-left:-79px; } ul li dl, ul li dl dt, ul li dl dd { margin:0; padding:0; } ul li dl dd { border:1px solid #f00; background-color:#996666; width:100px; height:100px; position:absolute; margin-top:11px; *margin-top:10px; margin-left:-1px; } <ul> <li> 標題 - #text 下拉式功能表 - div </li> <li style="position:relative;">列表b</li> <li>列表c</li> <li> <dl> <dt>標題 - dt</dt> <dd>下拉式功能表 - dd</dd> </dl> </li> </ul>
[Ctrl+A 全選 注:如需引入外部Js需重新整理才能執行]
補充一個例子,請在IE和非IE瀏覽器中對比觀看:

<style> .main { width:500px; height:500px; background-color:#9cf; } .layer_a, .layer_b, .layer_c, .layer_d { position:absolute; width:100px; height:60px; } .layer_a { background-color:#69c; } .layer_b { background-color:#369; } .layer_c { background-color:#eee; } .layer_d { background-color:#696; } .brd { border:1px solid #c30; margin:1em; } .block { display:block; } </style> 一段文本一段文本一段文本一段文本一段文本一段文本一段文本 另一段文本另一段文本另一段文本 <p class="brd">第三段不同的文本第三段不同的文本</p> <p class="brd block">第四段指定了block的文本</p> 第四段指定了block的文本 <map class="brd block">第四段指定了block的文本</map> <dd class="brd">第四段指定了block的文本</dd> <li class="brd">第四段指定了block的文本</li>
[Ctrl+A 全選 注:如需引入外部Js需重新整理才能執行]
從這個例子可以看出,IE將一個塊元素絕對位置時,如果父元素是一個區塊層級元素,那麼拖出文檔流之後它仍會繼承原來所在位置的座標;
而非IE瀏覽器的做法是:拖出文檔流之後,直接定位到父元素所在的座標。
  • 相關文章

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.