重學前端學習筆記(二十五)--CSS的正常流

筆記說明

重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄, 天天10分鐘,重構你的前端知識體系,筆者主要整理學習過程的一些要點筆記以及感悟,完整的能夠加入winter的專欄學習【原文有winter的語音】,若有侵權請聯繫我,郵箱:kaimo313@foxmail.com。

1、正常流的行爲

正常流的排版行爲:依次排列,排不下了換行。

1.一、float

在正常流基礎上,有 float 相關規則,使得一些盒佔據了正常流須要的空間,能夠把 float 理解爲 文字環繞

文字環繞

1.二、vertical-align

vertical-align 相關規則規定了如何在垂直方向對齊盒。基線、文字頂 / 底、行頂 / 底等概念。

vertical-align

1.三、margin 摺疊

一、參考文章:CSS中margin摺疊問題記錄css

二、塊級格式上下文Block Formatting Context(簡稱 BFC)html

Web頁面的一種佈局方式,通俗點說,也是指頁面上一個渲染區域,裏面的元素按文檔流中的順序垂直排列,而且發生垂直方向上的 margin摺疊,同時這個區域內的元素佈局不會對外面的元素有任何影響。

三、產生一個BFC:當元素知足一下任何一個條件前端

  • float 屬性取值不是 none
  • overflow 屬性取值不是 visible
  • display 的值爲 table-cell, table-caption, inline-block 中的任何一個
  • position 的值不爲 static 或 relative 中的任何一個

四、BFC 內部垂直方向上的 margin摺疊面試

能夠用https://codepen.io/pen/測試:算法

<div id="father">
     <div id="first-child">box1</div>
     <div id="second-child">box2</div>
     <div id="three-child">box3</div>
</div>
*{
     margin: 0;
     padding: 0;
}
#father{
     width: 2000px;
     height: 400px;
     background: #0016d9;
}
#first-child{
     margin-top: 20px;
     background: chocolate;
     width: 60px;
     height: 60px;
}
#second-child{
     background: chartreuse;
     width: 60px;
     height: 60px;
     margin-bottom: 20px;
}
#three-child{
     margin-top:40px;
     background: fuchsia;
     width: 60px;
     height: 60px;
}

這段代碼渲染出來的結果:瀏覽器

例子

能夠看出 box1 距離 body 上邊 20px,而 box2 和 box3 之間距離 40px,就是由於發生了摺疊。body就是一個BFC,裏面元素會發生margin摺疊。佈局

五、摺疊現象去除學習

<!-- 添加一個層級加上overflow: hidden以及float: left -->
<div id="father">
     <div id="first-child">box1</div>
     <div style="overflow: hidden">
          <div id="second-child">box2</div>
     </div>
     <div style="float: left">
          <div id="three-child">box3</div>
     </div>
</div>
/*  添加overflow: hidden; */
#father{
     overflow: hidden;
}

這樣就能夠獲得咱們想要的效果:測試

例子2

2、正常流的原理

在 CSS 標準中,規定了如何排布每個文字或者盒的算法,這個算法依賴一個排版的 當前狀態,CSS 把這個當前狀態稱爲 格式化上下文(formatting context)

2.一、排版過程

格式化上下文 + 盒 / 文字 = 位置

formatting context + boxes/charater = positions

2.二、塊級盒和行內級盒排版

排版須要分別爲它們規定了塊級格式化上下文和行內級格式化上下文。

一、塊級格式化上下文順次排列元素:spa

塊級

二、行內級格式化上下文順次排列元素:

行內級

三、正常流中的一個盒或者文字排版,須要分紅三種狀況處理

  • 當遇到塊級盒:排入塊級格式化上下文。
  • 當遇到行內級盒或者文字:首先嚐試排入行內級格式化上下文,若是排不下,那麼建立一個行盒,先將行盒排版(行盒是塊級,因此到第一種狀況),行盒會建立一個行內級格式化上下文。
  • 遇到 float 盒:把盒的頂部跟當前行內級上下文上邊緣對齊,而後根據 float 的方向把盒的對應邊緣對到塊級格式化上下文的邊緣,以後重排當前行盒。

3、正常流的使用技巧

3.一、等分佈局問題

一、採用百分比寬度解決

<div class="outer">
    <div class="inner"></div>
    <div class="inner"></div>
    <div class="inner"></div>
</div>
.inner {
    width:33.33%;
    height:300px;
    display:inline-block;
    outline:solid 1px blue;
}

二、上面 1 的代碼每一個 div 並不是緊挨,中間有空白,由於爲了代碼格式加入的換行和空格被 HTML 看成空格文本,跟 inline 盒混排了的緣故。

<!-- 去掉空格和換行 -->
<div class="outer"><div class="inner"></div><div class="inner"></div><div class="inner"></div></div>

三、上面 2 的作法影響代碼可讀性

/* 解決方案:設置 outer 中的字號爲 0 */
.inner {
    width:33.33%;
    height:300px;
    display:inline-block;
    outline:solid 1px blue;
    font-size:30px;
}
.outer {
    font-size:0;
}

四、在某些瀏覽器中,由於像素計算精度問題,仍是會出現換行

/*  解決方案:給 outer 添加一個特定寬度 */
.inner {
    width:33.33%;
    height:300px;
    display:inline-block;
    outline:solid 1px blue;
}
.outer {
    width:101px
}

五、這個代碼在某些舊版本瀏覽器中會出現換行

/* 解決方案:給最後一個 div 加上一個負的右 margin */
.outer {
    width:101px
}

.inner {
    width:33.33%;
    height:300px;
    display:inline-block;
    outline:solid 1px blue;
}

.inner:last-child {
    margin-right:-5px;
}

3.二、自適應寬

自適應寬(一個元素固定寬度,另外一個元素填滿父容器剩餘寬度)是個經典的佈局問題。

一、如何使用正常流來解決?

<!-- div.fixed是固定寬度的,須要添加css讓div.auto填滿剩餘寬度 -->
<div class="outer">
    <div class="fixed"></div>
    <div class="auto"></div>
</div>
.fixed {
    width:200px;
}
.fixed, .auto {
    height:300px;
    outline:solid 1px blue;
}

二、利用負 margin

.fixed {
    display:inline-block;
    vertical-align:top;
}
.auto {
    margin-left:-200px;
    width:100%;
    display:inline-block;
    vertical-align:top;
}

這樣作會致使 auto 中的內容位置不對,還須要使用 padding 把內容擠出來,最終完整代碼以下:

.fixed {
    display:inline-block;
    vertical-align:top;
}
/* 給 auto 添加 padding-left 和 box-sizing 兩個屬性 */
.auto {
    margin-left:-200px;
    padding-left:200px;
    box-sizing:border-box;
    width:100%;
    display:inline-block;
    vertical-align:top;
}

我的總結

好像BFC是前端面試題的常客。。。

相關文章
相關標籤/搜索