重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄, 天天10分鐘,重構你的前端知識體系,筆者主要整理學習過程的一些要點筆記以及感悟,完整的能夠加入winter的專欄學習【原文有winter的語音】,若有侵權請聯繫我,郵箱:kaimo313@foxmail.com。
正常流的排版行爲:依次排列,排不下了換行。
在正常流基礎上,有float
相關規則,使得一些盒佔據了正常流須要的空間,能夠把float
理解爲文字環繞
。
有
vertical-align
相關規則規定了如何在垂直方向對齊盒。基線、文字頂 / 底、行頂 / 底等概念。
一、參考文章: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; }
這樣就能夠獲得咱們想要的效果:測試
在 CSS 標準中,規定了如何排布每個文字或者盒的算法,這個算法依賴一個排版的當前狀態
,CSS 把這個當前狀態稱爲格式化上下文(formatting context)
。
格式化上下文 + 盒 / 文字 = 位置 formatting context + boxes/charater = positions
排版須要分別爲它們規定了塊級格式化上下文和行內級格式化上下文。
一、塊級格式化上下文順次排列元素:spa
二、行內級格式化上下文順次排列元素:
三、正常流中的一個盒或者文字排版,須要分紅三種狀況處理
一、採用百分比寬度解決
<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; }
自適應寬(一個元素固定寬度,另外一個元素填滿父容器剩餘寬度)是個經典的佈局問題。
一、如何使用正常流來解決?
<!-- 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是前端面試題的常客。。。