首页 > 代码库 > 对行、块元素inline-block的兼容

对行、块元素inline-block的兼容

     学习前端以来发现好多东西需要记忆,但又经常忘记,曾试着把内容记录在word文档中发现有时候又会忘记放在哪不是很方便。看到好多人写博客感觉不错,既可以方便自己查找又可以让其他人浏览以供交流......

     废话不多说了,相信学过css的对display肯定不会陌生,我们经常通过设置display的值可以改变元素的表现形式,来达到想要的布局。今天着重看了一下display属性的inline-block的表现,查阅了写资料整理如下,现在来一起看看吧,如有错误还望各位不吝赐教。

      设置为inline-block 的元素既具有 block 元素可以设置宽高的特性,同时又具有 inline 元素默认不换行的特性。当然不仅仅是这些特性,比如 inline-block 元素也可以设置 vertical-align 属性。简而言之:

inline-block 后的元素就是一个格式化为行内元素的块容器( Block container )

 该属性值在各浏览器的表现

测试表明:IE6 中 inline 元素只要触发了hasLayout其表现就类似于 inline-block(但IE6并非真支持inline-block)这里设置 display:inline-block; 或者 zoom:1; 等其他属性值可以触发 hasLayout,表现出来是一样的。

IE6 中 block 元素即使触发了 hasLayout 也不能具有 inline-block 元素不换行的特性。想要 block 元素支持 inline-block 元素的特性,我们可以这样做:

.dib-block {
display:inline;
zoom:1;
}

首先让 block 元素转化为 inline 元素,强制其不换行;然后通过 zoom:1 触发hasLayout,使其可以设置宽高。

 结合现代浏览器

综上,现代浏览器都支持display:inline-block ,IE6、7 inline 元素也可以达到同样的效果,IE6、7 block 元素需要设置 display:inline; zoom:1; 它们结合在一起便是:

display:inline-block; /* 现代浏览器 +IE67 inline 元素 */
*display:inline; /* IE6
7 block 元素 */
*zoom:1;

为了不让支持 CSS2.1 inline-block 的浏览器 重置为 inline,我们针对 IE6、7 做一个 hack。由于现代浏览器也开始支持 zoom 属性,这里只是希望 IE6、7 中生效,所以还是 hack 一下比较合适。至此产生了我们熟悉的兼容各个浏览器的 inline-block 写法。

1. display:inline-block 后的元素为什么会产生水平空隙,这真的是 bug 吗?

  • 现代浏览器中 inline 和 block 元素 display:inline-block 后均会产生水平空隙;
  • IE6、7,IE8(Q)模拟 display:inline-block 后分两种情况:

    IE6、7,IE8(Q)中:inline 元素会产生空隙,block 元素不会产生空隙。

看看 inline 元素默认的表现情况如何?原来默认就有空隙存在!它们是谁?是空白符(white space)!

而是因为 inline-block 具有inline 元素固有的特性。那么为何 IE6、7 block 元素没有产生空隙呢?其实前面也提到了 IE 的 hasLayout,具有独立性,所以产生 hasLayout 的元素之间表现出来互不影响,这也再次表明 IE6、7 中的 inline-block 不能等同于CSS2.1 中的 inline-block。如果非要说是有 bug,IE6、7 block 元素inline-block 后不产生空隙才是 bug。

去掉空隙

HTML 中的换行符、空格符、制表符等产生了空白符,而这些归根结底都是字符,那么它们的大小都是 受font-size 来控制的,字体大小直接导致 inline 或者inline-block 后元素之间空隙的大小,把 inline-block 元素间的空隙认为总是某个固定大小是错误的。

Chorme

低版本的 chrome 浏览器为了不让文字过小不利于阅读,默认是不支持 font-size:0 的,还好我们有 -webkit-text-size-adjust 这个私有属性来控制,当设为 none 时就支持字体大小为 0 了。我已经记不清楚 chrome 从哪个版本开始支持 font-size:0 了,反正我用chrome 19 是支持了(有知道的朋友,烦请告诉一丝一声,最好有官方更新说明)。但是,-webkit-text-size-adjust:none; 会直接导致页面文字无法缩放,这对于用户来说显然是不友好的。所以-webkit-text-size-adjust:none;一定要慎用,确保使用的地方没有大面积的文字。

Safari 

不支持font-size:0;

处理 Safari 不支持font-size:0 的问题上面已经指出 letter-spacing 是支持负值的,那么这个负值到底取多少合适呢?经过测试得出的结论是:inline-block 产生的空隙与父级元素继承或者设定的 font-familyfont-size 有关,通常情况下,12px 大小的 tahoma 字体,inline-block 后元素间产生的空隙(间隙)大约是 5px

IE

  • IE8 以上支持 font-size:0;
  • IE6、7 inline 元素 inline-block 后设置 font-size:0 始终有 1px 的空隙。

font-size:0;/* 所有浏览器 */
letter-spacing:-5px;/* Safari
等不支持字体大小为 0 的浏览器 */
*letter-spacing:normal;
word-spacing:-1px;/* IE6
7 */

  • 第四步:子元素重置回正常值
    上述所有操作都是在父元素设置的,那么子元素都会继承这些属性,字体大小为0了,子元素就什么都看不到了,这并不是我们想要的。 同时字符和单词间距我们也要把它重置为默认值。「font-size: 12px; letter-spacing: normal; word-spacing: normal;」
  • 最后:inline-block 更好的复用

去除 inline-block 空隙终极解决方案

.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;
}

其实在 YUI 3 中也全面运用了 inline-block 作为基础布局,YUI 3 是这样解决的:

.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;
}

显然,这里纯粹使用了 letter-spacing 和 word-spacing 来控制元素间的空隙,局限性极大,-0.31em和-0.43em 只是因为YUI 3 全局 cssfonts.css 里设置是:「body { font:13px/1.231 arial,helvetica,clean,sans-serif; }」。

当然,如果你坚持使用把 html 写在一行的方式来达到去除 inline-block 空隙的目的,我只能说:一切以牺牲结构来兼容表现的行为都是耍流氓!所以探讨此种方式去除空隙也将是

本文产生的一些观点如下:

    • IE5.5 后开始支持 inline-block  CSS2.1 更早提出 inline-block 的概念并作为所谓的私有属性值使用。但是它所支持的 inline-block 不能等同于 CSS2.1 中的 inline-blockIE 5.567 8Q)中 block 元素对 inline-block 支持不完整,因此二者表现出来的效果是不完全一致。
    • 产生 inline-block 空隙的根本性原因是:HTML 中的换行符、空格符、制表符等合并为空白符,字体大小不为 0 的情况下,空白符自然占据一定的宽度,因此产生了元素间的空隙。
    • 慎用 -webkit-text-size-adjust:none,它将会导致页面无法通过缩放来改变字体大