IE6,7下實現white-space:pre-wrap

HTML 的空白符處理規則

HTML 中的“空白符”包括空格 (space)、製表符 (tab)、換行符 (CR/LF) 三種。

我們知道,在默認情況下,HTML 源碼中的空白符均被顯示爲空格,並且連續的多個空白符會被視爲一個,或者說,連續的多個空白符會被合併。

然而在有些時候,我們希望 HTML 源碼中的多個連續空格在網頁瀏覽器中可以真實地呈現,或者需要源碼中的換行符能起到真正的換行作用。於是,我們發現了

 標籤,它可以真實還原它內部文本的空白符的真實情況。

於是我們經常會把一段表示計算機代碼的文本放進

 標籤中,它們在瀏覽器中會表現出自身的空格縮進和換行效果,而不需要我們增加額外的樣式和標籤來控制它的縮進和換行。

隨着對 CSS 的瞭解不斷深入,我們發現,原來這一切都是 white-space 屬性在安排。

 元素之所以如此神奇,是因爲它自身具有 {white-space: pre;} 這一默認樣式。

white-space 屬性

CSS 中的 white-space 屬性用於設置文本空白符的處理規則,這其中包括:是否合併空白符、是否保留換行符、是否允許自動換行。各屬性值的不同行爲如下表所示:

white-space 屬性值一覽表

屬性值空白符換行符自動換行最早出現於normal合併忽略允許CSS 1nowrap合併忽略不允許CSS 1pre保留保留不允許CSS 1pre-wrap保留保留允許CSS 2.1pre-line合併保留允許CSS 2.1

:在 CSS1/2 下,white-space 屬性只可應用於塊級元素;在 CSS 2.1 下,可應用於所有元素。)

如果我們需要某個容器元素具有

 元素的空白符處理行爲,則爲它設置 {white-space: pre;} 樣式即可。

對 pre-wrap 的需求

我們先解釋一下上述表格中的“自動換行”行爲,它是指某元素內部的文本流按照文本方向排版,當文本流遇到限制其繼續延伸的邊界時,是否換行。“不允許自動換行”則意味着文本流會溢出該元素。

因 此,{white-space: pre;} 樣式有時候並不能滿足我們的期望。比如,在某些不需要特別嚴謹的場合,或者排版某些對換行不敏感的代碼片斷(比如 HTML 或 CSS)的時候,我們不希望代碼片段中的一行長代碼令它的容器元素產生水平滾動條,因爲那樣不便閱讀。我們希望在這種情況下,長代碼自動換行就好。

這時,對照一下上表中各屬性值的不同行爲特徵,我們會發現 pre-wrap 這個屬性值脫穎而出——它正是我們所需要的。

對 pre-wrap 的另一種需求

再來看另一種實戰中可能會遇到的情形。

表單中的文本域(

隨之而來的一個問題就是,我們通過多行文本框提交多行 文本數據,是爲了在網頁上最終顯示出多行文本。但由於瀏覽器對 HTML 源代碼默認進行空白符合並處理,爲了確保我們提交的多行文本數據最終在網頁上正確地呈現出多行的形態,通常需要在服務器端做處理,比如將文本中的換行符轉 換爲 HTML 的換行標籤
,再寫入數據庫;或者從數據庫中讀出文本數據時進行似的轉換操作。

這樣當服務器向網頁輸出這些文本數據時,原始的回車狀態才能得到再現。

但是,由於設計失誤(或系統有意限制),服務器端可能就不會做這樣的處理。從而導致這些文本信息中的換行符無法呈現出換行效果,取而代之的是一個小空格。

(下圖爲 cnBeta 網站對評論文本的兩種不同處理方式:左側爲普通評論,可能爲了限制各條評論的高度、防止惡意刷屏,系統未做換行符轉換處理;右側爲熱門評論,系統進行了處理。)

如果服務器端因爲疏忽沒有做換行符轉換處理,那麼在前端是否可以用最小的代價來補救?這時,pre-wrap 就可以發揮作用——無需做任何的額外處理,直接爲文本的容器元素設置 {white-space: pre-wrap;} 樣式,就可以還原多行文本的真實狀態。

在 IE6,7 下變通實現 pre-wrap

經常反覆測試,我們找到了在 IE6,7 下變通實現 pre-wrap 效果的方法。

比如,有如下 HTML 結構:

這是一段多行文本數據其中某些文本行會非常長從而溢出容器比如你現在看到的這行行與行之間有換行符但沒有使用 HTML 換行標籤

我們需要將 .content 元素設置爲 pre-wrap 樣式,理想情況下只需要編寫如下 CSS 代碼就可以了。、

123.content {white-space: pre-wrap;}

但爲了應付 IE6,7,我們需要將上述 CSS 代碼修改如下:

12345.content {white-space: pre-wrap;*white-space: pre;*word-wrap: break-word;}

這樣就可以了,我們在各瀏覽器中實測一下,可以發現我們需要的效果完美實現。

當然,你可能注意到了,我們使用了一點兒 CSS hack。別擔心,它們條理清晰並且容易維護,我覺得這可以接受。在面對低能瀏覽器的時候,我們只能給予它們一些額外關照。

原理

如果你是一個實用主義者,那麼文章到這裏已經結束了。你可以把代碼存下然後走人,或者繼續瀏覽CSS魔法的其它文章。如果你是一個充滿好奇心的 CSS 學習者,那麼我很樂意與你一起來分析一下它的實現原理。

在上面的最終版 CSS 代碼中,很顯然對於標準瀏覽器,我們是用正常的 {white-space: pre-wrap;} 來實現所需效果的。而對於 IE6,7,我們使用了 CSS hack,讓它接受額外的樣式聲明,使用其它方法來實現似 pre-wrap 的效果。

首 先,在 IE6,7 下,{white-space: pre-wrap;} 這條樣式聲明由於不能識別而被丟棄,於是我們爲 .content 另外設置了 {white-space: pre;} 的樣式。我們已經很熟悉 pre 了,它的特性與我們想要的 pre-wrap 效果只有一點區別,即 pre 不允許自動換行,也就是說,較長的文本行可能會溢出其容器元素。

因此,接下來,爲了讓這些較長的文本行自動 換行,我們爲 .content 元素設置 {word-wrap: break-word;} 樣式(謹慎起見,我們用 CSS hack 將這條聲明隔離給 IE6,7;不過即使將它暴露給所有瀏覽器,它也是無害的)。這條聲明負責對 .content 元素內的文本行進行約束,並強制其換行。也就是說,{white-space: pre;} 完成了識別文本換行符的任務,剩下的自動換行的任務交由 {word-wrap: break-word;} 來完成。

回到前面的原理分析,其實我們會發現一個矛盾,{white-space: pre;} 很倔犟地不願換行,而 {word-wrap: break-word;} 則要求內部文本自動換行。面對這樣的衝突,瀏覽器如何決斷?

插播 word-wrap 的相關資料

CSS 發展至今經歷了多個版本,但它對文本排版的控制仍然不夠精確和靈活。於是微軟的 IE 瀏覽器開發了一些私有屬性,擴展了 CSS 的文本排版功能,尤其可貴的是,這些擴展屬性大多考慮到了非拉丁語系語言的排版規則。由於這些私有擴展屬性確實很有價值,它們被整理並收錄到了 CSS3 草案中。
word-wrap 屬性就是其中很有代表性的例子。它決定了文本行超過容器的邊界時是否斷開轉行。目前這一屬性已經得到了絕大多數主流瀏覽器的支持。

杯具的 IE6 和 IE7

再 來看一下上面的表格,我們發現 pre-wrap 是從 CSS 2.1 纔開始引入的屬性值。然而,目前網民使用最爲廣泛的 IE6 和 IE7 瀏覽器都是基於 CSS1 和部分 CSS2 的,它們完全不能識別 pre-wrap,當然也無法實現 pre-wrap 的空白符處理行爲。

在瘋狂地問候了微軟、IE 及其相關人等之後,網頁開發者們還是不得不面對這個問題——如何在 IE6,7 下實現 pre-wrap 的效果?

在 CSS 中,控制文本換行方式的屬性有很多,當發生衝突的時候,某些屬性在文本排版中的優先級更高,因而會在衝突中勝出,決定最終的文本樣式。很顯然,在上面的這 起衝突中,{word-wrap: break-word;} 更加強勢,倔犟的文本行最終還是乖乖地換行了。

 

轉自:http://www.php302.com/a/ie7-white-space-pre-wrap.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章