從CSS盒模型談起
1. 盒模型Box Model
- 盒模型由外而內是四部分:margin,border,padding,content。
- 盒模型有兩種模型:標準模型和IE模型。
content-box
的寬高指定contentborder-box
的寬高指定border+padding+content的總寬高
/*標準*/
box-sizing: content-box;
/*IE*/
box-sizing: border-box;
2. JS獲取寬高
dom.style.width
只能得內聯樣式getComputedStyle(dom).width
dom.offsetWidth
最常用dom.getBoundingClientRect().width
3. 邊距摺疊問題Collapsing Margins
- 父子或兄弟元素在垂直方向上margin遇見margin,以較大值爲準。
- 毗鄰:沒有padding、border等隔斷
4. 塊級格式下文BFCBlock formatting context
- FC決定子元素如何定位,自身和其他元素的關係和相互作用
- IFC是行內格式化上下文,box一個接一個的水平排列
- BFC是一個獨立的容器,內外元素互不影響
- BFC內部的box一個接一個的垂直放置
- 垂直方向的距離由margin決定,屬於同一個BFC的相鄰元素的margin會重疊
- 不與浮動元素重疊
- 計算BFC高度時,浮動元素也參與計算
- 作用:
- 消除垂直margin摺疊
- 清除浮動
- 創建一個BFC:
position: absolute|fixed;
,display: inline-block;
- 根元素
- 浮動元素(float不是none)
- 絕對定位元素(position:absolute|fixed)
- 非塊級元素具有display: inline-block|table-cell|table-caption|inline-flex;
- 塊級元素具有overflow值非visible
inline-block元素內部是一個BFC,外部呈現爲一個inline元素,可以和其他inline元素一起形成IFC
5. css優先級
!important
- 行內樣式
- id選擇器
- class選擇器
- 標籤選擇器
權重相同時,後者覆蓋前者
一種權重計算規則: 0.0.0.0 依次代表行內、id、class、標籤選擇器
.a.b
和.a .b
和.a,.b
的區別
寫法 | 描述 |
---|---|
.a.b | 同時擁有兩個類名 |
.a,.b | 相當於分別定義樣式 |
.a .b | 父級a下的子級b |
.a | 分別定義 |
.b | 分別定義 |
<div class="a b">
你好|綠色
<div class="a b">你好|紫色</div>
</div>
<style>
/* .a.b 和 .a .b的順序會有影響 */
.a.b{
color: green;
}
.a .b{
color: purple;
}
.a{
color: red;
}
.b{
color: blue;
}
</style>
6. position和display
6.1 position
值 | 描述 |
---|---|
absolute | 絕對定位,相對於static定位以外的第一個父元素進行定位 |
fixed | 固定定位,根據瀏覽器窗口定位 |
relative | 相對定位,相對於元素本來的正常位置進行偏移 |
static | 默認,出現在正常流中,忽略z-index等 |
inherit | 繼承父元素 |
sticky | 粘性定位 |
- z-index屬性,只在定位元素上起作用
- 必須有position不爲static才起作用
- 水平垂直居中,絕對定位+偏移
- 絕對定位:父元素有position(不是static),子元素absolute
6.2 display
值 | 描述 |
---|---|
none | 不顯示 |
block | 塊級元素,前後帶有換行符 |
inline | 默認,行內元素,前後無換行 |
inline-block | 行內塊 |
- 隱藏元素的三種方法
- display: none; 元素不出現文檔流中
- visibility: hidden; 元素不顯示
- opacity: 0; 元素顯示但是透明度爲0
- block和inline的區別
-
display: block;
- 塊級元素會獨佔一行;前後都有換行符
- 塊級元素默認寬度自動填充滿父元素寬度
- 塊級元素可以設置width和height
- 可以設置margin和padding
-
display: inline;
- 行內元素沒有換行符,多個元素排在一行,直到排不下
- 行內元素設置寬高無效
- 行內元素僅支持水平方向的margin和padding,垂直方向無效
-
display: inline-block;
- 對外呈現爲inline;對內作爲block
- 具有block的寬高屬性,又具有inline的同行屬性
- 常見的塊級元素和行內元素
元素 | 標籤 |
---|---|
塊級 | canvas,div,footer,form,h1,li,ol,ul,p,table,audio,hr,aside,header,section |
行內 | i,a,b,br,em,input,textarea,video,button,embed,label,q,strong,span |
7. 迴流reflow和重繪repaint
- 瀏覽器渲染流程
- 講解
- 解析HTML生成DOM樹;CSS生成CSSOM樹
- DOM和CSSOM結合生成渲染書Render tree
- 迴流:計算節點幾何信息
- 重繪:得到節點的絕對像素
- Display:將像素髮送給GPU,展示頁面
- 何時發生迴流重繪:當頁面佈局和幾何信息發生變化
- 添加、刪除、移動可見的DOM
- DOM元素尺寸變化(margin、padding、border、width、height)
- 元素的content變化
- 初始渲染時
- 瀏覽器窗口尺寸變化
- 瀏覽器優化機制
迴流需要大量計算消耗。瀏覽器通過隊列化修改並批量執行來優化
瀏覽器將修改操作放入隊列,直到一定時間或者操作達到一定閾值,才清空隊列
獲取佈局信息的操作時,會強制隊列刷新,這些操作有:
- offsetTop
- scrollLeft
- clientWidth
- getComputedStyle()
- getBoundingClientRect()
- 減少迴流和重繪
let ele = document.getElementById('test');
/*最小化迴流重繪次數*/
ele.style.padding = '5px';
ele.style.border = 'red 1px solid';
/*使用cssText*/
ele.style.cssText += 'padding: 5px;border: 1px red solid;';
/*修改CSS類名*/
ele.className += ' active';
// ele.classList.add("active");
- 批量修改DOM
對DOM做一系列修改的時候,通過以下步驟可以減少迴流重繪次數
- 使元素脫離文檔流
- 修改
- 放回文檔
使脫離文檔流的方法有:
- 浮動
float
- 絕對定位
- 固定定位