老生長談的問題了,以前都是看別人的,今天抽空本身總結一下,方便本身複習。
1.flex
html:
<div class="wrap">
<section class="son"></section>
</div>
css:
.wrap {
display:flex;
justify-content: center;
align-items: center;
width: 200px;
height: 200px;
background-color: #ccc;
}
.son {
width: 100px;
height: 30px;
background-color: #d60;
}
效果:
複製代碼
2.absolute+transform
html:
<div class="wrap">
<div class="son"></div>
</div>
css:
.wrap {
width: 200px;
height: 200px;
background-color: #ccc;
position: relative;
}
.son {
width: 100px;
height: 30px;
background-color: #a45;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
效果:
複製代碼
3.absolute+margin
html:
<div class="wrap">
<div class="son"></div>
</div>
css:
.wrap {
width: 200px;
height: 200px;
background-color: #ccc;
position: relative;
}
.son {
width: 100px;
height: 100px;
background-color: #e45;
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px;
margin-left: -50px;
}
效果:
複製代碼
總結一下,爲何優先使用transform,由於margin-left/margin-top涉及迴流和重繪,
left/top/margin 之類的屬性會影響到元素在文檔中的佈局,當對佈局(layout)進行動畫時,該元素的佈局改變可能會影響到其餘元素在文檔中的位置,就致使了全部被影響到的元素都要進行從新佈局,瀏覽器須要爲整個層進行重繪並從新上傳到 GPU,形成了極大的性能開銷。
transform 屬於合成屬性(composite property),對合成屬性進行 transition/animation 動畫將會建立一個合成層(composite layer),這使得被動畫元素在一個獨立的層中進行動畫。一般狀況下,瀏覽器會將一個層的內容先繪製進一個位圖中,而後再做爲紋理(texture)上傳到 GPU,只要該層的內容不發生改變,就不必進行重繪(repaint),瀏覽器會經過從新複合(recomposite)來造成一個新的幀。