CSS float浮動的深入研究、詳解及拓展(一)

來源:互聯網
上載者:User
文章目錄
  • 概念目錄
  • 一、引言
  • 二、浮動的情感化認識
  • 三、浮動的原始意義是什嗎?
  • 四、浮動的本質是什嗎?
本文作者為:張鑫旭 來源於:張鑫旭-鑫空間-鑫生活 網站地址是:http://www.zhangxinxu.com概念目錄
  • 個人感悟之CSS代碼的情感化思維
  • 個人觀點之浮動的意義僅僅是文字環繞顯示而已
  • 個人觀點之浮動的本質是“包裹及破壞”
  • 個人觀點之目前大多數浮動應用都不是浮動應該做的
  • 個人觀點之浮動其實是個魔鬼、混球
一、引言

你我看待事物的方式不同,價值取向也不同,因為我們有著不同的世界觀,價值觀。這種世界觀的差異不僅僅體現在實際的生活中,也反映在代碼上。你我看待代碼的方式,或者說是代碼在我們情感層面的位置是不一樣的,我這裡說的是情感層面,與邏輯無關,與演算法無關(雖然演算法受情感影響)。這種看待代碼的方式是我們在不斷學習與工作的過程中積累出來的,是在潛意識層面逐漸積累起來的,一切悄然而至,不知不覺。當我們積累到一定階段後,會突然發現,關於代碼,我們已經形成了自己的世界觀和屬於自己的準則。回到我剛提到的“情感層面”,這個詞也可以用“感性思維”來代替。通常而言,程式-代碼屬於很理性很邏輯的東西,與感性-情感這類詞搭不上邊,但是CSS例外。CSS也屬於代碼範疇,而且是一種偉大的代碼,其有別於C,JAVA之類程式語言——沒有演算法,沒有複雜的邏輯。於是,CSS有了先天的優勢可以滲入一些感性的情感化的東西。正如我上面提及的,大多數情況下,這種滲入是無意識的(除非有人直接表露——就像我現在所做的),並且是個體差異明顯的(因為是專屬於自己的情感化的東西)。弗洛伊德將人格劃分為無意識、前意識和意識,我發現代碼的情感化思維形成正是走的從無意識到前意識到意識的路線,所以我個人認為:情感化的代碼也屬於人格的一部分。於是,有了“CSS-情感化代碼-人格”這一微妙的關係。

我不清楚他人是如何看待CSS的,CSS的這些屬性在他們心中是個什麼東西,他們到底賦予了多少自身的情感(或人格或品性或特質等)在這些代碼身上,他們是否已經意識到這些CSS屬性身上正一點一點地融入他們情感化的一些東西。但我清楚自己,在這些CSS的屬性身上添加了很多個人的色彩,這種情感化的東西可以說讓我更好的理解CSS,我想這不難理解,舉個例子:假設你將每個CSS屬性看做是你的孩子,每個孩子有著不同的性格,隨著學習你會挖掘到更多的一些性格,這就好比母親看著自己的孩子一點點長大,到了一定的程度就會把自己的孩子的性格摸得一清二楚,管教也就從容了。當然,我並沒有對CSS所有的屬性都有很清晰的情感化的理解,我用CSS才幾年啊,我要學的還有很多。但是,對於CSS中常用的float屬性,我還是有些感覺的,這也是本文的主旨所在。本文將會從我的一些感性的認識的角度講解CSS float屬性。所以,這裡,你會看到別樣的技術文章。

二、浮動的情感化認識

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

三、浮動的原始意義是什嗎?

我們使用float浮動做了很多其本職工作以外的事情,於是我們會混淆,我們會回看不清float真正的面目。浮動真正的意義在哪裡呢?要知道這個問題的答案很簡單,假設現在CSS中沒有浮動(float)屬性,那麼會變成一個什麼樣子。我們會發現,目前流行採用浮動方法實現的無論是分欄布局,還是列表排列我們都可以用其他一些CSS屬性(不考慮table)代替實現,唯一一個實現不了的就是“文字環繞圖片”,我是想不出來能有什麼方法可以讓文字環繞圖片顯示。好,這個替代不了的作用才是float真正的意義所在。此作用類似於word中的版式,很基礎的原始的作用:

例如左邊這張word就含有左浮動屬性(float:left),這才是浮動應該做的事情。這是非常重要的結論,這是深入理解浮動屬性的基礎,我們後面探討的一些浮動相關的問題都可以由這裡引申出來,所以,請記住,浮動出現的意義其實只是用來讓文字環繞圖片而已,僅此而已。而我們目前用浮動實現頁面配置本不是浮動該乾的事情。

四、浮動的本質是什嗎?

我將浮動的本質定義為“包裹與破壞”!

1. 浮動的“包裹性”
先說句您應該沒有見過的結論:撇開浮動的“破壞性”,浮動就是個帶有方位的display:inline-block屬性。

display:inline-block某種意義上的作用就是包裹(wrap),而浮動也有類似的效果。舉個常見例子,或許您有實現寬度自適應按鈕的經驗,實現寬度自適應的關鍵就是要讓按鈕的大小自適應於文字的個數,這就需要按鈕要自動包裹在文字的外面。我們用什麼方法實現呢?一就是display:inline-block;二就是float。例如我們要實現新浪部落格中的“發表文章”之類的寬度自適應按鈕(如):

背景圖片為: 

display:inline-block方法

CSS代碼如下:

.btn1{display:inline-block; background:url(http://www.zhangxinxu.com/study/image/sina_gray_btn.png) no-repeat left top; padding-left:3px; color:#000000; font-size:12px; text-decoration:none;}.btn1 cite{display:block; line-height:26px; padding:0 13px 0 10px; background:url(http://www.zhangxinxu.com/study/image/sina_gray_btn.png) no-repeat right top;}

HTML代碼如下:

<a href="javascript:void(0);" class="btn1"><cite>inline-block方法</cite></a>

結果如:

float:left方法
此方法的CSS代碼與上面的inline-block方法唯一不同之處就在於這裡是float:left;

CSS代碼如下:

.btn1{float:left; background:url(http://www.zhangxinxu.com/study/image/sina_gray_btn.png) no-repeat left top; padding-left:3px; color:#000000; font-size:12px; text-decoration:none;}.btn1 cite{display:block; line-height:26px; padding:0 13px 0 10px; background:url(http://www.zhangxinxu.com/study/image/sina_gray_btn.png) no-repeat right top;}

HTML代碼如下:

<a href="javascript:void(0);" class="btn1"><cite>float方法</cite></a>

結果如:

您可以狠狠地點擊這裡:按鈕寬度自適應demo

上面這個例子旨在說明浮動屬性(無論是左浮動還是右浮動)某種意義上而言與display:inline-block屬性的作用是一模一樣的,所以類似於display:block; float:left;的CSS代碼超過95%的情況是沒有道理的(display:block是多餘的)。然而,float無法等同於display:inline-block,其中原因之一就是浮動的方向性,display:inline-block僅僅一個水平排列方向,就是從左往右,而float可以從右往左排列,這就是兩者的差異。然而,我們又有多少情況需要元素從右往左排列呢?很少,所以,CSS中,沒有浮動這一屬性不是什麼大不了的事情,它其實就那麼回事。

2. 浮動的“破壞性”
浮動可以說是所有CSS屬性中的“破壞之王”。要理解浮動的破壞性,我們要從浮動最原始的意義入手。我在上面把浮動的原始意義用粗斜體表示出來了,就是“只是用來讓文字環繞圖片而已,僅此而已。”

所以,只要您弄明白了為什麼文字會環繞含浮動屬性的圖片,您就會知道我所說的浮動的“破壞性”是什麼意思了。//下面這部分內容是本文核心,多個人觀點,我盡量表述清楚。您若有興趣,可以放慢在這裡的閱讀速度。

先說結論:文字之所以會環繞含有float屬性的圖片時因為浮動破壞了正常的line boxes。

這裡有必要先講講line boxes模型。先看下面一段普通的HTML代碼:

<p>這是一行普通的文字,這裡有個 <em>em</em> 標籤。</p>

這段HTML代碼涉及到4種boxes:
1、首先是p標籤所在的containing box,此box包含了其他的boxes;

2、然後就是inline boxes,如標註,

inline boxes不會讓內容成塊顯示,而是排成一行,如果外部含inline屬性的標籤(span,a,cite等),則屬於inline boxes,如果是個光禿禿的文字,則屬於匿名inline boxes。

3、line boxes,見的標註:

在containing boxes裡,一個一個的inline boxes組成了line boxes。這是浮動影響布局的關鍵box類型,下面會詳細闡述。

4、content area,見標註:

content area 是一種圍繞文字看不見的box。content area的大小與font-size大小相關。

正常的圖文混排
預設情況下,圖片與文字混排應該是這個樣子:圖片與文字基準對齊,圖片與文字在同一行上,如所示:

中,圖片為一個inline boxes,兩邊的文字也是inline boxes。由於line boxes的高度是由其內部最高的inline boxes的高度決定的,所以這裡line boxes的高度就是圖片的高度。此時圖片與文字是同一box類型的元素(都是inline boxes),是在同一行上的,所以,預設狀態下,一張圖片只能與一行文字對齊。而要想讓一張圖片要與多行文字對齊,您唯一能做的就是破壞正常的line boxes模型。

含有浮動屬性的圖片與文字
先看一片添加了float:left樣式後的表現,見:

剛才說過,正常情況下,圖片自身就是個inline boxes,與兩側的文字inline boxes共同組成了line boxes,但是,一旦圖片加入了浮動,情況就完全變了。我認為是浮動徹底破壞了img圖片的inline boxes特性,至少有一點我可以肯定,圖片的inline boxes不存在了,被惡魔附體,變身了,而這個惡魔就是浮動。一旦圖片失去了inline boxes特性就無法與inline boxes的文字排在一行了,其會從line boxes上脫離出來,跟隨自身的方位屬性,靠邊排列。這種狀態跟限制性內切酶起作用幾乎一致,一條基因鏈上(line boxes)有很多的基因(inline boxes),然後限制性內切酶(float)會切除特定的DNA序列,此序列(float元素)就會從基因鏈上脫離出來。

這個從line boxes上脫離的浮動元素其實就是一個軀體,一個空殼子,表象。因為其沒有inline boxes。有人可能會問,沒有inline boxes就沒有唄,有什麼大不了的?非也非也!這個inline boxes很個很重要的概念。我曾在“css行高line-height的一些深入理解及應用”一文中提到過高度的本質,這裡有必要再講一遍。

在目前的CSS的世界中,所有的高度都是有兩個CSS模型產生的,一個是box盒狀模型,對應CSS為”height+padding+margin”,另外一個是line box模型,對應樣式為”line-height”。前者的height屬性分為明顯的height值和隱藏的height值,所謂隱藏的height值是指圖片的高度,一旦載入一張圖片,其內在的height值就會起作用,即使您看不到”height”這個詞。而後者針對於文字等這類inline boxes的元素(圖片也屬於inline boxes,但其height比line-height作用更兇猛,故其inline boxes高度等於其自身高度,對line-height無反應),inline boxes的高度直接受line-height控制(改變line-height文字拉開或重疊就是這個原因),而真正的高度表現則是由每行眾多的inline boxes組成的line boxes(等於內部最高的inline box的高度),而這些line boxes的高度垂直堆疊形成了containing box的高度,也就是我們見到的div或是p標籤之類的高度了。所以,對於line box模型的元素而言,沒有inline boxes,就沒有高度了,而浮動卻恰恰做了這麼齷齪的事情,其直接將元素的inline boxes也破壞了,於是這些元素也就沒有了高度。

我們所處的這個世界時需要壞人來維持平衡的。武俠世界裡不是常有要消滅某個超牛叉的大魔頭時,會有人修鍊魔功與之抗衡嘛。浮動似乎就是這樣的一個角色,在網頁最初的時候就是顯示一些圖片的文字啊什麼的,所需要的布局也就那麼幾個,其中之一就是文字環繞圖片顯示了,可是怎麼實現這樣的效果呢?聰明的CSS開發人員就創造了一個修鍊“魔功”的float屬性,其作用就是破壞line boxes模型好讓文字環繞圖片顯示,最後實現了嗎?確實實現了。還記得我多次說到的浮動的意義嗎——只是用來讓文字環繞圖片而已,而要實現這個就需要用到浮動的“破壞性”。

沿用上面圖片的例子。浮動破壞了圖片的inline box,產生了兩個結果:一是圖片無法與文字同行顯示,脫離了其原來所在的line box鏈;二是沒有了高度(無inline box -> 無line box -> 無高度)。而這些結果恰恰是文字環繞圖片顯示所必須的。

文字環繞圖片顯示的原因
先看下面的flash動畫示範(點擊按鈕開始):
如果沒有顯示flash動畫,可能您看到的不是原出處,請訪問 張鑫旭-鑫空間-鑫生活 http://www.zhangxinxu.com

動畫所示範的關鍵點其實就是上面的一系列分析與講解,即“包裹與破壞”!包裹是讓標籤佔據的空間水平收縮,破壞是破壞的inline box。正如上面講解的,inline boxes是高度形成的基礎,浮動破壞了inline boxes也就沒有高度可言了。真是由於浮動元素沒有了inline boxes,沒有了inline boxes高度,才能讓其他inline boxes元素重新整合,環繞浮動元素排列。

我們現在假設浮動沒有破壞inline boxes,那麼雖然圖片會靠左顯示,但是其會與文字形成新的高度信封(同類彙總),且只能與一行文字形成line box,無法實現文字環繞效果,所以浮動破壞inline boxes是必須的。

我們可以拿浮動元素與絕對位置元素做對比或許可以協助理解。與浮動元素一樣,絕對位置元素也具有“包裹性”,此“包裹性”適用於任何元素。那麼,浮動元素與絕對位置元素的差別在哪裡呢?我覺得最主要的差別在於:絕對位置的元素脫離了文檔流,而浮動元素依舊在文檔流中;而這造成的顯示上的差異就是:同處於文檔流中的文字實體不會與浮動元素重疊,而會與絕對位置元素重疊。這就是文字環繞顯示的重要原因之一:雖然圖片實際佔據的高度為0,但是由於其寬度實體存在(包裹性),同樣是content area 實體的文字不會與之重疊(外部的容器盒子containing box(p,div,ul,li)會重疊),這就好比籃球場上站了個植物人,雖然其幾乎不可能得分,運球之類,但是他的實體在那裡,它可以阻擋同一水平空間上的同一類型的個體(即人)直接穿過去,要通過,得繞道。但是其無法阻擋整個球隊的向前推進。見(firebug顯示):

簡短的小結
雖然嘮嘮叨叨說了這麼多,但是我個人覺得還是沒有講清楚,因為這裡面涉及的東西都是看不見的,很多概念性的抽象的東西,即使我做了動畫,也配了圖,但是還是覺得沒有講得很明白。尤其我所說的浮動元素沒有高度,“你看,那圖片實實在在就在那兒,怎麼沒有高度?沒有高度為什麼文字會繞行?”所以我免不了在實際高度與inline boxes的關係這類概念間折騰,越折騰顯得越亂。不過沒有關係,下面我會根據上面的講解分析浮動元素各種各樣的表現,相信會對浮動的深入理解有更多的協助。本文僅完成了三分之一,內容較多,我要分篇發布。

相關文章

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.