css_10 | CSS——讓「盒子」動起來:① 浮動

本文推薦 PC 端閱讀~

本文版權歸 「公衆號 | 前端一萬小時」 全部,未經受權,請勿轉載!
複製代碼

獲取編號.png

css_10
複製代碼

涉及面試題.png

1. 浮動元素有什麼特徵?對父容器、其餘浮動元素、普通元素、文字分別有什麼影響?
2. 清除浮動指什麼?如何清除浮動?兩種以上方法。
複製代碼

前言: 前 10 篇文章,咱們基本上都是在用「理論」學習「理論」,那從這篇開始,咱們試着用「實踐」來學習理論,而後又用於實踐。
一個原則:把代碼拷貝到 JS Bin 上,對照效果搞懂每行代碼的「是什麼」、「爲何」、「怎麼樣」?css



1 爲何須要「浮動」?

假設咱們須要有個東西,而後它的排版不是依照盒模型的定義——從上往下依次排列,而是從左到右這種結構,那麼咱們須要考慮到使用「浮動」。html

例如一個網站的頭部,一部分在左邊,一部分在右邊。首先,「部分」的表示咱們會用 div ,而 div 是塊級元素,按理說它會從上到下,佔據一整行,不可能整列排列。那這個時候咱們就須要「浮動」。前端


2 「浮動」是怎麼用的,有什麼表現效果?

2.1 放不下會換行

一個「浮動盒」會向左或向右移動,直到其外邊(outer edge)捱到包含塊邊沿或者另外一個浮動盒的外邊。若是沒有足夠的水平空間來浮動,它會向下移動,直到空間合適或者不會再出現其它浮動了。面試

🔗源碼及效果展現
htmlapi

<div class="ct">
  <div class="box box1">1</div>
  <div class="box box2">2</div>
  <div class="box box3">3</div>
</div>
複製代碼

css瀏覽器

.ct {
  width: 280px;
  height: 300px;
  border: 1px solid;
  margin: 100px;
}
.box {
  color: #fff;
  width: 100px;
  height: 100px;
  background: red;
  float: left;
/*🚀直接在你須要浮動的元素上加 float 屬性。*/

}
.box1{
  background: blue;
}
.box2{
  background: pink;
}
複製代碼

10-01.png

🆚對比:
🔗源碼及效果展現
cssbash

.ct {
  width: 280px;
  height: 300px;
  border: 1px solid;
  margin: 100px;
}
.box {
  color: #fff;
  width: 100px;
  height: 100px;
  background: red;
  float: right;
}
/*🚀站在瀏覽器的角度看,它會挨着順序依次渲染*/

.box1{
  background: blue;
}
.box2{
  background: pink;
}
複製代碼

10-02.png

2.2 被卡住的狀況

🔗源碼及效果展現
htmlide

<body>
<div class="ct">
  <div class="box box1">1</div>
  <div class="box box2">2</div>
  <div class="box box3">3</div>
</div>
</body>
複製代碼

css佈局

.ct {
  width: 280px;
  height: 300px;
  border: 1px solid;
  margin: 100px;
}
.box {
  color: #fff;
  width: 100px;
  height: 100px;
  background: red;
  float: left;
}
.box1{
  background: blue;
  height: 120px;
}
.box2{
  background: pink;
}

/*依然站在瀏覽器的角度,從上往下渲染文檔, 當依次渲染完 一、2 後,渲染 3 的時候,右邊放不下, 而後它要被擠下去,擠下去後它貼着 2 的下邊緣開始向左移動, 當移動碰到 1 右下角時,動不了了,1 被卡住了。 因此咱們在設置高度不同時,會出現一個「卡住」的問題。*/
複製代碼

10-03.png

2.3 當浮動元素與文本有交集的時候

🔗源碼及效果展現
html學習

<body>
<div class="ct">
  <div class="box box1">1</div>
  <p>捱到包含塊邊沿或者另外一個浮動盒的外邊。
若是存在行盒,浮動盒的外 top (邊)會與當前行盒的 top (邊)對齊。
若是沒有足夠的水平空間來浮動,它會向下移動,直到空間合適或者不會再出現其餘浮動了。
  </p>
  <div class="box box2">2</div>
  <div class="box box3">3</div>
</div>
</body>
複製代碼

css

.ct {
  width: 280px;
  height: 300px;
  border: 1px solid;
  margin: 100px;
}
.box {
  color: #fff;
  width: 100px;
  height: 100px;
  background: red;
  float: left;
}
.box1 {
  background: blue;
  width: 140px;
  height: 120px;
}
.box2 {
  background: pink;
}
複製代碼

10-04.png

🏆能夠獲得:
普通流中的一個元素,若是沒有設置定位和浮動,那它和浮動元素在一塊兒以後,它會被浮動元素所遮擋。

💡進一步驗證:
🔗源碼及效果展現
css

.ct {
  width: 280px;
  height: 300px;
  border: 1px solid;
  margin: 100px;
}
.box {
  width: 100px;
  height: 100px;
  background: red;
  float: left;
}
.box1 {
  background: blue;
  height: 120px;
  width: 140px;
  opacity: 0.2;  /*🚀設置透明度來觀察*/
}
.box2 {
  background: pink;
}

/*🚀但裏邊的文字並無被這個浮動元素所遮擋,那他呈現的這個效果是: 這個段落 p 是看不到這個浮動元素的,而文字看獲得,而且圍繞這個浮動元素排列。 */
/*🚀即展示出來的一個規則就是: 當一個普通元素碰到一個浮動元素後,這個普通元素看不見這個浮動元素, 但普通元素裏邊的文字看得見這個浮動元素。 */
複製代碼

10-05.png

2.4 浮動元素脫離了普通流

脫離普通流是指:他的父容器在去計算寬高的時候,發現不了浮動元素。即,父容器不會被裏面的浮動元素撐開;

⚠️注意:和 absolute 不同。

🔗源碼及效果展現
html

<div class="ct">
  <div class="box box1">1</div>
  <div class="box box2">2塊盒看不見浮動的 box1,但我是文本我能看見</div>
  <div class="box box3">3</div>
</div>
複製代碼

css

.ct {
  width: 280px;
  height: 300px;
  border: 1px solid;
  margin: 100px;
}
.box {
  color: #fff;
  width: 100px;
  height: 100px;
  background: red;
}
.box1 {
  background: blue;
  float: left;
  opacity: 0.6;
}
.box2 {
  background: pink;
  height: 110px;
  width: 110px;    
}
複製代碼

10-06.png

2.5 塊級元素浮動寬度收縮,行內元素浮動以塊級特性去呈現

🔗源碼及效果展現
html

<body>
<div class="box">這是div</div>
<span>這是span</span>
</body>
複製代碼

css

.box {
  color: #fff;
  float: left;
  background: red;
}
span {
  color: #fff;
  float: left;
  background: blue;
  width: 100px;
  height: 50px;
  margin: 10px;
} 

/*🚀塊級元素設置浮動以後,它就呈現出 inline-block 這種感受,他的寬度會收縮。*/
/*🚀行內元素設置爲浮動以後,它就呈現了塊級的特性, 也有 inline-block 的感受,就把行內元素變成能夠設置寬高、margin 等, 但沒有居中這些東西。 */
複製代碼

10-07.png


3 「浮動」的使用場景

3.1 兩欄佈局(左側固定寬度,右側自適應; 右側固定寬度,左側自適應)

🔗源碼及效果展現——左側固定寬度,右側自適應
html

<div class="aside">側邊欄固定寬度</div>
<div class="main">內容區塊自適應寬度</div>
複製代碼

css

.aside {
  color: #fff;
  width: 150px;
  height: 400px;
  background: red;
  float: left;
}
.main {
  color: #fff;
  margin-left: 160px;
/*🚀表示左邊的這 160px 的範圍我不用了*/

  background: blue;
  height: 500px;
}
複製代碼

10-08.png

🆚對比(右側固定寬度,左側自適應):
🔗源碼及效果展現
html

<div class="aside">側邊欄固定寬度</div>
<div class="main">內容區塊自適應寬度</div>
複製代碼

css

.aside {
  color: #fff;
  width: 150px;
  height: 400px;
  background: red;
  float: right;
}
.main {
  color: #fff;
  margin-right: 160px;
/*🚀表示右邊的這 160px 的範圍我不用了*/

  background: blue;
  height: 500px;
}
複製代碼

10-09.png

3.2 三欄佈局——兩側寬度固定,中間自適應(注意 HTML 中的 menu aside main 的順序!)

🔗源碼及效果展現
html

<div class="menu">側邊欄固定寬度</div>
<div class="aside">側邊欄固定寬度</div>
<div class="main">內容區塊自適應寬度</div>
複製代碼

css

.menu {
  color: #fff;
  width: 150px;
  height: 400px;
  background: red;

  float: left;
}
.asidecolor: #fff;
  width: 150px;
  height: 400px;
  background: red;

  float: right;
}
.main {
  color: #fff;
  margin-right: 160px;
  margin-left: 160px;
/*🚀加左右 margin 就把位置撐開了*/

  background: blue;
  height: 500px;
}
複製代碼

10-10-01.png

⚠️若是 HTML 中的 menu aside main 的順序變了:
🔗源碼及效果展現
html

<div class="menu">側邊欄固定寬度</div>
<div class="main">內容區塊自適應寬度</div>
<div class="aside">側邊欄固定寬度</div>

<!--順序一旦變了,後邊的 aside 就會跳行,跑到下邊去了。 緣由:假設我是瀏覽器,我須要對着 html 來畫出對應的圖像, 首先畫 menu ,結合其樣式,左浮; 但這裏咱們遇到了 main ,這個 main 是一個塊級元素,它會佔據一整行的寬度; 那接下來的 aside 就只有在 main 的基礎上往右下流動。-->
複製代碼

css

.menu {
  color: #fff;
  width: 150px;
  height: 400px;
  background: red;
  float: left;
}
.asidecolor: #fff;
  width: 150px;
  height: 400px;
  background: red;
  float: right;
}

.main {
  color: #fff;
  margin-right: 160px;
  margin-left: 160px;
/*加左右 margin 就把位置撐開了*/

  background: blue;
  height: 500px;
}
複製代碼

10-10-02.png

3.3 利用浮動實現「導航條」

3.3.1 「導航條」靠左

🔗源碼及效果展現
html

<ul class="navbar">
  <li><a href="#">1首頁</a></li>
  <li><a href="#">2產品</a></li>
  <li><a href="#">3服務</a></li>
  <li><a href="#">4關於</a></li>
</ul>
複製代碼

css

.navbar {
  list-style: none;
}
.navbar>li {
  float: left;
  margin-left: 15px;
}

/*🚀固然咱們用 inline-block 也能夠實現效果, 但不一樣方式須要注意的問題不同: 使用浮動咱們須要注意撐開容器;而用 inline-block 咱們須要注意它的縫隙。 */
複製代碼

10-12.png

3.3.2 「導航條」靠右

🔗源碼及效果展現
html

<body>
<ul class="navbar">
  <li><a href="#">1首頁</a></li>
  <li><a href="#">2產品</a></li>
  <li><a href="#">3服務</a></li>
  <li><a href="#">4關於</a></li>
</ul>
</body>
複製代碼

css

.navbar {
  float: right;
/*🚀把 ul 總體進行右浮動*/

  list-style: none;
}
.navbar>li {
  float: left;
/*🚀但 ul 裏邊的東西都是靠左的*/

  margin-left: 15px;
}
複製代碼

10-13.png

🆚對比:
🔗源碼及效果展現
html

<ul class="navbar">
  <li><a href="#">1首頁</a></li>
  <li><a href="#">2產品</a></li>
  <li><a href="#">3服務</a></li>
  <li><a href="#">4關於</a></li>
</ul>
複製代碼

css

.navbar {
  list-style: none;
}
.navbar>li {
  float: right;
/*🚀直接改這裏是不行的,由於站在瀏覽器的立場是按文檔順序來渲染的*/

  margin-left: 15px;
}
複製代碼

10-14.png


4 清除「浮動」

4.1 爲何要清除浮動?

由於任何東西有利有弊。

4.1.1 第一,浮動對後續元素位置產生影響(渲染時,由於塊元素看不見,但裏邊的文字看的見)

🔗源碼及效果展現
html

<div id="content">
  <div class="menu">側邊欄固定寬度</div>
  <div class="aside">側邊欄固定寬度</div>
  <div class="main">內容區塊自適應寬度</div>
</div>
<div id="footer">我是 footer,但個人樣式出現了問題</div>
複製代碼

css

.menu {
  color: #fff;
  width: 150px;
  height: 300px;
  background: red;
  float: left;
}
.asidecolor: #fff;
  width: 150px;
  height: 300px;
  background: red;
  float: right;
}
.main {
  color: #fff;
  margin-right: 160px;
  margin-left: 160px;
  background: blue;
  height: 200px;
}
#footer {
  color: #fff;
  background: grey;
}
複製代碼

10-15.png

10-16.png

4.1.2 第二,父容器高度計算出現問題

🔗源碼及效果展現
html

<ul class="navbar">
  <li><a href="#">1首頁</a></li>
  <li><a href="#">2產品</a></li>
  <li><a href="#">3服務</a></li>
  <li><a href="#">4關於</a></li>
</ul>
複製代碼

css

.navbar {
  list-style: none;
  border: 1px solid #ccc;
  /*加一個背景色也沒效果:   background: pink;*/

}
.navbar>li {
  float: left;
  margin-left: 15px;
}


/*🚀因爲浮動元素脫離了文檔流,因此他的父元素是看不見他的。 這裏對於 navbar 來講,他認爲裏邊沒有什麼 li 來把它撐開, 由於 li 已經浮動了,那沒有東西撐開它,它就會認爲高度爲 0。*/
複製代碼

10-17.png

4.2 清除浮動的方法

4.2.1 清除浮動實現的原理和方法

🔗源碼及效果展現
html

<ul class="navbar">
  <li><a href="#">1首頁</a></li>
  <li><a href="#">2產品</a></li>
  <li><a href="#">3服務</a></li>
  <li><a href="#">4關於</a></li>

  <li class="clear"></li>
<!-- 🚀想解決這個沒辦法撐開的問題, 那麼就要求這個源文檔中要有一個沒有被浮動的的元素——普通元素。--> 

</ul>
複製代碼

css

.navbar {
  list-style: none;
  border: 1px solid #ccc;
}
.navbar>li {
  float: left;
  margin-left: 15px;
}

.navbar .clear {
  float: none;
  clear: left;
}
/*🚀經過清除浮動來得到一個普通元素,進而撐開這個父容器*/
複製代碼

10-18.png

  • 清除浮動 clear: left; ——這個 clear 能夠用在任何元素上,無論你是否是浮動元素。要求該盒的 top 、border 邊位於源文檔(就是 html 文檔結構中)中在此以前的元素造成的全部左浮動盒的 bottom 外邊下方(若是沒有左浮動盒,那你清除左浮動也就沒有意義)。
  • 清除浮動 clear: right; ——要求該盒的 top border 邊位於源文檔中在此以前的元素造成的全部右浮動盒的 bottom 外邊下方。
  • 清除浮動 clear: both; ——只要源文檔中該盒前邊有浮動元素,那麼就在這個浮動元素下方。

1. 🆚對比

咱們上邊是用一個造了一個 li 來實體化普通元素,那咱們能否有更簡化的方法——僞元素(僞元素的一個做用就是去代替標籤)。
🔗源碼及效果展現
html

<ul class="navbar">
  <li><a href="#">1首頁</a></li>
  <li><a href="#">2產品</a></li>
  <li><a href="#">3服務</a></li>
  <li><a href="#">4關於</a></li>
</ul>
複製代碼

css

.navbar {
  list-style: none;
  border: 1px solid #ccc;
}
.navbar>li {
  float: left;
  margin-left: 15px;
}

.navbar::after {
  content: '';
/*🚀寫了一個元素,你必需要有 content */

  display: block;
/*🚀注意這裏若是沒有這個 block ,是不會生效的, 由於寫了 after ,只是表示是一個匿名的行盒,即一個字符串。 然而他必須是塊級元素,他纔會下去。*/

  clear: both;
}
/*🚀用僞元素這樣寫就是表示: 我在源文檔 navbar 的最後生成了一個 block 元素, 而後清除浮動,他就會位於浮動盒子的下方, 進而撐開了 navbar 這個父容器。*/
複製代碼

10-19.png

2. 🆚再對比

🔗源碼及效果展現
爲了通用性,咱們經常 .clearfix::after; ——就是爲了修復浮動所產生的問題。
html

<ul class="navbar clearfix">
<!--🚀凡是須要清除浮動的地方咱們均可以加一個這個樣式就能夠通用-->

  <li><a href="#">1首頁</a></li>
  <li><a href="#">2產品</a></li>
  <li><a href="#">3服務</a></li>
  <li><a href="#">4關於</a></li>
</ul>
複製代碼

css

.navbar {
  list-style: none;
  border: 1px solid #ccc;
}
.navbar>li {
  float: left;
  margin-left: 15px;
}

.clearfix::after {
/*🚀爲了通用性,咱們直接 clearfix ,而後在 HTML 文檔中, 哪裏須要清除浮動,就直接加一個這個類名進去就能夠了。*/

  content: '';
  display: block;
  clear: both;
}
複製代碼

4.2.2 解決上邊由「浮動」帶來的問題

🔗源碼及效果展現
html

<div id="content" class="clearfix">
<!--🚀意思就是:這三個元素下邊還有一個元素, 而後這個元素會在這三個元素的下方,進而就會撐開這個 content 。-->

  <div class="menu">側邊欄固定寬度</div>
  <div class="aside">側邊欄固定寬度</div>
  <div class="main">內容區塊自適應寬度</div>
</div>
<div id="footer">我是 footer,但個人樣式出現了問題</div>
複製代碼

css

.menu {
  color: #fff;
  width: 150px;
  height: 300px;
  background: red;
  float: left;
}
.asidecolor: #fff;
  width: 150px;
  height: 300px;
  background: red;
  float: right;
}
.main {
  color: #fff;
  margin-right: 160px;
  margin-left: 160px;
  background: blue;
  height: 200px;
}
#footer {
  color: #fff;
  background: grey;
}


.clearfix::after {
/*🚀爲了通用性,咱們直接 clearfix , 而後在 HTML 文檔中,哪裏須要清除浮動,就直接加一個這個類名進去就能夠了。*/

  content: '';
  display: block;
  clear: both;
}
複製代碼

10-20.png

🏆小總結:
因此之後咱們想去實現一個水平佈局,就有了兩種方法:

  • 第一,inline-block——不須要清除浮動,簡單,在設置居中時更方便,適合子內容很少的元素水平排列。但要注意縫隙問題,以及對齊(上對齊);
  • 第二,float——沒縫隙問題,適合稍大的佈局。但須要解決的問題是父元素不會被撐開而致使的不少問題。

5 浮動和負 margin

兩個浮動元素,若是因放不下致使其中一個下移,對下移的元素設置負 margin 值大於自身的寬度可將其上移。
🔗源碼及效果展現
html

<div class="container">
  <div class="box box1">box1</div>
  <div class="box box2">box2</div>
</div>
複製代碼

css

* {
  margin: 0
}
.container {
  width: 400px;
  height: 400px;
  border: 1px solid red;
}
.box1 {
  width: 300px;
  height: 100px;
  background: pink;
  float: left;
}
.box2 {
  width: 110px;
  height: 100px;
  background-color: red;
  float: left;

  margin-left: -10px;  
/*🚀瀏覽器計算的時候就至關於寬度減去這個 10 ,而後就是 100,那就正好放上去。*/ 
}
複製代碼


後記: 下篇咱們將討論與「浮動」對應的「定位」是怎樣讓「盒子」動起來的。後續文章都是重中之重,每一篇都乾貨滿滿!

祝好,qdywxs ♥ you!

相關文章
相關標籤/搜索