margin: 0 auto失效的原因
- 元素沒有寬度
- 元素浮動(dòng)
- 元素絕對(duì)定位(脫離文檔流),注意:
相對(duì)定位不會(huì)失效 - 元素display屬性為table-cell,table-cell元素對(duì)margin無感
使absolute元素的文字內(nèi)容寬度自適應(yīng)
absolute元素寬度高度并不能依據(jù)內(nèi)容自適應(yīng)。在元素只有文字內(nèi)容時(shí)定位元素,發(fā)現(xiàn)出現(xiàn)中文排成了一列而不是一行的問題,可以通過強(qiáng)制文字不換行解決這個(gè)問題。
.text-nowrap{
white-space: nowrap;
}
inline和inline-block元素并排時(shí)存在水平空隙
使用百分比布局時(shí),發(fā)現(xiàn)40%和60%的inline-block元素并不能排列于一行,這是因?yàn)樗鼈冎g存在間隙??梢酝ㄟ^設(shè)置父元素的font-size為0解決問題。
.clear-inline-hspace{
font-size: 0;
}
這些空白間隙實(shí)際上是html標(biāo)簽中的空白符,如果把標(biāo)簽之間的回車換行空格都刪除掉也可以解決問題。
line-height會(huì)影響所有inline-block元素高度
line-height的改變會(huì)造成inline-block元素的高度改變,這可能帶來布局上的問題。所以,在使用許多inline-block元素的復(fù)雜布局中,最好不要先設(shè)置容器的padding和height,應(yīng)該先設(shè)置內(nèi)部高度(可能使用line-height)后再考慮是否使用padding。
margin-top和margin-bottom失效
對(duì)于inline元素而言,設(shè)置margin-top和margin-bottom是無效的。
設(shè)置margin-top導(dǎo)致父元素出現(xiàn)空白的解決方法
在父容器中設(shè)置溢出隱藏
.ofw-hidden{
overflow: hidden;
}
margin和float會(huì)使布局變亂
<style>
.top {
background-color: blue;
}
.bottom {
height: 100px;
background-color: red;
}
p {
float: right;
margin-bottom: 10px;
}
</style>
<div class="top">
top
<p>This is the top content</p>
</div>
<div class="bottom"></div>
結(jié)果:

這是因?yàn)閜浮動(dòng)脫離文檔流,它不會(huì)撐開容器,設(shè)置的margin也無效。
margin重疊
fixed失效問題
- 祖先元素含transform
當(dāng)布局未fixed的元素遇到祖先元素設(shè)置了transform屬性時(shí),但對(duì)于該祖先元素定位,而不是相對(duì)于瀏覽器可視窗口。 - 祖先元素含will-change: transform
情況同transform
負(fù)margin
負(fù)數(shù)margin會(huì)導(dǎo)致子元素超出容器,可能導(dǎo)致布局問題,所以盡量少用負(fù)margin;即使要用,也盡量在容器中使用。
box-sizing
padding+width大于窗口寬度,會(huì)導(dǎo)致空白問題,可以使用box-sizing: border-box快速解決。
flex布局
flex布局會(huì)使元素的高度相同,如果水平并列的元素寬度不同,需要添加一層容器包裹子元素。
頭部fixed的占位問題
如果要自定義實(shí)現(xiàn)position: sticky的頭部導(dǎo)航效果,通過js切換static和absolute,會(huì)導(dǎo)致導(dǎo)航條出現(xiàn)抖動(dòng)問題。一種比較好的方法是使用一個(gè)空白的div進(jìn)行占位,頭部定位保持fixed就可以了。
/**
fixed元素占位
@param {DOM} el fixed元素
@param {String} pos 插入占位元素的位置
*/
function fixFixedSpace (el, pos = 'append') {
const pass = document.createElement('div')
const parent = el.parentNode
pass.cssText = `width: ${pass.offsetWidth}px; height: ${pass.offsetHeight}px;`
if (pos === 'append') {
parent.appendChild(pass)
} else if (pos === 'prev') {
parent.insertBefore(pass, el)
} else if (pos === 'next') {
parent.insertBefore(pass, el.nextSibling)
}
}