【正視CSS 06】構建我們自己的世界觀!

來源:互聯網
上載者:User
前言

我們很小的時候什麼都不知道,於是什麼都會是別人對我們解釋,也許是父母,也許是師長,但是隨著年齡的增大,我們會逐步形成自己的世界觀,並且當我們有小孩時候,他會問我們很多問題,我們會為他解答,那麼我們的答案有何而來呢?

我們的答案來自我們自己的世界,來自我們自己形成的世界觀!

我們初學CSS時候什麼也不知道,於是我們從書上、部落格上擷取了很多知識,那麼我們是不是也應該形成自己的世界觀呢?我們碰到的問題是不是都可以用我們形成的世界觀解釋呢?

以上是我最近思考的問題,我覺得我們有必要形成自己的世界觀了,形成世界觀才是長大的標誌,我形成的世界觀可以不堅固,可以很小但是他必須存在,你們的也必須存在。

我們需要捍衛我們的世界觀,我們需要建造我們的世界觀,當我們的世界足夠大,足夠發達的時候,我們就會被稱為高手啦,哇哈哈!!!

師尊,我們的頁面是哪裡來的?

在我們的瀏覽器中輸入了一個url後,我們的伺服器便會返回一堆字串給我們,這個字串就是傳說中html。

從得到html位元組開始,dom樹便開始勾踐了,遇到以下情況時候dom樹的構建會被暫時阻塞:

① 網路卡

② 有未載入的指令碼

③ 樣式還未載入結束就遇到script

dom樹是基礎,dom樹構建結束以後便根據樣式與dom構建我們的渲染樹了,這個時候樣式檔案便會阻塞我們的頁面渲染。

PS:有些網頁會把CSS寫在頁面裡,而不是外部檔案是為了避免頁面閃爍,或者出現裸奔的局面。

當樣式表載入結束後,渲染樹也被構建好了,我們的頁面就基本成型了。

渲染樹一旦構建完成後,若是js指令碼操作dom,就很可能引起頁面迴流,過多的迴流是前端效能的殺手。

瀏覽器下載的順序是由上到下的,渲染順序也是由上到下的,下載樣式表與渲染樹形成是同步完成的

在渲染到頁面某一部分時,上面的所有部分已經下載完成,並且渲染結束(一旦有js引起改變,邊可能引起之前元素髮生迴流)

若是瀏覽器中有多個樣式表,在所有樣式表下載結束後瀏覽器又會將所有的樣式表放到一起重新解析,會對之前的所有元素重新渲染,所以樣式表過多也不是太好的。

PS:我們在做頁面時候要注意頁面的大小開始不宜過大,這樣可以渲染的很快,以消極式載入的方式進行。

以上的邏輯可以分割如下:

① 構建dom樹

② 構建render樹

PS:渲染樹,寫英文為了防止以後被問到不知道是什麼,包含顏色和屬性的矩形塊。

③ 布局render樹,確定每個節點在螢幕上的確切座標,然後開始繪製。

師尊,我們的頁面如何布局呢?

以上為瀏覽器乾的事情,他幹完了就形成了我們所看到的頁面,我們不需要過於關注,但是我們需要關注他的布局。

當渲染樹被建立並添加到樹中,他並沒有位置和大小,計算他位置與大小的過程便是layout或者reflow。

每個渲染對象都有一個layout或者reflow方法,每個渲染對象須有布局的children的layout方法。

每個小變化都可能導致重新布局,瀏覽器使用一個dirty bit系統,一個渲染對象發生變化就會標記他以及他的children胃dirty,就會重新布局之,若是僅僅是其children有問題的話,就只會搞他的children。

全域迴流(reflow)是需要避免的,因為其很耗效能,視窗改變會引起全域迴流是可以理解的,但是改變整個瀏覽器字型大小的事情我們要少做。

渲染一個對象時候,這個元素的尺寸(高度不定)由其parent決定,他又會決定其children對象,children積累高度與margin、padding便為自己的尺寸,總之這個過程中瀏覽器很忙。

瀏覽器在渲染頁面的時候很忙,所以你一個不小心哪裡不如他意了他就會使壞的,所以不要一來就認為瀏覽器有bug,他忙自然關注不了太多。

PS:元素繪製的過程就是講元素壓入堆棧的過程,一個渲染對象的堆棧順序為:背景色->背景圖->border->children->outline。所以我們在寫css時候規則可言參照之

CSS規定所有元素都應該具有盒模型(內容區、padding、border、margin),但是不同元素又有差異:

區塊層級元素——塊級盒模型

行內元素——產生一個或者多個inline boxes ,inline boxes組成line boxes確定其行高

none——不產生盒模型

師尊,什麼是盒模型?

盒模型對我們後面的布局至關重要

瀏覽器要定位元素就必須知道其定位與尺寸,瀏覽器有三種方式布局:

① normal 根據自身和模型大小布局

② float 開始與普通流類似,然後脫離文檔儘可能靠左或者靠右

③ absolute 與dom無關,根據top等決定位置,盒模型決定尺寸

以上三種無論如何都應該有其支點,這個支點就是傳說中的containing block(包含快),也就是元素所處容器,再簡單點就是依賴於其parent了(這塊可能有誤)

前面我們說過,每個元素皆遵循盒模型定理,所以各個元素可以簡單看做一個個盒子,小盒子擺放依賴於大盒子。

① static/relative元素包含快為其父元素的內容區(出去padding部分)

② absolute包含快為最近定位元素(absolute/relative)

③ fixed為根項目(html)

④ float包含快為最近的區塊層級元素

師尊,BFC/IFC又是什嗎?

而在盒子們布局時候為了減除彼此間的影響,便出現了block formatting context(塊級上下文)這種布局特性,我理解為隔開盒子的隔板。

以下行為會產生bfc:

① float不為none

② overflow不為visible

③ display為table-cell,table-caption,inline-block中的任何一個

④ position不為relative和static時

在IE7以下沒有BFC的概念,其為瞭解決的這個問題便提出了haslayout,兩者之間可以畫等號,但是haslayout bug較多,所以IE7以下有很多bug。

相鄰的區塊層級元素之間會發生margin collapse現象,便是外邊距疊加行為。

這個原因便是相鄰且在同一bfc時垂直外邊距疊加行為。

垂直外邊距便會疊加要解決的話,

有兩種方案(不讓其相鄰,處在不同的bfc)可以為外部設定padding屬性將彼此隔開,當然也可以使用overflow觸發器bfc導致其處在不同的bfc,便不會造成疊加

師尊,區塊層級元素又是什嗎?

有了以上知識後,我們再來看看區塊層級元素

區塊層級元素會獨佔一行,在normal中,其排布由其盒模型確定

PS:IE6盒模型解析有誤,需要向下相容需要處理

區塊層級元素為布局大戶,他與position的配合便是布局的瑞士軍刀。

我這裡對absolute布局的區塊層級元素有兩種理解:

1 absolute破壞了元素的高寬,並且將其剝離正常文檔流,而形成了一個會飛的inline-block元素,其初始原點(top/left)與文檔流中正常元素一致,但不會影響其它元素

2 absolute擁有了自己的bfc環境,自成一格與主流bfc分割開後,大小由盒模型確定,位置由top等確定

因為頁面上可能出現多個absolute,所以彼此間的顯示可能出現遮蓋的現象,所以我們有了z-index遮蓋傢伙幫我們幹事。

PS:我猜測,要讓元素靠近我們其實是讓其bfc靠近我們,而ie7以下不存在bfc,取而代之的是haslayout,所以在ie7以下便會有這樣那樣的bug,並且元素需要依賴其父元素的z-index,事實上便是子項目的haslayout需要依賴父元素的haslayout,他這樣的真相便是,標準瀏覽器的bfc是各自獨立的,ie7/6的haslayout是依賴於父元素的(猜測,歡迎拍磚)

行內元素

對於行內元素來說,每個字會形成一個匿名inline boxes,每個行內元素也會有一個inline boxes,一行的inline boxes便會形成一個line boxes,行框決定著這行的高度。

但是,我們這裡的inline boxes幹了什麼事呢?

既然有塊級格式上下文,便會有inline formatting contexts(行內格式化上下文)

ifc中,inline boxes都是水平排列的,起點是其containing block的頭部,

PS:這塊我有所欠缺,後面再補上

inline boxes會撐開line boxes,line boxes才給予了我們一行的高度,所以文字撐不開高度,是inline boxes撐開的高度,最後便是line-height決定高度(若是區塊層級元素的高度未設定)。

float

我們知道float也會建立獨立的bfc,這裡我對他的理解也形成了兩種:

1 float這傢伙破壞了元素的高度,將之變為會左右移動的inline-block,雖然高度不存在了,但是寬度還在,所以其它文本會圍繞之,區塊層級元素(邊框等)卻會覆蓋之。

2 float擁有了自己的bfc了,所以脫離了文檔流,其margin屬性與其它元素無關了(該理念還無法成型,暫時依賴第一個吧)

你的世界觀形成了嗎?

至此,我們便瞭解了css中的很多東西了,我們以此形成了世界觀,於是我們今後需要在此世界中找到所有我們需要的答案,若是找不到就說明這個世界還不夠發達,需要你在建,我們需要維護他,不讓他崩毀,但他若是真的崩毀了也不要緊,因為你在形成的世界會無比的輝煌!!!

好了我們以此世界觀來解釋我們遇到的一些問題:

相容性問題?

其實我們說的相容性問題主要是IE7以下有問題,IE7以下因為不存在BFC而替用了haslayout,所以會有很多bug,針對bug,

高手會避免haslayout產生問題,而一般人會選擇使用hack技術

為什麼會高度坍塌?

因為float破壞了元素的inline boxes,而我們的inline boxes撐開了我們的區塊層級元素,所以不動態指定高度的話,其實不會具有高度的。

如何解決高度坍塌,其原理是什嗎?

clear:我這裡猜測清除浮動強制修複了行內元素的inline boxes,所以元素又能撐開區塊層級元素了(但是我不能證明自己)

overflow:overflow觸發了元素的bfc,讓元素具有獨立的bfc,所以其元素不用坍塌了!以上就是坑爹的!因為我自欺欺人都不行,何況忽悠你們,所以我們這裡換個說法,這裡我想換個思路,我們知道bfc其實就是格式化上下文,說白了他會包裹著我們的元素(我們在IE7中有時候用a標籤類比按鈕,但是沒戲,觸發layout後便可以了,應該就是這個原理),若是我們來看看觸發了bfc的元素,他本來都沒了高度,但是我要包括你,我們不能包裹沒有的東西吧,所以瀏覽器又被迫恢複了其inline boxes。

PS:我第一是確實一時間找不到還有什麼問題可以讓我自說自答了,二來是怕真的出現問題答不起,我好不容易搭建起了的世界就給崩毀了就太傷心啦,所以我暫時不在問自己問題了。

為什麼我在js操作dom的時候風扇會不停的轉?

因為操作dom後可能引起大量迴流reflow,所以頁面又要重新布局,這個過程很耗資源的。

為什麼我們要指定圖片的容器寬度

因為圖片載入後,若是寬度不固定,會撐開他所在頁面,以下部分會發生下層現象,也是一種reflow,(dom構建結束後才載入圖片)

結語

我形成了自己的CSS時間觀了,雖然他還很脆弱,但是我會慢慢建設他,讓我的CSS世界堅固而美麗。

各位,若是你們覺得有什麼不足以及錯誤,請提出哦。

 

相關文章

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.