1. 程式人生 > >CSS定位relative和absolute

CSS定位relative和absolute

一、有話要說

以前寫內容基本上都是:眼睛一亮——喲呵,這個不錯,寫!然後去古人所說的茅房裡蹲會兒,就有寫作的思路了。但是,構思相對/絕對(relative/absolute)定位系列卻有好些時日,考慮到:
1、 瑣碎的俗稱tip的東西不少,如何尋找主線串聯;
2、 不少自己“非主流”的破常規的觀點,如何一句話提煉,如何清晰表述,如何讓人易於理解;
3、 relative/absolute/z-index本身關係曖昧非比尋常,如何有重點的敘述,同時又不扯斷他們之間的牽連;
4、 又要拿一些大網站說事,如何避免可能的無意的言語上的冒犯;
5、 想一個夠淡定同時又很噱頭的題目;//zxx:此項以失敗告終
6、 等等……

現在,終於決定開始敲鍵盤了,長時間的醞釀使得現在胸中有千言萬語想傾吐啊,不急,像《火影》《海賊王》一樣,是個長篇,娓娓道來。

二、必要的題外話

題外話說兩點內容,一是關於觀點與言論,二是關於情感化思維。

觀點與言論

有句話貌似是這麼說的:“我堅決不同意你的觀點,但是我誓死捍衛你說話的權利!”;前段時間回家,在閒聊子女教育問題上(我純聽眾),小舅就反覆強調他的觀點:“你可以義正言辭的當面孩子說:‘你的這種做法我認為是錯誤的!’,但是,你不能強制他按照你的想法來做。”

技術的道路上,似乎有這麼個流程:經驗 → 觀點 → 世界觀。 很多有經驗的開發人員心中(可能無意識的)就形成了一套自己的準則,亦稱技術方面的世界觀。這種世界觀本質上是帶有宗教信仰的氣息的,於是,當相悖的言論、相悖的世界觀出現的時候,如果其不是海納百川版包容與謙遜,所謂不屑,口水仗就會隨之出現。

有著自己的世界觀本身是好的,但是,如果像清朝政府一樣,自我感覺良好,閉關鎖國,對外在事物過分敵對,對自身也是一種限制,難有大成。所以,應該時時刻刻保持謙遜,虛懷若谷地思考接受別人的觀點,方能在技術飛道路上不斷前行,突破一個又一個的瓶頸。這也是我自己經常提醒自己的。

這裡,我是非常歡迎各同行發表您的不同觀點與看法的,尤其有理有據,爭鋒相對的觀點,因為這讓我看到了進步的可能點。為了幫助闡述自己的觀點,本系列中會反覆拿國內的一些大網站說事。我認為發表觀點的權利應該是自由的,我可以很直接毫不掩飾地說:“我認為你這裡的做法是欠妥的,可以改進的!”,這裡我僅僅是從我個人的角度,以我的世界觀來表達我的觀點,僅僅是表達,完全沒有什麼嘲笑、不屑的意思,因為我知道,本身就沒有什麼對錯之分,或許只是大家的出發點,側重點不同而已。優秀的同行往往反而樂於見到真知灼見的觀點,但是,林子大了,什麼樣的鳥都有,有些一直自以為是的人往往會自認為自己小小的自尊被侵犯而惡語相加,或是報以鄙視與嘲諷。要知道,在山頂上的人和山腳下的人眼中,對方都是渺小的;笑是會傳染的,你在笑別人的時候也在被別人笑著;自以為在看畫中人,其實自己也被當作畫中人看著。

文章這東西就跟藝人一樣,要有特色,好比蘇打綠的娘娘聲,春哥的爺們聲。尤其是論述觀點的文章,顯然就要像辯論賽一樣,觀點鮮明,言辭激烈,否則,大家寧可去看鳳姐說英語也不會鳥你寫些什麼東西的。

情感化思維

我在年初的“CSS float浮動的深入研究、詳解及拓展(一)”一文中的引言部分曾闡述過“情感化思維”,認為“程式碼的情感化思維從無意識到前意識到意識”“程式碼的情感化認識滲透著部分人格”,您要是有興趣可以去原文檢視,這裡再補充點我的新認識,情感化思維接近於感性思維,主要有感情傾向和形象化思維組成。這不難理解,舉個2年之後的例子,假設那時我有女朋友了,並同時假設名叫婉兒,然後同事問婉兒,你對小張的情感是?婉兒的回答就會使“喜歡”,這就是“感情傾向”;然後同事又問,小張在你心中形象是?婉兒的回答是“冬日裡的陽光,溫暖的避風港”,這就是形象化思維。

例如浮動(一)中提到的我對浮動的感性化的認識:浮動就是一個變態,魔鬼,自私自利且影響他人的混球。我討厭浮動。

其中,“變態,魔鬼,自私自利且影響他人的混球”屬於形象化思維,“討厭浮動”就屬於感情傾向,合起來就是情感化思維。

我到現在還不清楚,是不是其他人跟我一樣,會很感性的,夾雜著強烈的個人情感和性格特質去看到CSS的一些屬性的。就自己而言,這種情感化的認識有助於理解與使用CSS。所以,本文也將藉助情感化思維分析“position:relative/absolute”屬性的脾氣特性,利弊好壞。

三、absolute屬性的情感化認識

我對position:absolute屬性感性化的認識:absolute是一個善良的有個性的,我行我素、喜歡凌駕一切之上的魔鬼。這傢伙,不喜歡也算不上討厭,但是知道沒事最好少招惹,免有後患。

四、position:absolute與float:left是近親

先給大家講個故事吧。曾經有兩個魔鬼兄弟,一個叫浮動,一個叫絕對定位,它們總是一起在空中飛行戲耍的。但是,不幸的是,有一天,浮動被巨雷擊中,雙翼折損,隕落凡間,好在性命還在,但是,翅膀不在,它只能永遠留在凡間,與芸芸眾生呆在一起。偶然一天,眾生髮現浮動有一種能力,可以讓佈局整齊,有方向性的排列,於是,大肆使用其能力,建房子,造家園。但是,浮動本質上是魔鬼,其破壞性經常讓房子高度塌陷,而飽受眾生詬病。可憐的浮動啊,原本出身的意義就不是來建房子的,卻被眾人誤解與指責。浮動的兄弟絕對定位本應在天空翱翔,但是為了看望其兄弟,也經常去凡間看望。後來,人們發現,絕對定位也有佈局建房子的能力,也想拿來使用。但是,絕對定位不同於浮動,其翅膀尚在,其一個不樂意就可以飛回天空。聰明而狡黠的人們發現了一個可以限制絕對定位的物體,名叫相對定位。於是,什麼時候,人們想利用絕對定位建房子,就使用這個名叫相對定位的東西把他限定住。後來,有一天,人們忍不住心中的疑問,就問絕對定位:“你在天上好好的,為什麼沒事要下來受罪呢?”絕對定位長吁一口氣,道出了浮動就是他那可憐的弟弟的事情。“不會吧!”人們很驚訝,“你們樣貌差異這麼大,跟志玲姐和鳳姐之間的差異有得一拼呢!”“唉”絕對定位又是一聲嘆氣,“被雷擊,翅膀沒了,還毀了容,於是……”絕對定位忍不住抽泣起來。後來,人們逐漸明白,原來絕對定位下凡間幫著建房子都是自願的。果然,後來,一部分人試著不再使用叫做相對定位的東西限制絕對定位,絕對定位也沒有飛向天空……(未完,待續)

故事先說到這兒,正如故事裡提到的,position:absolutefloat:left論長相差別有志玲姐和鳳姐那麼大,但是,卻是近親,細想一下也合情合理,兩者有兩大共性:包裹性,破壞性。

包裹性
包裹性換種說法就是讓元素inline-block化,例如一個div標籤預設寬度是100%顯示的,但是一旦被absolute屬性纏上,則100%預設寬度就會變成自適應內部元素的寬度。哦,舉個例子吧,如下測試程式碼:

CSS部分:

.div { padding:20px; margin-bottom:10px; background-color:#f0f3f9; }
.abs { position:absolute; }

HTML部分:

<div class="div">
    <img src="mm1.jpg" />
    <p>無absolute</p>
</div>
<div class="div abs">
    <img src="mm1.jpg" />
    <p>absolute後</p>
</div>

結果如下圖所示:
absolute的inline-block化

float也是典型的inline-block化元素,這種元素的inline-block化適用於任何水平的標籤。例如平時我們要讓span標籤支援width屬性,可能要設定:

span { display:block; width:100px; }

但是,有float:left/position:absolute撐腰的情況下,display屬性就是多餘的,可以直接回家喝茶了。

span { float:left; width:100px; }
span { position:absolute; width:100px; }

破壞性
論破壞的功力,絕對定位顯然比浮動更甚一籌,但是人們詬病的更多的卻是浮動的破壞性。這不難理解,整天在耳邊飛來飛去的蒼蠅要比不常見的吸血牛虻討厭。眾人已經把浮動當作凡人中的一份子,而對於絕對定位,人們知道,畢竟人家原本隸屬天上,能下凡間來幫忙造房子已經不錯了,沒有必要去苛求指責人家。

浮動與絕對定位與眾生之間的關係

浮動的破壞性在於切斷line box鏈,致使高度塌陷,但由於浮動元素仍在凡間(DOM tree),實體是看得見摸得著的,所以其佔據的實體位置還是在的。而absolute絕對定位不僅讓高度塌陷,又由於從未深入凡間,在凡間沒有他的實體位置,所以寬度也是塌陷的。

由於浮動身處凡間,所以其造成的破壞是可以通過其他手段彌補的;但是,絕對定位不屬於凡間,其破壞無法修復,因為一是孤獨,無人幫忙;二是隻有空氣,怎能修補。

例如下面的測試:
CSS程式碼:

.div { padding:20px; margin:10px 0 0 10px; background-color:#f0f3f9; float:left; }
.abs { position:absolute; }

HTML如下:

<div class="div">
    <img src="mm1.jpg" />
    <p>圖片無absolute</p>
</div>
<div class="div">
    <img class="abs" src="mm1.jpg" />
    <p>圖片absolute後</p>
</div>

結果如下截圖:

absolute屬性致使高寬塌陷

可以看到,圖片應該的position:absolute屬性後,父標籤的高寬都塌陷了,連它的兄弟float都救不了。

五、position:absolute濫用

在我看來,很多網站,position:absolute都有濫用的嫌疑,不僅僅是position:absolute濫用,其lefttop屬性值也濫用,relative屬性值濫用,z-index也濫用。有的屬性濫用就是單純的多些程式碼而已;而有些其實可以不使用的地方也使用的話會給後來的擴充套件和維護造成很大的麻煩的。

relative/absolute/left/top/z-index這5個關係緊密,無論將哪一點都會牽扯到其他。為了避免講述的混亂,我儘量只講某一個。例如,這裡只講absolute屬性。

absolute經常被一些新手拿來大肆建房子做佈局也是可以理解的,貌似什麼時候我看過一篇文章說,absolute屬性的出現本來是想把頁面搞得像photoshop那樣,一個圖層一個圖層覆蓋似的。但是,頁面的發展顯然與這個背道而馳,畢竟頁面是活的。確實,像photoshop,把一個個層搞出來,使用absolute屬性,以及一定座標值就可以定位出來了。不需要考慮什麼間距啊,margin啊,一些IE下亂七八糟的bug啊什麼的,有一了百了的暢快感。尤其對於頁面製作不熟悉的新手,這種絕對定位佈局可謂屢試不爽。

還有時候,遇到有些複雜的佈局,專案經理又催得緊,懶得再去折騰,乾脆,直接,絕對定位,先把效果做出來再說。因為絕對定位畢竟有飛翔的能力,例如想在黃浦江中間建個燈塔,直接告知座標,飛過去,燈塔一插,搞定了,很省事的。

看上去省事,其實是自掘墳墓。所謂“本屬天上人,勿管凡間事”,對於普通的頁面佈局,不到萬不得已不要使用absolute進行定位。

對普通的layout,如果動不動就使用absolute屬性,我個人是比較深惡痛疾的。

首先自己是個流體佈局控,絕對定位這種東西,顯然沒有流動的氣質,尤其拿來定位後(雖然有時候在relative的庇護下也有一定的流動性)。流動性佈局很強調不定寬,不定高,活用標籤自身屬性,順其自然,最少干預。但是由於absolute屬性(尤其是帶有left/top值)的破壞性,會導致高寬塌陷,於是,不得已,需要設定一個高度值(或是足以撐開高度的值),例如新浪微博導航就是絕對定位,於是,導航外標籤必須定高,否則,下面的元素會上來發生重疊:

新浪微博導航外標籤定高
高度禁用後導航重疊

其次,自己是個程式碼控。自己是個有程式碼癖的人,眼中是容不得可以不使用的CSS屬性的。對於absolute佈局,為了修復其破壞造成的後遺症而花費的CSS程式碼開銷在我看來已經超出的容忍的限制。

最後,也是更重要的,就是絕對定位大大降低了頁面的擴充套件性和維護性。其在降低維護性方面的卓越表現不僅僅在於自身,還在於其領導能力(指引領relativez-index製造更加混亂的頁面,這個後面會依次講到)。我想有經驗的頁面重構人員都深有體會,去改之前別人寫的頁面,出現問題的很多時候就是那些不知道為什麼要絕對定位的元素,這些元素就像地雷一樣,總以為安全,放心大膽地往前走,結果,“砰”一聲嗝屁了。覆蓋,重疊,精確調距離,修改之前的高寬引數等,想想都讓人吐槽。最後,越改越混亂。

absolute屬性本來是個好孩子,可做奇兵,頗有妙用。但是,太多人把天上的鳳凰當野雞養,把absolute過多的用於普通佈局,而沉浸其中,不亦樂乎。

其實想想,要求也不能那麼高。畢竟大部分的同行都是做中小站點的,一個頁面壽命短短几個月說不定就要抄底重來。花功夫去折騰擴充套件性,程式碼量什麼的,實在是對不起自己那點可憐的工資,有這點閒功夫還不如去撩撩美女姐姐,泡泡清純小妹呢。所以,淡定,淡定!

不過,一些結論性的話還是要說的:想重構高質量的頁面,少用絕對定位佈局

六、鞋子是用來穿的

又是題外話。對於CSS屬性,如何高效地使用它們,如何使頁面流暢,靈動,又極具擴充套件性和可維護性呢?就是該生下來該幹嘛的就讓他幹嘛。就拿絕對定位舉例,absolute最大最能動的空間是在天空中,不受任何限制的天空,可以自由馳騁,又與世隔絕,不會對凡間造成任何侵擾,頂多遮住點陽光。所以,absolute儘量不要身陷林立的DOM中,尤其是用來做普通的佈局,這可真是拿砍刀削指甲,做著危險的活兒啊。

舉個更容易理解的例子吧。我們都知道鞋子是用來穿的。但是,它還有其他功能,比如說攻擊武器,例如嫌小布什臺上講話語速太快跟不上,聽不懂,你就可以擲出你的飛鞋提醒他降低語速。很顯然,雖然鞋子有做武器這個特殊功能,你是不會去淘寶上買個百八十雙鞋子,專門用來扔人的吧!absolute屬性的使用一個道理。

下集看點

下集內容還是講absolute定位,多例項與實踐。內容大致有:
普通absolute佈局的替代實現方案;
body標籤是absolute自由的海洋;
解析absolute元素margin定位於left/top的恩怨情仇;
absolutereflow迴流及應用;