打印

RT1012: IE6 IE7 IE8(Q) Opera 认为 'white-space:nowrap' 仅作用在纯文本内容上

作者:钱宝坤

标准参考

根据 W3C CSS 2.1 规范中的描述 'white-space:nowrap' 设置的含义为:该值像 'normal' 那样合并空白,但是阻止文本内的分行。

详细说明请参考:16.6 White space: the 'white-space' property

替换元素是用来表示超出 CSS 格式化模型表示范围的元素,他们的共同特点是没有设置宽高的情况下拥有默认宽高。常见的有:IMG INPUT TEXTAREA IFRAME 等。

详细说明请参考:replaced-element

问题描述

对容器设置了 'white-space:nowrap' 特性值后,期望抑制内容换行。但是,在容器内没有文本内容仅存在行内替换元素和行内块元素时,IE6 IE7 IE8(Q) Opera 浏览器认为这些元素不是文字内容,因而抑制内容换行规则不生效。在容器布局宽度不够的情况下,行内替换元素和行内块元素将不受父容器 'white-space:nowrap' 特性值约束,产生换行。

造成的影响

原本不希望换行的部分产生换行,导致各浏览器中小范围布局差异产生。

受影响的浏览器

IE6 IE7 IE8(Q) Opera  

问题分析

根据 CSS 2.1 规范描述, 'white-space:nowrap' 值设置会阻止文本内的分行。

原文: nowrap This value collapses white space as for 'normal', but suppresses line
                breaks within text.

在说明中, text 单词存在二义性问题,他可以表示正文也可以表示为通常意义的文字内容。

在实际情况中,元素内不仅只含有文本内容,还可能存在其他行内元素,如行内替换元素以及行内块元素,他们在父元素内组成了正文内容。如果规范所描述的 text 为正文含义,那么 'white-space:nowrap' 特性值设置将抑制这些元素之间产生换行。相反,'TEXT' 含义为普通文字,那么抑制换行策略将不会对这些元素生效。

我们来分析以下代码:

<style> body { font:20px/1.2 'simsun'; } div { width:60px; background:wheat; margin:10px 0; }
                </style> <div> <span style="white-space:nowrap;">中国字</span><span
                style="white-space:nowrap;"><img src="google.png" /></span> </div> <div>
                <span style="white-space:nowrap;">中国字</span><span
                style="white-space:nowrap;"><input /></span> </div> <div> <span
                style="white-space:nowrap;">中国字</span><span style="white-space:nowrap;"><input
                type="button" /></span> </div> <div> <span
                style="white-space:nowrap;">中国字</span><span style="white-space:nowrap;"><input
                type="submit" /></span> </div> <div> <span
                style="white-space:nowrap;">中国字</span><span style="white-space:nowrap;"><input
                type="file" /></span> </div> <div> <span
                style="white-space:nowrap;">中国字</span><span style="white-space:nowrap;"><input
                type="checkbox" /></span> </div> <div> <span
                style="white-space:nowrap;">中国字</span><span style="white-space:nowrap;"><input
                type="radio" /></span> </div> <div> <span
                style="white-space:nowrap;">中国字</span><span
                style="white-space:nowrap;"><textarea></textarea></span> </div> <div>
                <span style="white-space:nowrap;">中国字</span><span
                style="white-space:nowrap;"><select></select></span> </div> <div>
                <span style="white-space:nowrap;">中国字</span><span
                style="white-space:nowrap;"><iframe></iframe></span> </div> <div>
                <span style="white-space:nowrap;">中国字</span><span
                style="white-space:nowrap;"><button></button></span> </div> <div>
                <span style="white-space:nowrap;">中国字</span><span style="white-space:nowrap;"><span
                style="display:inline-block">汉字</span></span> </div>

上例中,容器 DIV 元素的宽度为 60px,'white-space' 特性值是默认的 'normal' ,容器内标记紧密排列 ,没有因换行和空格产生匿名行内元素。这样容器的 'white-space:normal' 设置不会对容器内容是否换行产生影响。

容器内首个 SPAN 元素内有三个中文,每个中文的字号设置为 20px,整体宽度恰好是容器宽度 60px。这个 SPAN 元素内又设置 'white-space:nowrap' 特性值,说明其内三个文字会抑制换行产生。

第二个 SPAN 元素设置 'white-space:nowrap' 特性值,其内子元素没有产生文本内容,分别是常用行内替换元素以及行内块元素。

实际运行结果如下:

  IE6 IE7 IE8(Q) Opera IE8(S) Firefox Chrome Safari
常见行内替换元素 产生换行 不产生换行
行内块元素1 产生换行 不产生换行

【注】:IE6 IE7 IE8(Q) 不支持严格意义上 CSS 2.1 规范内说明的 'display:inline-block' 特性值,但是设置 ‘inline-block’ 后会触发 IE 特有的 hasLayout 特性,使行内元素具有布局块特征,这与规范描述所要达到的效果一致。关于 hasLayout 特性的详细描述请参考 MSDN : "HasLayout" Overview

从表中可以看出:

  • IE6 IE7 IE8(Q) Opera 认为行内替换元素以及行内块元素不是规范内说明的文本内容,他们在父容器布局宽度不足时不受 ‘white-space:nowrap’ 特性值制约,会产生换行;
  • IE8(S) Firefox Chrome Safari 认为行内替换元素以及行内块元素均属于容器内正文,即使容器布局宽度不足,依然会抑制换行产生。

解决方案

如果需要使用 'white-space:nowrap' 特性值抑制内容换行,最好避免在容器内加入替换元素以及行内块元素,避免各浏览器出现对规范理解差异。

参见

知识库

相关问题

测试环境

操作系统版本: Windows 7 Ultimate build 7600
浏览器版本: IE6
IE7
IE8
Firefox 3.6.10
Chrome 8.0.552.5 dev
Safari 5.0.2
Opera 10.63
测试页面: replace_element_and_inline_block_element_nowrap.html
本文更新时间: 2010-10-20

关键字

text replace element white-space nowrap suppresses line breaks inline-block