整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          淺談html元素的float屬性

          web網頁制作的工作中,元素的float屬性非常常用。顧名思義float屬性就是浮動的意思,運用了浮動屬性的元素常稱為浮動元素。我們經常使用元素浮動屬性來控制網頁的結構以及制作一些酷炫的效果。但是這個屬性具有難以把握的特點,下面逐條進行說明:


          a. 運用了這種屬性的元素會對該元素自身的行為和表現有影響;

          b. 對于運用浮動屬性的元素,其父級和兄弟級別的元素會對它產生干擾;

          c. 浮動元素對其包含或者包含它的元素也會有影響。


          對于上面所說的內容我將通過一個在我工作中遇到的問題作為例子進行說明,首先我將所用到的代碼展示如下:



          先直接使用html代碼,其效果就是三行排列的段落;然后再逐行代碼進行渲染,當第一行和第四行CSS代碼渲染完后,我們會發現段落呈橫向排列而且所有的段落不在其父元素.site-nav中。其效果如下圖所示:


          上圖中黃色的部分表示.site-nav的部分,而三個段落都不在其中。從這可以看出使用了浮動元素后元素不會占據文檔流的位置,而且其父元素的高度變為0。對于這樣的狀況,需要清除浮動元素的影響,具體來說就是需要在浮動元素后添加clear:both;屬性來消除其影響。

          文介紹了四種清除浮動的方法,并嘗試解釋其原理。在理解了各種清除浮動的原理之后,你會發現,很多清除浮動的方法本質上其實是一樣的。掌握這些原理,相信你可以根據場景和需求,靈活運用原則發展出不同的清除浮動的方法,而不再死記或拘泥于文中提到的方法。

          為什么要清除浮動

          在講清除浮動的方法之前,我們先來了解一下為什么要清除浮動,清除浮動的目的是什么,即,要解決什么樣的問題。來看一個浮動的例子

          <div class="topDiv">
           <div class="floatDiv">float left</div>
           <div class="textDiv">...</div>
          </div>
          <div class="bottomDiv">...</div>
          

          其樣式為:

          .topDiv {
           width: 500px;
           border: 2px solid black;
          }
          .floatDiv {
           width: 100px;
           height: 100px;
           border: 2px dotted red;
           color: red;
           margin: 4px;
           float: left;
          }
          .bottomDiv {
           width: 500px;
           height: 100px;
           margin: 5px 0;
           border: 2px dotted black;
          }
          .textDiv {
           color: blue;
           border: 2px solid blue;
          }
          

          在chrome中渲染的效果如下圖所示:

          這肯定不是我們想要的渲染效果,它可能存在如下問題:

          1. 文字圍繞浮動元素排版,但我們可能希望文字(.textDiv)排列在浮動元素下方,或者,我們并不希望.textDiv兩邊有浮動元素存在。
          2. 浮動元素排版超出了其父級元素(.topDiv),父元素的高度出現了塌縮,若沒有文字高度的支撐,不考慮邊框,父級元素高度會塌縮成零。
          3. 浮動元素甚至影響到了其父元素的兄弟元素(.bottomDiv)排版。因為浮動元素脫離了文檔流,.bottomDiv在計算元素位置的時候會忽略其影響,緊接著上一個元素的位置繼續排列。

          解決第一個問題,需要清除.textDiv周圍的浮動,而解決第二個問題,因為父元素的兄弟元素位置只受父元素位置的影響,就需要一種方法將父級元素的高度撐起來,將浮動元素包裹在其中,避免浮動元素影響父元素外部的元素排列。

          接下來開始介紹清除浮動的方法。

          清除浮動的方法

          1. 利用clear樣式

          還是開篇的例子,我們給需要清除浮動的元素添加如下樣式:

          .textDiv {
           color: blue;
           border: 2px solid blue;
           clear: left;
          }
          

          清除浮動后的渲染效果如下:

          解釋一下:

          通過上面的樣式,.textDiv告訴瀏覽器,我的左邊不允許有浮動的元素存在,請清除掉我左邊的浮動元素。然而,因為浮動元素(.floatDiv)位置已經確定,瀏覽器在計算.textDiv的位置時,為滿足其需求,將.textDiv渲染在浮動元素下方,保證了.textDiv左邊沒有浮動元素。同時可以看出,父元素的高度也被撐起來了,其兄弟元素的渲染也不再受到浮動的影響,這是因為.textDiv仍然在文檔流中,它必須在父元素的邊界內,父元素只有增加其高度才能達到此目的,可以說是一個意外收獲。(clear的值為both也有相同的效果,通俗理解就是,哪邊不允許有浮動元素,clear就是對應方向的值,兩邊都不允許就是both)

          但是,如果我們把HTML中的.floatDiv和.textDiv交換一下位置呢?

          <div class="topDiv">
           <div class="textDiv">...</div>
           <div class="floatDiv">float left</div>
          </div>
          <div class="bottomDiv">...</div>
          

          無論.textDiv是否應用清除浮動,情況都是下面的樣子:

          .textDiv的位置先確定了,于是浮動元素就緊接著.textDiv下方渲染在父元素的左側。然而,父元素的高度并沒有被撐起來,沒有將浮動影響“內化”,導致浮動影響到了接下來的元素排版。

          看來,為達到撐起父元素高度的目的,使用clear清除浮動的方法還是有適用范圍的。我們需要更加通用和可靠的方法。

          這里澄清一下,單從元素清除浮動的角度,clear完全已經達到了目的,它已經使得.textDiv特定的方向上不再有浮動元素,清除浮動其實僅僅針對需要清除浮動的元素本身而言,只關注自身需求是否達到,和外界沒有什么關系,它不關注浮動是否超出父元素,以及浮動是否影響到后續元素排列。我們只是利用了浮動的一些特性達到某些目的,但這不是清除浮動關心的問題,只不過,相對于清除浮動,我們可能更加關心這些特性能為我們做些什么而已。我的理解是,清除浮動和撐起父元素高度其實是兩個不同的問題,在這里,可以簡單地理解為工具和目的之間的關系,接下來要討論的兩個方法都是在利用清除浮動這個工具在解決問題,它并不是清除浮動這個工具本身。不過,我們經常將兩者混為一談。

          2. 父元素結束標簽之前插入清除浮動的塊級元素

          HTML結構如下,在有浮動的父級元素的末尾插入了一個沒有內容的塊級元素div:

          <div class="topDiv">
           <div class="textDiv">...</div>
           <div class="floatDiv">float left</div>
           <div class="blankDiv"></div>
          </div>
          <div class="bottomDiv">...</div>
          

          應用樣式:

          .topDiv {
           width: 500px;
           border: 2px solid black;
          }
          .floatDiv {
           width: 100px;
           height: 100px;
           border: 2px dotted red;
           color: red;
           margin: 4px;
           float: left;
          }
          .bottomDiv {
           width: 500px;
           height: 100px;
           margin: 5px 0;
           border: 2px dotted black;
          }
          .textDiv {
           color: blue;
           border: 2px solid blue;
          }
          // 區別在這里
          .blankDiv {
           clear: both; // or left
          }
          

          渲染效果如下:

          原理無需多講,和第一個例子里.textDiv應用clear清除浮動,撐起父級元素高度的原理完全一樣。這里強調一點,即,在父級元素末尾添加的元素必須是一個塊級元素,否則無法撐起父級元素高度。

          3. 利用偽元素(clearfix)

          HTML結構如下,為了慣例相符,在.topDiv的div上再添加一個clearfix類,被稱為萬能清除法 after偽類(現在主流方法,推薦使用)

          <div class="topDiv clearfix">
           <div class="textDiv">...</div>
           <div class="floatDiv">float left</div>
          </div>
          <div class="bottomDiv">...</div>
          

          樣式應用如下:

          // 省略基本的樣式
          // 區別在這里
          .clearfix:after {
           content: '.';
           height: 0;
           display: block;
           clear: both;
          }
          

          該樣式在clearfix,即父級元素的最后,添加了一個:after偽元素,通過清除偽元素的浮動,達到撐起父元素高度的目的。注意到該偽元素的display值為block,即,它是一個不可見的塊級元素(有的地方使用table,因為table也是一個塊級元素)。你可能已經意識到,這也只不過是前一種清除浮動方法(添加空白div)的另一種變形,其底層邏輯也是完全一樣的。前面的三種方法,其本質上是一樣的。

          after偽類after IE6,7下不兼容
          zoom 縮放 
           a、觸發 IE下 haslayout,使元素根據自身內容計算寬高。
           b、FF 不支持
          

          所以,一般會加上一段下面的樣式,針對IE6/7

          .clearfix{
           zoom: 1; /*IE6、7*/
           }
          

          4. 利用overflow清除浮動

          首先直觀地看看,overflow是如何清除浮動的。

          HTML結構如下:

          <div class="topDiv">
           <div class="floatDiv">float left</div>
           <div class="textDiv">...</div>
          </div>
          <div class="bottomDiv">...</div>
          

          樣式應用如下:

          .topDiv {
           width: 500px;
           padding: 4px;
           border: 2px solid black;
           // 區別在這里
           overflow: auto;
          }
          .floatDiv {
           width: 100px;
           height: 100px;
           border: 2px dotted red;
           color: red;
           margin: 4px;
           float: left;
          }
          .bottomDiv {
           width: 500px;
           height: 100px;
           margin: 5px 0;
           border: 2px dotted black;
           clear: both;
          }
          .textDiv {
           color: blue;
           border: 2px solid blue;
          }
          

          不應用上面標識出來的CSS時,渲染結果和本文開始的第一個圖形效果相同,應用CSS后的渲染效果如下:

          僅僅只在父級元素上添加了一個值為auto的overflow屬性,父元素的高度立即被撐起,將浮動元素包裹在內。看起來,浮動被清除了,浮動不再會影響到后續元素的渲染(嚴格講,這和清除浮動沒有一點關系,因為不存在哪個元素的浮動被清除,不糾結這個問題)。其實,這里的overflow值,還可以是除了"visible"之外的任何有效值,它們都能達到撐起父元素高度,清除浮動的目的。不過,有的值可能會帶來副作用,比如,scroll值會導致滾動條始終可見,hidden會使得超出邊框部分不可見等。那它們是如何做到浮動清除的呢?

          要講清楚這個解決方案的原理,有一個概念始終是繞不過去,那就是塊格式化上下文(BFC),然而這又是一個非常抽象的概念,如果要清楚地把這個概念講出來,恐怕需要非常大的篇幅,這里僅提及和理解該問題相關的內容。

          這是從MDN上摘下來的BFC定義:

          A block formatting context is a part of a visual CSS rendering of a Web page. It is the region in which the layout of block boxes occurs and in which floats interact with each other.

          翻譯過來就是:塊級格式化上下文是CSS可視化渲染的一部分。它是一塊區域,規定了內部塊盒的渲染方式,以及浮動相互之間的影響關系。

          塊格式化上下文(BFC)有下面幾個特點:

          1. BFC是就像一道屏障,隔離出了BFC內部和外部,內部和外部區域的渲染相互之間不影響。BFC有自己的一套內部子元素渲染的規則,不影響外部渲染,也不受外部渲染影響。
          2. BFC的區域不會和外部浮動盒子的外邊距區域發生疊加。也就是說,外部任何浮動元素區域和BFC區域是涇渭分明的,不可能重疊。
          3. BFC在計算高度的時候,內部浮動元素的高度也要計算在內。也就是說,即使BFC區域內只有一個浮動元素,BFC的高度也不會發生塌縮,高度是大于等于浮動元素的高度的。
          4. HTML結構中,當構建BFC區域的元素緊接著一個浮動盒子時,即,是該浮動盒子的兄弟節點,BFC區域會首先嘗試在浮動盒子的旁邊渲染,但若寬度不夠,就在浮動元素的下方渲染。[看這里]

          有了這幾點,就可以嘗試解釋為什么overflow(值不為visible)可以清除浮動了。

          當元素設置了overflow樣式,且值不為visible時,該元素就建構了一個BFC(哪些情況下,元素可以建構出BFC,可以看查看CSS文檔對BFC的定義)。在我們的例子中,.topDiv因設置了值為auto的overflow樣式,所以該元素建構出一個BFC,按照第三個特點,BFC的高度是要包括浮動元素的,所以.topDiv的高度被撐起來,達到了清除浮動影響的目的。(至于為什么值為visible的overflow不能建構BFC,這個答案給了一個解釋)

          其實,這里overflow的作用就是為了構建一個BFC區域,讓內部浮動的影響都得以“內化”。如果你看了BFC的定義,你會發現,構建一個BFC區域的方法有很多種,overflow只是其中的一種,那在這里,我們是否也可以利用其它的方式構建BFC,且同樣能達到清除浮動的目的呢?

          BFC定義中說,inline-block同樣也能構建BFC,那我們就用該樣式來試試:

          .topDiv {
           width: 500px;
           padding: 4px;
           border: 2px solid black;
           // 區別在這里
           display: inline-block;
          }
          // 其他樣式相同
          

          渲染效果如下:

          效果完全一樣!只要我們理解了原理,就可以靈活演變出不同的清除浮動的方法,而不必死記某種手段。

          當然,要說明的是,在實際項目中選擇采用哪種方式構建BFC是要具體問題具體分析的,因為要考慮到選用的樣式自身的作用和影響。這個例子中,選用inline-block和選用overflow效果完全一樣,沒有看出有什么副作用,但不代表在其他項目中一樣能行得通。甚至對overflow值的選擇也要考慮其表現和影響。在各種構建BFC的方式中,overflow方式可能是外部影響更可控的一種,我猜想這也許就是為什么普遍采用overflow來清除浮動的原因吧。

          到這里,我要分享的清除浮動的方法已經講完了。其實,如果在不同的使用場景下,對這幾個方法進行拆分組合(其實是對底層原理的拆分組合),還可以實現其他形式不同的清除浮動的方法,最重要的還是對底層原理的把握。知其然,亦知其所以然才是最有效的學習方式。


          鏈接文章:

          https://juejin.im/post/59e7190bf265da4307025d91

          https://juejin.im/entry/59377a05b123db006444eb3e

          https://m.html.cn/qa/css3/11033.html

          https://www.jianshu.com/p/5fa383bc1ce2

          、有float屬性的元素會跑

          代碼:<div id="box1"></div>

          <div id="box2"></div>

          <div id="box3"></div>

          CSS:div{ width: 50px; height: 50px; }

          #box1{background: blue; float: left;}

          #box2{ background: red;float: left; }

          #box3{background: black;float: left; }

          在瀏覽器中的樣式:

          從圖中可以看出,div本為塊級標簽,本應各自占一行,但是添加浮動屬性之后,都向左浮動,跑到了一排。

          二、如果上一行沒有float元素,那么float元素是跑不上去的

          代碼:<div id="box1"></div>

          <div id="box2"></div>

          <div id="box3"></div>

          CSS:div{ width: 50px; height: 50px; }

          #box1{background: blue;}

          #box2{ background: red;float: left; }

          #box3{background: black;float: left; }



          從圖中可以看出,div1沒有floa屬性,所以div2不能浮動上去;而div2有浮動屬性,所以div3會浮動上來。

          三、有float屬性的元素是脫離文檔流的,非浮動元素會忽略掉前面的浮動元素

          代碼:<div id="box1"></div>

          <div id="box2"></div>

          <div id="box3"></div>

          CSS:div{ width: 50px; height: 50px; }

          #box1{background: blue;float:left;}

          #box2{ background: red;float: left; }

          #box3{background: black;width:150px;height:100px; }

          在瀏覽器中的樣式:

          從圖中可以看出,div1和div2浮動在文檔之上,div3忽略了div1和div2,div1和div2沒有影響div3的位置。


          主站蜘蛛池模板: 最新中文字幕一区二区乱码| 国产婷婷一区二区三区| 国产一区二区三区日韩精品| 久久精品无码一区二区三区日韩 | 精品无码人妻一区二区三区不卡 | 色久综合网精品一区二区| 亚洲熟妇AV一区二区三区浪潮| 制服美女视频一区| 国产一区二区三区美女| 日韩最新视频一区二区三| 亚洲av无码一区二区三区网站| 国产精品毛片a∨一区二区三区| 国产Av一区二区精品久久| 国产精品一区在线麻豆 | 韩国精品一区二区三区无码视频| 日本在线一区二区| 亚洲AV福利天堂一区二区三| 中文字幕一区二区三区有限公司| 午夜精品一区二区三区在线观看 | 中文字幕无码免费久久9一区9| 日本人真淫视频一区二区三区 | 日韩精品一区二区三区四区| 中文字幕一区二区在线播放| 精品少妇一区二区三区在线| 国产精品无码一区二区在线观一 | 久久精品综合一区二区三区| 一区视频免费观看| 中文字幕乱码一区久久麻豆樱花| 色窝窝无码一区二区三区色欲 | 亚洲欧美国产国产综合一区| AV无码精品一区二区三区宅噜噜| 精品人妻中文av一区二区三区| 日本中文一区二区三区亚洲| 狠狠色婷婷久久一区二区三区| 亚洲线精品一区二区三区| 精品一区二区三区四区电影| 免费无码毛片一区二区APP| 无码人妻品一区二区三区精99 | 97一区二区三区四区久久| 亚洲电影一区二区三区| 国产无线乱码一区二三区 |