Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elements not wrapping as expected in IE 8/ 9

Yet another "IE is doing something different from other browsers" question but this is one is slightly unusual in that IE7 does the correct thing but IE 8 and 9 do not.

Here is the situation, I have a simple 3 column layout. The first 2 columns are fixed width and the third I want to be variable width so that it uses up the available space.

I am outputting textual data in the third column. The text data should be free to wrap at the end of a data value/sentence - so I output it as .

<span class="nowrap">foo bar</span>
<span class="nowrap">moo bahh</span>

(See the example below also)

everything works like a charm in FF, Chrome and IE7 but internet explorer 8 and 9 treat the consecutive nowrap spans as 1 big nowrap element (i.e. it puts all the values on one line). There is white space between the spans and so (IMO) it should be free to wrap. The only way i can get IE8/9 to wrap as I want is to include some non-white space between the nowrapped spans.

This workaround is OK but I am curious to know:

  • Is IE rendering the markup correctly or incorrectly (i.e. is my expectation that the values should wrap incorrect. I only assume that IE is at fault because the other browsers do it differently)
  • Is there a more elegant solution that the one I have: In an ideal world, I would want to ensure that the separating comma never wrapped to the start of a new line.

Thanks in advance

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head runat="server">
    <style type="text/css">
        .leftBit {float:left; margin-right: 10px; background-color: yellow;}
        .middleBit {float:left; width:305px; margin-right: 10px; background-color: orange;}
        .remainder {margin-left: 420px;  min-width: 200px;background-color: #DDD;}
        .nowrap { white-space:nowrap;}
        .clear {clear: both;}
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div>
         <div >
            <div class="leftBit">Left bit</div>
            <div class="middleBit">This value wraps - but I want to keep the values on the same line</div>
            <div class="remainder">
                <span>Blue the colour of the sea and the sky, </span> 
                <span>Green green green green of home, </span> 
                <span>Red red red red fire engine red red red red</span>
            </div>
         </div>
         <div class="clear"></div>
    </div>
    <div>
         <div >
            <div class="leftBit">Left bit</div>
            <div class="middleBit">I don't know why these values do not wrap?  They do in FF and chrome and IE7 but not IE8/9</div>
            <div class="remainder">
                <span class="nowrap">Blue the colour of the sea and the sky, </span> 
                <span class="nowrap">Green green green green of home, </span> 
                <span class="nowrap">Red red red red fire engine red red red red</span>
            </div>
         </div>
         <div class="clear"></div>
    </div>
    <div>
         <div >
            <div class="leftBit">Left bit</div>
            <div class="middleBit">Here is my "work around" - I have to include some non-whiite space between the "nowrap" elements.  Is this a bug or expected behaviour?</div>
            <div class="remainder">
                <span class="nowrap">Blue the colour of the sea and the sky </span> ,
                <span class="nowrap">Green green green green of home </span> ,
                <span class="nowrap">Red red red red fire engine red red red red</span>
            </div>
         </div>
         <div class="clear"></div>
    </div>
    <hr />
    </form>

</body>
</html>
like image 974
Chris Fewtrell Avatar asked Oct 24 '11 14:10

Chris Fewtrell


2 Answers

Determining word breaks isn't preformed the same in different browsers or between different specifications. I believe Firefox is the only latest release that will format the way you are expecting. There are certain length situations where Chrome will also break out of the parent box.

As such, manual hints need to be provided in the HTML to get consistent output.

In the specific example, a way to get around this is to use the unicode character for Zero Width Space. This will break apart your code without introducing additional space.

<span class="nowrap">foo bar</span>&#8203;
<span class="nowrap">moo bahh</span>

If for some reason you can't use the unicode code, you might want to try the html entity &thinsp; which is a thin space. It will, however, introduce some additional space into your html output.

Although this seems like an issue where there should be consistency between the browsers, http://www.cs.tut.fi/~jkorpela/html/nobr.html quotes several technical documents and their differences between how words should be broken, in addition to the differing browser interpretations of those documents. I'm guessing each browsers overall strategy plays a part in this specific example.

Except for preformatted elements - -, each block structuring element is regarded as a paragraph by taking the data characters in its content and the content of its descendant elements, concatenating them, and splitting the result into words, separated by space, tab, or record end characters (and perhaps hyphen characters). The sequence of words is typeset as a paragraph by breaking it into lines.

Source: HTML 2.0, section Characters, Words, and Paragraphs

In HTML, there are two types of hyphens: the plain hyphen and the soft hyphen. The plain hyphen should be interpreted by a user agent as just another character. The soft hyphen tells the user agent where a line break can occur.

Source: HTML 4.0, section Hyphenation

see Unicode Technical Report #14: Line Breaking Properties (technicality alert!), which seems to allow a "direct break" between an alphanumeric character and an opening parenthesis, for example. This is hardly a good idea in general, though. It would even allow very dishono(u)rable breaks!

like image 187
nosilleg Avatar answered Nov 15 '22 03:11

nosilleg


Thanks to @nosilleg's answer I made a great solution using CSS only.

Given that you're already using classes this is easy, add this;

.nowrap:before {
    content : '\200B';
}

What this does is inserts the Zero Width Space character just before each of your nowrap elements, without you editing the HTML!
Now you wont have to remember to add in that pesky HTML entity every time you use your nowrap class.

Worked in IE8 and 9 and didn't affect the other browsers.

like image 21
Hashbrown Avatar answered Nov 15 '22 05:11

Hashbrown