设计观点View
作者头像

inline-block 未来

【一丝冰凉】 /2013-06-17/已有人看过/层叠之美

F9R上海云路网络科技有限公司

《inline-block 前世今生》写完之后,很多朋友戏说为啥没有未来呢?现在,未来真的来了。且听我娓娓道来。F9R上海云路网络科技有限公司

不过在「娓娓」之前,我们回顾一下「前世今生」中主要讲了几个问题:F9R上海云路网络科技有限公司

  1. IE6 是不是真的不支持 inline-block;
  2. 到底什么是 inline-block;
  3. display:inline-block 后的元素为什么会产生水平空隙,这是不是 Bug?
  4. 如何更好的去掉 inline-block 产生的空隙。

虽然前文中连 inline-block 他爸都写出来了,但无论是 YUI 的解决方案,还是我给出的解决方案都是一坨一坨的,捞出来给大家瞅瞅:F9R上海云路网络科技有限公司

YUI的解决方案:F9R上海云路网络科技有限公司

.yui3-g {F9R上海云路网络科技有限公司
letter-spacing: -0.31em; /* webkit: collapse white-space between units */F9R上海云路网络科技有限公司
*letter-spacing: normal; /* reset IE < 8 */F9R上海云路网络科技有限公司
word-spacing: -0.43em; /* IE < 8 && gecko: collapse white-space between units */F9R上海云路网络科技有限公司
}F9R上海云路网络科技有限公司

 F9R上海云路网络科技有限公司

.yui3-u {F9R上海云路网络科技有限公司
display: inline-block;F9R上海云路网络科技有限公司
zoom: 1; *display: inline; /* IE < 8: fake inline-block */F9R上海云路网络科技有限公司
letter-spacing: normal;F9R上海云路网络科技有限公司
word-spacing: normal;F9R上海云路网络科技有限公司
vertical-align: top;F9R上海云路网络科技有限公司
}F9R上海云路网络科技有限公司

我写的方案:F9R上海云路网络科技有限公司

.dib-wrap {F9R上海云路网络科技有限公司
font-size:0;/* 所有浏览器 */F9R上海云路网络科技有限公司
*word-spacing:-1px;/* IE6、7 */F9R上海云路网络科技有限公司
}F9R上海云路网络科技有限公司

.dib-wrap .dib{F9R上海云路网络科技有限公司
font-size: 12px;F9R上海云路网络科技有限公司
letter-spacing: normal;F9R上海云路网络科技有限公司
word-spacing: normal;F9R上海云路网络科技有限公司
vertical-align:top;F9R上海云路网络科技有限公司
}F9R上海云路网络科技有限公司

@media screen and (-webkit-min-device-pixel-ratio:0){F9R上海云路网络科技有限公司
/* firefox 中 letter-spacing 会导致脱离普通流的元素水平位移 */F9R上海云路网络科技有限公司
.dib-wrap{F9R上海云路网络科技有限公司
letter-spacing:-5px;/* Safari 等不支持字体大小为 0 的浏览器, N 根据父级字体调节*/F9R上海云路网络科技有限公司
}F9R上海云路网络科技有限公司
}F9R上海云路网络科技有限公司

.dib {F9R上海云路网络科技有限公司
display: inline-block;F9R上海云路网络科技有限公司
*display:inline;F9R上海云路网络科技有限公司
*zoom:1;F9R上海云路网络科技有限公司
}F9R上海云路网络科技有限公司

我们知道造成空隙的根本性原因是:空白符(whitespace)。F9R上海云路网络科技有限公司

在 CSS 中空白符的表现主要是由 white-space 属性来控制的,取值与特性如下:F9R上海云路网络科技有限公司

取值 换行 空白和制表符 文字换行
normal 折叠 折叠 换行
pre 保留 保留 不换行
nowrap 折叠 折叠 不换行
pre-wrap 保留 保留 换行
pre-line 保留 折叠 换行

但是我们发现没有一个关键字来忽略空白符,于是有人在「www-style」发邮件提出:增加一个「white-space: ignore」来忽略空白符。并且通过 JS 来模拟了一个「white-space:none」去除 inline-block 空隙的 Demo,更多例子可以看 Github 上的介绍。F9R上海云路网络科技有限公司

实际上,在「CSS Text Level 4」中已经把 white-space 分为两部分:F9R上海云路网络科技有限公司

  1. white-space-collapsing
  2. text-wrap

这样一来「white-space」与「white-space-collapsing」、「text-wrap」的关系便可以通过下表来描述:F9R上海云路网络科技有限公司

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 专门用来控制元素中的空白如何折叠,取值如下:F9R上海云路网络科技有限公司

  • 「collapse」该值要求用户代理将一系列空白折叠为一个单独的字符(或者在某些情况下,没有字符)。F9R上海云路网络科技有限公司
  • 「preserve」该值阻止用户代理折叠空白,换行符保留为强制换行符。
  • 「preserve-breaks」该值将与「collapse」一样折叠空白字符,但保留换行符为强制换行符。
  • 「discard」该值要求用户代理”丢弃(discard)”元素中的所有空白符。
  • 「trim-inner」对于块容器,该值要求用户代理丢弃所有在元素开始处的空白符,直到并包含在第一个非空白字符之前的最后一个换行符;同时丢弃在元素结尾处的所有空白符,其从最后一个非空白字符之后的第一个换行符开始。
  • 「consume-before」该值要求用户代理折叠紧邻元素开始(位置)之前的所有可折叠空白符。
  • 「consume-after」该值要求用户代理折叠紧邻元素开始(位置)之后的所有可折叠空白符。

「discard」便是我们需要的救星,它会删除一切空白符,再也不用担心了。Like this:F9R上海云路网络科技有限公司

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 是个没人要的孩子?你说嗯哼不嗯哼?F9R上海云路网络科技有限公司

最后,抛开 inline-block 本身的局限性,放眼未来,Tab Atkins 也更赞同布局问题应该用布局属性在内部解决空白符的问题,所以充分运用 flex 才是主流的方向。CSS Text 4 毕竟还只是编辑草案,「white-space-collapsing」 随时可能会被修改或者删除。或者你发现在现代浏览器上,inline-block 可以实现 flex 却不能实现的效果,欢迎写出 Demo和我交流。F9R上海云路网络科技有限公司

未来,你或许不用再担心 inline-block 空隙的问题了,未来是 flex,grid 的天下,你说嗯哼不嗯哼?F9R上海云路网络科技有限公司