浅谈Inline-Block的跨浏览器兼容

Ah, inline-block, that elusive and oh so tempting display declaration that promises so much, yet delivers so little. Too many times have I received PSD files like this:

浅谈Inline-Block的跨浏览器兼容_第1张图片

and begin to cry.

Normally, this type of layout would be a cakewalk. Fixed width, fixed height, float:left and you’re done. Buuuuut, the design needs to work with variable amounts of content, which means if one of these blocks has more content than the others, it will break the layout:

浅谈Inline-Block的跨浏览器兼容_第2张图片

Because the first gallery item is taller than the rest, the 5th item is floated left against it instead of below it. Basically we want a layout with the flexibility of a table, but proper, semantic markup.

We start with a simple page with an unordered list and display set to inline-block:

  • This is awesome

    lobster
  • ...

And it looks ok in Firefox 3, Safari 3 and Opera:

浅谈Inline-Block的跨浏览器兼容_第3张图片

Obviously, something is wrong with the vertical alignment. Well, not exactly wrong, because this is the correct behavior, but it’s not what we want.

What’s going on here is the baseline of each

  • is being aligned with the baseline of the parent
      . What’s a baseline, you ask? A picture is worth a thousand words:

      Baseline

      The baseline is the black line running through the text above. Putting it as simply as possible, the default vertical-align value on inline or inline-block element is baseline, which means the element’s baseline will be aligned with its parent’s baseline. Here’s the first inline-block attempt with baselines shown:

      浅谈Inline-Block的跨浏览器兼容_第4张图片

      As you can see, each baseline is aligned with the baseline for the text ‘This is the baseline’. That text is not in a

    • , but simply a text node of the parent
        , to illustrate where the parent’s baseline is.

        Anyway, the fix for this is simple: vertical-align:top, which results in a great looking grid:

        浅谈Inline-Block的跨浏览器兼容_第5张图片

        Except it still doesn’t work in Firefox 2, IE 6 and 7.

        浅谈Inline-Block的跨浏览器兼容_第6张图片

        Let’s start with Firefox 2.

        Firefox 2 doesn’t support inline-block, but it does support a Mozilla specific display property ‘-moz-inline-stack’, which displays just like inline-block. And when we add it before display:inline-block, FF2 ignores that declaration and keeps -moz-inline-stack because it doesn’t support inline-block. Browsers that support inline-block will use it and ignore previous display property.

        Unfortunately, it has a small bug:

        浅谈Inline-Block的跨浏览器兼容_第7张图片

        Honestly, I don’t know what causes this bug. But there is quick fix. Wrap everything inside the

      • with a
        .

      • This is awesome

        lobster
      • This seems to ‘reset’ everything inside the

      • ’s and makes them display appropriately.

        浅谈Inline-Block的跨浏览器兼容_第8张图片

        Now, on to IE 7. IE 7 does not support inline-block, but we can trick it into rendering the

      • s as if they were inline-block. How? hasLayout, a magical property of IE that allows for all sorts of fun! You can’t set hasLayout explicity on an element with hasLayout:true; or anything easy like that, but you can trigger it with other declarations like zoom:1.

        Technically, what hasLayout means is an element with hasLayout set to true is responsible for rendering itself and its children (combine that with a min-height and width, and you get something very similar to display:block). It’s kinda like magical fairy dust you can sprinkle on rendering issues and make them disappear.

        When we add zoom:1 and *display:inline (star hack to target IE6 & 7) to the

      • s, we make IE 7 display them as if they were inline-block:

        浅谈Inline-Block的跨浏览器兼容_第9张图片

        Phew! Almost done. Just IE 6 left:

        浅谈Inline-Block的跨浏览器兼容_第10张图片

        IE 6 doesn’t support min-height, but thanks to its improper handling of the height property, we can use that instead. Setting _height (IE6 underscore hack) to 250px will give all

      • s a height of 250px, and if their content is bigger than that, they will expand to fit. All other browsers will ignore _height.

        So after all that work, here’s the final CSS and HTML:

        
        
        
      • This is awesome

        lobster
  • 你可能感兴趣的:(CSS3,inline-block,浏览器兼容性,hack)