No replies
gary.turner
gary.turner's picture
Offline
Moderator
Dallas
Last seen: 2 years 3 weeks ago
Dallas
Timezone: GMT-6
Joined: 2004-06-25
Posts: 9776
Points: 3858

See also, IE White Space Bug.

There are cases in which IE treats the white
space "\n" between and the next

  • as a literal linefeed. That creates extra space between list items. So this code,
     
    <ul> 
      <li>list item</li> 
      <li>list item</li> 
      <li>list item</li> 
      <li>list item</li> 
    </ul>
    which should give you this,

    list item
    list item
    list item
    list item,

    instead gives this,

    list item

    list item

    list item

    list item.

    The common fix has been to remove the offending white space;
     
    <ul> 
       <li>list item</li><li> 
           list item</li><li> 
           list item</li><li> 
           list item</li></ul> 
     
    <ul> 
       <li>list item</li>< 
        li>list item</li>< 
        li>list item</li>< 
        li>list item</li>< 
    /ul> 
     
    <ul> 
       <li>list item</li><li>list item</li><li>list item</li><li>list item</li></ul>

    That works, but is ugly. In the case of non-trivial lists, the formatting can
    make the list code all but unreadable. Plus, jiggering the html
    formatting to control display is just wrong.

    After proclaiming I had found the secret to the IE white space bug in
    lists, I found there were 'issues'. A bulleted list had screwy
    placement of the bullets. As long as you don't need the bullets, all
    is well. I don't think that little caveat makes for a good cure. So
    the search was restarted.

    I thought I had discovered the trigger to be whether the list item was
    dimensioned, eg. the width set. From that I figured MSIE's hasLayout()
    was involved. There was another clue, and I glommed onto the wrong
    one. The trigger is actually a link with {display: block;}[1]. You
    may see this in the following test cases;

    (1)
     
    <ul id="plain"> 
      <li>list item</li> 
      <li>list item</li> 
      <li>list item</li> 
      <li>list item</li> 
    </ul>


    (2)
     
    <ul id="inline-links"> 
      <li><a href="#" rel="nofollow">some inline link</a></li> 
      <li><a href="#" rel="nofollow">some link</a></li> 
      <li><a href="#" rel="nofollow">some link</a></li> 
      <li><a href="#" rel="nofollow">some link</a></li> 
    </ul>


    (3)
     
    #block-links a {
        display: block;
        }
    ---------
    <ul id="block-links"> 
      <li><a href="#" rel="nofollow">some block link</a></li> 
      <li><a href="#" rel="nofollow">some link</a></li> 
      <li><a href="#" rel="nofollow">some link</a></li> 
      <li><a href="#" rel="nofollow">some link</a></li> 
    </ul>


    Only #3 will exhibit the white space bug. So an undimensioned li is not
    the prime mover. Will setting a dimension do away with the extra
    space? Yes. That only reinforces my feeling this is a hasLayout()
    related 'feature'.
     
    /* Hide this from IE-Mac \*/ 
    * html #hacked-li li { 
        height: 1px; 
        } 
    /* End the hiding */ 
    ---------- 
     <ul id="hacked-li"> 
        <li><a href="#" rel="nofollow">some block link</a> hacked li</li> 
        <li><a href="#" rel="nofollow">some link</a></li> 
        <li><a href="#" rel="nofollow">some link</a></li> 
        <li><a href="#" rel="nofollow">some link</a></li> 
      </ul>

    You'll notice the bullets. They go to the bottom of the li. They're
    too low on a single line, and opposite the last line on multi-line
    list items. I used the Holly hack to trigger hasLayout(), but all
    methods do the same or worse.

    Properties and corresponding values that, if set, cause an element to
    have layout.[2]
      CSS property: Value
      --------------------
      display: inline-block
      height: any value
      float: left or right
      position: absolute
      width: any value
      writing-mode: tb-rl
      zoom: any value

    The hasLayout() property applied to the li fixes the white space bug
    but causes its own set of problems. MS says hasLayout() applies to
    anchors, too. Since the anchor caused the problem, can it fix it?
     
    /* \*/ 
    * html #hacked-link a { 
        height: 1px; 
        } 
    /*  */ 
    ---------------- 
      <ul id="hacked-link"> 
        <li><a href="#" rel="nofollow">some block link</a> hacked link</li> 
        <li><a href="#" rel="nofollow">some link</a></li> 
        <li><a href="#" rel="nofollow">some link</a></li> 
        <li><a href="#" rel="nofollow">some link</a></li> 
      </ul>

    Why yes. Yes, it does, and without the shifted bullets. I think I
    can now declare a general fix for the IE white space bug. Cause the
    anchor element to have hasLayout()=true. The full test case[5] should
    bear me out.

    All that, and I did run into another fairly unknown fix[3]. Give the
    li a bottom border! How simple is that? It has limitations on where
    it can be used, but when it can ….
  • And yet another fix is found[4]. This has already been mentioned, {display: inline-block;}, as setting hasLayout=true. What is new is that we can use that as a trigger, then go to {display: block;} without un-setting hasLayout. So, doing

    a {
        display: inline-block;
        }
    
    a {
        display: block;
        }
    will set hasLayout, but {display: block;} will apply as overruling the earlier display value.

    cheers,

    gary

    **************************************

    [1] Hicks Design

    [2]
    hasLayout property


    [3] css-discuss

    [4] Thanks to C, aka SuzyUK, a mod/guru at WebmasterWorld Forums, and aka cssangel in these forums.

    If your web page is as clever as you can make it, it's probably too clever for you to debug or maintain.

    Tags: