Blog Entry - 2nd February 2008 - Programming - CSS

That About Wraps It Up


I have been exploring some of the blogs and work done on getting word-wrap to work in <pre> elements.

I am not sure if there is a completely cross-browser solution, but the following are solutions I have encountered so far.

Outside Tables

When you are operating outside a table, something like the following seems to work for most browsers.

white-space:		pre-wrap; /* css-3 */
white-space:		-moz-pre-wrap !important; /* Mozilla */
white-space: 		-pre-wrap; /* Opera 4-6 */
white-space:		-o-pre-wrap; /* Opera 7 */
word-wrap:		break-word;    /* IE 5.5+*/

(Note : I am not sure if the !important for Mozilla/Firefox is really needed.)

Lets try it out:-

<!-- PRE WRAP TEST -->
<html>
<head>
<style>

pre
{
 	background-color: #ccc;
	border:   	1px solid #aaa;
	font-family:   	"courier new";
	font-size:  	0.82em; /*11pt*/
 	line-height:  	1.3em;
	margin:		0;

	white-space:   	pre-wrap; /* css-3 */
	white-space:   	-moz-pre-wrap !important; /* Mozilla */
	white-space:   	-pre-wrap; /* Opera 4-6 */
 	white-space:   	-o-pre-wrap; /* Opera 7 */
 	word-wrap:   	break-word;    /* IE 5.5+*/
}

div
{
	border:   1px solid blue;
	width:	  300px;
}
</style>
<body>
<div><pre>Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line.

Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line.
</pre></div>
</body>
</html>

editpop-upiframe

Certainly within the latest IE, Firefox and Opera, that seems pretty successful.

Inside Tables

The Problem With Internet Explorer

As soon as you put the pre inside a table, you need to be a little more wary.

If your table uses percentage widths, Internet Explorer fails to wrap, and forces the table width out to the full length of the longest unwrapped line.

Opera and Firefox still seem to be fine.

Here is an example:-

<!-- INTERNET EXPLORER DOESN'T WRAP -->
<html>
<head>
<style>

pre
{
 	background-color: #ccc;
	border:   	1px solid #aaa;
	font-family:   	"courier new";
	font-size:  	0.82em; /*11pt*/
 	line-height:  	1.3em;
	margin:		0;

	white-space:   	pre-wrap; /* css-3 */
	white-space:   	-moz-pre-wrap !important; /* Mozilla */
	white-space:   	-pre-wrap; /* Opera 4-6 */
 	white-space:   	-o-pre-wrap; /* Opera 7 */
 	word-wrap:   	break-word;    /* IE 5.5+*/
}

div
{
	border:   1px solid blue;
}

table
{
	width:	  50%;
}
</style>
<body>
<table>
<tr>
<td>
<div><pre>Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line.

Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line.
</pre></div>
</td>
</tr>
</table>
</body>
</html>

editpop-upiframe

Solution 1 : Table Layout Fixed

The first solution seems to be to add table-layout:fixed to the table style.

I speculate (from a quick read of the W3C specifications) that the reason for this is how Internet Explorer interprets the specifications when table-layout is set to auto. As the table does width calculations taking account of the content of the cells and their potential wrapped and unwrapped widths, I guess that Internet Explorer does the column width calculation first, which takes account of the un-wrapped width of the pre element, before then applying any wrapping on the pre element. By setting table-layout to fixed, column widths do not seem to depend on so much on the potential width of the content.

Thus:

<!-- SOLUTION 1 : TABLE LAYOUT FIXED -->
<html>
<head>
<style>

pre
{
 	background-color:	#ccc;
	border:   		1px solid #aaa;
	font-family:   		"courier new";
	font-size:  		0.82em; /*11pt*/
 	line-height:  		1.3em;
	margin:			0;

	white-space:   		pre-wrap; /* css-3 */
	white-space:   		-moz-pre-wrap !important; /* Mozilla */
	white-space:   		-pre-wrap; /* Opera 4-6 */
 	white-space:   		-o-pre-wrap; /* Opera 7 */
 	word-wrap:   		break-word;    /* IE 5.5+*/
}

div
{
	border:   1px solid blue;
}

table
{
	table-layout:fixed;
	width:	  50%;
}
</style>
<body>
<table>
<tr>
<td>
<div><pre>Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line.

Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line.
</pre></div>
</td>
</tr>
</table>
</body>
</html>

editpop-upiframe

Solution 2 : White Space Normal

The second solution is to apply white-space:normal for Internet Explorer.

The reason why this works is probably part of the reason why table-layout:auto leads to problems. If auto does column-width calculations based on content width, then by setting white-space:normal for a pre you are in effect saying that the content width for the pre is not the unwrapped width, but the width after any potential wrapping.

Thus:-

<!-- SOLUTION 2 : WHITE SPACE NORMAL -->
<html>
<head>
<style>

pre
{
 	background-color:	#ccc;
	border:   		1px solid #aaa;
	font-family:   		"courier new";
	font-size:  		0.82em; /*11pt*/
 	line-height:  		1.3em;
	margin:			0;

	white-space:   		pre-wrap; /* css-3 */
	white-space:   		-moz-pre-wrap !important; /* Mozilla */
	white-space:   		-pre-wrap; /* Opera 4-6 */
 	white-space:   		-o-pre-wrap; /* Opera 7 */
 	word-wrap:   		break-word;    /* IE 5.5+*/
	_white-space:		normal; /* IE */
}

div
{
	border:   1px solid blue;
}

table
{
	width:	  50%;
}
</style>
<body>
<table>
<tr>
<td>
<div><pre>Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line.

Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line. Please wrap this line.
</pre></div>
</td>
</tr>
</table>
</body>
</html>

editpop-upiframe

Solution 3 : LI Element

The third solution is to put the pre inside a li element. This seems to change the way in which the width of a cell's content is calculated.

<ul><li><pre></pre></li></ul>

Interestingly, the use of a li element also features in some of the drop-down menu solutions for IE6 found at CSS Play.

I have not included an example, but I would speculate that some of the same Internet Explorer rendering quirks are at work here.


Comment(s)


Sorry, comments have been suspended. Too much offensive comment spam is causing the site to be blocked by firewalls (which ironically therefore defeats the point of posting spam in the first place!). I don't get that many comments anyway, so I am going to look at a better way of managing the comment spam before reinstating the comments.


Leave a comment ...


{{PREVIEW}} Comments stopped temporarily due to attack from comment spammers.