我一直以為inline-block是一個(gè)很簡(jiǎn)單的屬性,把inline元素設(shè)置為display:inline-block,就能得到一個(gè)可以設(shè)置寬高剪决、有block特性的的inline元素次员;或者把block元素設(shè)置為display:inline-block,就能得到一個(gè)可以在行內(nèi)顯示的block元素割笙。
但其實(shí)权烧,inline-block是一個(gè)非常復(fù)雜的屬性,它與line-height、vertical-align密不可分伤溉,并且存在著兩個(gè)很大的問題——間隙和居中般码。這篇博客主要對(duì)這兩個(gè)問題進(jìn)行整理并描述了inline-block的幾個(gè)應(yīng)用場(chǎng)景。
文章結(jié)構(gòu):
-
inline-block的問題
- 關(guān)于間隙
- 關(guān)于對(duì)齊
-
inline-block的應(yīng)用場(chǎng)景
- inline-block包住浮動(dòng)元素
- inline-block實(shí)現(xiàn)水平垂直居中
一乱顾、inline-block的問題
1板祝、關(guān)于間隙
首先我們來看inline元素,舉一個(gè)非常簡(jiǎn)單的例子走净。
// html
<body>
<span>1</span>
<span>2</span>
</body>
結(jié)果是什么券时?
選項(xiàng)A:12
選項(xiàng)B:1 2
為了方便觀察,我們給span加上border:
// css
span{
border:1px solid;
}
結(jié)果:
我們看到伏伯,1和2之間是有空隙的橘洞,所以上面應(yīng)該選“B”。
inline-block是一種特殊的inline元素说搅,那如果我把上面的span設(shè)置為inline-block炸枣,結(jié)果又是什么樣的呢?
// css
span{
display:inline-block;
border:1px solid;
}
結(jié)果:
我們看到,與上面的結(jié)果幾乎一模一樣(不一樣的地方在于設(shè)置為inline-block時(shí)邊框要高一些适肠,這是由line-height決定的)霍衫,都有空隙。造成空隙的原因是兩個(gè)inline/inline-block元素之間有空格/回車侯养。去掉這個(gè)回車即可消除空隙敦跌。
// html
<body>
<span>1</span><span>2</span>
</body>
結(jié)果:
但是你總不能永遠(yuǎn)不寫空格、回車吧逛揩?
還有一種方法柠傍,設(shè)置父元素的font-size為0(這樣空格/回車的font-size也為0),再設(shè)置span的font-size為 'xx'px即可辩稽,代碼如下:
<body>
<div>
<span>1</span>
<span>2</span>
</div>
</body>
div{
border:1px solid red;
font-size:0;
}
span{
font-size:16px;
display:inline-block;
border:1px solid;
}
但是這樣是很麻煩并且容易出錯(cuò)的携兵,所以這種方法也不建議使用!
在實(shí)際工作中搂誉,建議使用block/float/flex徐紧,棄用inline-block。block/float/flex均可消除這個(gè)間隙炭懊。
2并级、關(guān)于對(duì)齊
你可能不理解我這里的“關(guān)于對(duì)齊”是什么意思。同樣侮腹,我們來看代碼:
// html
<div>
<span class='s1'>
1
<span class='s2'>
2
</span>
</div>
// css
div{
border:1px solid red;
}
span{
display:inline-block;
border:1px solid;
}
.s1{
width:100px;
height:200px;
}
.s2{
width:200px;
height:300px;
}
結(jié)果:
除了上面討論過的空隙問題外嘲碧,其他都是正常的。我們改變第一個(gè)span的內(nèi)容:
<span class='s1'>
1哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈 哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
</span>
結(jié)果:
我們改變第二個(gè)span的內(nèi)容:
<span class='s2'>
2嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿
</span>
結(jié)果:
我們同時(shí)改變二個(gè)span的內(nèi)容:
<span class='s1'>
1哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈 哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
</span>
<span class='s2'>
2嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿
</span>
結(jié)果:
綜上父阻,inline-block除了空隙問題外愈涩,還出現(xiàn)了一個(gè)新的問題——兩個(gè)inline-block的對(duì)齊問題。由于才疏學(xué)淺加矛、經(jīng)歷有限履婉,我還并沒有徹底弄清楚到底為什么會(huì)這樣,只是知道和字體默認(rèn)的基線對(duì)齊'vertical-align:baseline'
有關(guān)斟览。
現(xiàn)在我們給span添加vertical-align:
// html
<div>
<span class='s1'>
1哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈 哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
</span>
<span class='s2'>
2嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿
</span>
</div>
// css
div{
border:1px solid red;
}
span{
display:inline-block;
border:1px solid;
}
.s1{
width:100px;
height:200px;
vertical-align:top;
}
.s2{
width:200px;
height:300px;
}
結(jié)果:
所以毁腿,要想實(shí)現(xiàn)inline-block的對(duì)齊,需要改變 inline-block 元素的vertical-align:top /middle苛茂。在實(shí)際工作中已烤,同樣建議使用float/flex,棄用inline-block妓羊。
總結(jié):
1胯究、使用inline-block:該元素是獨(dú)生子,沒有兄弟元素躁绸,不需對(duì)齊(這樣也不會(huì)有空隙問題)
2裕循、inline-block一定要慎用丙猬!inline-block一定要慎用!inline-block一定要慎用费韭!
二、inline-block的應(yīng)用場(chǎng)景
1庭瑰、inline-block包住浮動(dòng)元素
我們現(xiàn)在想實(shí)現(xiàn)這樣一個(gè)界面:
‘logo’和‘login’水平垂直居中星持,且中間沒有空隙。
前面講到弹灭,如果想要去除inline/inline-block的空隙督暂,最好使用block/float/flex,棄用inline-block穷吮。使用flex十分簡(jiǎn)單逻翁,這里我們就使用float完成這個(gè)效果。
// html
<body>
<div class='parent'>
<span>logo</span>
<span>login</span>
</div>
</body>
// css
body{
margin:0;
padding:0;
}
.parent{
max-width:300px;
margin:0 auto;
border:1px solid;
}
span{
border:1px solid red;
float:left;
}
結(jié)果:
我們知道捡鱼,當(dāng)元素設(shè)置float后八回,元素就脫離了文檔流,所以兩個(gè)span元素已經(jīng)不在.parent里了驾诈。那我怎么可以讓這兩個(gè)浮動(dòng)元素居中呢缠诅?
這時(shí)候,inline-block就派上用場(chǎng)了乍迄。由于inline-block可以包住浮動(dòng)元素管引,我們?cè)趦蓚€(gè)span的上面加一個(gè)inline-block包裹住他們。代碼如下:
// html
<body>
<div class='parent'>
<div class='box'>
<span>logo</span>
<span>login</span>
</div>
</div>
</body>
// css
body{
margin:0;
padding:0;
}
.parent{
max-width:300px;
margin:0 auto;
border:1px solid;
}
.box{
border:1px solid blue;
display:inline-block;
}
span{
border:1px solid red;
float:left;
}
結(jié)果:
你看闯两,inline-block是不是把兩個(gè)浮動(dòng)元素包住了褥伴?如果你還存在疑問,可以試試block漾狼,看看能不能包住浮動(dòng)元素(結(jié)果肯定是不能)重慢,是不是很神奇?
其實(shí)逊躁,inline-block之所以能包住浮動(dòng)元素伤锚,是因?yàn)?strong>BFC的影響,大家可查看我的另一篇博客為什么"overflow:hidden"能清除浮動(dòng)的影響中對(duì)BFC的講解志衣。
接下來屯援,我們對(duì).parent元素設(shè)置居中:
.parent{
max-width:300px;
margin:0 auto;
border:1px solid;
text-align:center;
}
結(jié)果:
但是,inline-block下面還是有空隙澳罡狞洋!這是怎么回事?
inline-block默認(rèn)基線對(duì)齊,所以inline-block下方還是有一個(gè)空隙(請(qǐng)參考我的另一篇博客“圖片下方為什么會(huì)有空隙”)绿店。所以我們?nèi)孕柙O(shè)置這個(gè)inline-block的vertical-align:
.box{
border:1px solid blue;
display:inline-block;
vertical-align:top/bottom/middle;
}
結(jié)果:
2吉懊、inline-block實(shí)現(xiàn)水平垂直居中
inline-block實(shí)現(xiàn)水平垂直居中要和vertical-align配合使用庐橙,該方法能實(shí)現(xiàn)不定長(zhǎng)多行文字、不定長(zhǎng)圖片的水平垂直居中借嗽。
首先我們先來實(shí)現(xiàn)垂直居中态鳖,代碼如下:
// html
<body>
<div class='wrapper'>
<span></span>
![](http://upload-images.jianshu.io/upload_images/5617133-bea075f677449c0a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
</div>
</body>
// css
body{
padding:0;
margin:0;
}
*{
box-sizing:border-box;
}
.wrapper{
width:400px;
height:300px;
margin:0 auto;
border:1px solid;
text-align:center;
}
span{
display:inline-block;
border:1px solid blue;
height:100%;
vertical-align:middle;
}
img{
width:200px;
vertical-align:middle;
}
結(jié)果:
分析:
在圖片前面設(shè)置一個(gè)“透明”的span(為了觀察方便我將span顯示出來),將這個(gè)span設(shè)置為inline-block并設(shè)置高度與父元素的高度相同恶导,這樣浆竭,同時(shí)設(shè)置該span和圖片以中線對(duì)齊vertival-align:middle
,即可實(shí)現(xiàn)垂直居中效果惨寿。
我們很容易看到邦泄,這時(shí)的圖片僅僅實(shí)現(xiàn)了垂直居中,還未實(shí)現(xiàn)水平居中裂垦,原因在于span和圖片之間的“空隙”顺囊。我們通過在圖片后面再添加一個(gè)相同的span來“抵消”這個(gè)空隙。代碼:
// html
<body>
<div class='wrapper'>
<span></span>
![](http://upload-images.jianshu.io/upload_images/5617133-bea075f677449c0a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
<span></span>
</div>
</body>
結(jié)果:
最后消除兩個(gè)span的邊框:
//添加span樣式
span{
border:1px solid transparent;
}
結(jié)果:
至此蕉拢,我們就實(shí)現(xiàn)了圖片的水平垂直居中特碳。
最后,我們對(duì)上述代碼做一個(gè)小小的改進(jìn)晕换。我們看到测萎,圖片前面和后面都有一個(gè)span元素,換句話說届巩,父元素的第一個(gè)子元素和最后一個(gè)子元素都是無內(nèi)容不可見的span元素硅瞧,因此我們可以使用偽元素的特性進(jìn)行一些改進(jìn),代碼如下:
// html
<body>
<div class='wrapper'>
![](http://upload-images.jianshu.io/upload_images/5617133-bea075f677449c0a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
</div>
</body>
// css
.wrapper{
width:400px;
height:300px;
margin:0 auto;
border:1px solid;
text-align:center;
}
.wrapper::before,.wrapper::after{
content:'';
border:1px solid transparent;
display:inline-block;
height:100%;
vertical-align:middle;
}
img{
width:200px;
vertical-align:middle;
}
結(jié)果:
其實(shí)恕汇,flex可以很簡(jiǎn)單地實(shí)現(xiàn)水平垂直居中的這個(gè)功能腕唧,只需要短短三行代碼即可。CSS3果然很方便啊......
由于個(gè)人水平有限瘾英,博客錯(cuò)誤之處枣接,煩請(qǐng)指正!