不过在「娓娓」之前,我们回顾一下「前世今生」中主要讲了几个问题:
- IE6 是不是真的不支持 inline-block;
- 到底什么是 inline-block;
- display:inline-block 后的元素为什么会产生水平空隙,这是不是 Bug?
- 如何更好的去掉 inline-block 产生的空隙。
虽然前文中连 inline-block 他爸都写出来了,但无论是 YUI 的解决方案,还是我给出的解决方案都是一坨一坨的,捞出来给大家瞅瞅:
YUI的解决方案:
.yui3-g {
letter-spacing: -0.31em; /* webkit: collapse white-space between units */
*letter-spacing: normal; /* reset IE < 8 */
word-spacing: -0.43em; /* IE < 8 && gecko: collapse white-space between units */
}
.yui3-u {
display: inline-block;
zoom: 1; *display: inline; /* IE < 8: fake inline-block */
letter-spacing: normal;
word-spacing: normal;
vertical-align: top;
}
我写的方案:
.dib-wrap {
font-size:0;/* 所有浏览器 */
*word-spacing:-1px;/* IE6、7 */
}.dib-wrap .dib{
font-size: 12px;
letter-spacing: normal;
word-spacing: normal;
vertical-align:top;
}@media screen and (-webkit-min-device-pixel-ratio:0){
/* firefox 中 letter-spacing 会导致脱离普通流的元素水平位移 */
.dib-wrap{
letter-spacing:-5px;/* Safari 等不支持字体大小为 0 的浏览器, N 根据父级字体调节*/
}
}.dib {
display: inline-block;
*display:inline;
*zoom:1;
}
我们知道造成空隙的根本性原因是:空白符(whitespace)。
在 CSS 中空白符的表现主要是由 white-space 属性来控制的,取值与特性如下:
取值 | 换行 | 空白和制表符 | 文字换行 |
---|---|---|---|
normal | 折叠 | 折叠 | 换行 |
pre | 保留 | 保留 | 不换行 |
nowrap | 折叠 | 折叠 | 不换行 |
pre-wrap | 保留 | 保留 | 换行 |
pre-line | 保留 | 折叠 | 换行 |
但是我们发现没有一个关键字来忽略空白符,于是有人在「www-style」发邮件提出:增加一个「white-space: ignore」来忽略空白符。并且通过 JS 来模拟了一个「white-space:none」去除 inline-block 空隙的 Demo,更多例子可以看 Github 上的介绍。
实际上,在「CSS Text Level 4」中已经把 white-space 分为两部分:
这样一来「white-space」与「white-space-collapsing」、「text-wrap」的关系便可以通过下表来描述:
white-space 取值 | white-space-collapsing 取值 | text-wrap 取值 | 换行 | 空白和制表符 | 文字换行 |
---|---|---|---|---|---|
normal | collapse | normal | 折叠 | 折叠 | 换行 |
pre | preserve | none | 保留 | 保留 | 不换行 |
nowrap | collapse | none | 折叠 | 折叠 | 不换行 |
pre-wrap | preserve | normal | 保留 | 保留 | 换行 |
pre-line | preserve-breaks | normal | 保留 | 折叠 | 换行 |
其中,white-space-collapsing 专门用来控制元素中的空白如何折叠,取值如下:
- 「collapse」该值要求用户代理将一系列空白折叠为一个单独的字符(或者在某些情况下,没有字符)。
- 「preserve」该值阻止用户代理折叠空白,换行符保留为强制换行符。
- 「preserve-breaks」该值将与「collapse」一样折叠空白字符,但保留换行符为强制换行符。
- 「discard」该值要求用户代理”丢弃(discard)”元素中的所有空白符。
- 「trim-inner」对于块容器,该值要求用户代理丢弃所有在元素开始处的空白符,直到并包含在第一个非空白字符之前的最后一个换行符;同时丢弃在元素结尾处的所有空白符,其从最后一个非空白字符之后的第一个换行符开始。
- 「consume-before」该值要求用户代理折叠紧邻元素开始(位置)之前的所有可折叠空白符。
- 「consume-after」该值要求用户代理折叠紧邻元素开始(位置)之后的所有可折叠空白符。
「discard」便是我们需要的救星,它会删除一切空白符,再也不用担心了。Like this:
ul{ white-space-collapsing:discard; } li{ display: inline-block;}
但是「trim-inner」、「consume-before」、「consume-after」似乎不能很好的工作,因为「white-space-collapsing」具有继承的特性,假如插入一个<span>或<div>便会造成额外的空白被删除。这一块目前还没能很好的解决,如同「Tab Atkins」所说:我们没有给予 Text4 更多的关爱(We haven’t given Text 4 much love yet),可怜的 CSS Text 4 是个没人要的孩子?你说嗯哼不嗯哼?
最后,抛开 inline-block 本身的局限性,放眼未来,Tab Atkins 也更赞同布局问题应该用布局属性在内部解决空白符的问题,所以充分运用 flex 才是主流的方向。CSS Text 4 毕竟还只是编辑草案,「white-space-collapsing」 随时可能会被修改或者删除。或者你发现在现代浏览器上,inline-block 可以实现 flex 却不能实现的效果,欢迎写出 Demo和我交流。
未来,你或许不用再担心 inline-block 空隙的问题了,未来是 flex,grid 的天下,你说嗯哼不嗯哼?