zoukankan      html  css  js  c++  java
  • 对行、块元素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而是触发了hasLayout(IE5.5就开始支持display:inline-block只是支持的不是很完善)这里设置 display:inline-block; 或者 zoom:1; 等其他属性值可以触发 hasLayout,表现出来是一样的。

    (我们知道 IE6、7 中 display:inline-block 是可以触发 hasLayout 的,触发了 hasLayout 的元素表现出来的特征就是一个独立的矩形容器,可以设置宽高而且不受外部元素的影响,类似于现代浏览器中的 Block formatting contexts (块级格式化上下文)的概念。)

    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/inline-block 后都有水平间隙)

    • 现代浏览器中 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 但是它所支持的 inline-block 不能等同于 CSS2.1 中的 inline-block,它 CSS2.1 更早提出 inline-block 的概念并作为所谓的私有属性值使用,所以二者表现出来的效果是不完全一致。IE 5.567 8Q)中 block 元素对 inline-block 支持不完整,如果要达到类似的效果,需要先设置为 display:inline,然后使用 zoom:1 等触发 hasLayout。。
      • 产生 inline-block 空隙的根本性原因是:HTML 中的换行符、空格符、制表符等合并为空白符,字体大小不为 0 的情况下,空白符自然占据一定的宽度,因此产生了元素间的空隙。
      • 慎用 -webkit-text-size-adjust:none,它将会导致页面无法通过缩放来改变字体大
  • 相关阅读:
    高级I/O之存储映射I/O
    高级I/O之readn和writen函数
    高级I/O之readv和writev函数
    高级I/O之异步I/O
    高级I/O之I/O多路转接——pool、select
    高级I/O之STREAMS
    高级I/O之记录锁
    高级I/O之非阻塞I/O
    用于守护进程的出错处理函数
    守护进程之客户进程-服务器进程模型
  • 原文地址:https://www.cnblogs.com/hansu/p/3720359.html
Copyright © 2011-2022 走看看