如何在 IE6,7 下實現 white-space: pre-wrap;

HTML 的空白符處理規則

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

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

然而在有些時候,咱們但願 HTML 源碼中的多個連續空格在網頁瀏覽器中能夠真實地呈現,或者須要源碼中的換行符能起到真正的換行做用。因而,咱們發現了 <pre> 標籤,它能夠真實還原它內部文本的空白符的真實狀況。web

因而咱們常常會把一段表示計算機代碼的文本放進 <pre> 標籤中,它們在瀏覽器中會表現出自身的空格縮進和換行效果,而不須要咱們增長額外的樣式和標籤來控制它的縮進和換行。數據庫

隨着對 CSS 的瞭解不斷深刻,咱們發現,原來這一切都是 white-space 屬性在安排。<pre> 元素之因此如此神奇,是由於它自身具備 {white-space: pre;} 這一默認樣式。瀏覽器

white-space 屬性

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

white-space 屬性值一覽表
屬性值 空白符 換行符 自動換行 最先出現於
normal 合併 忽略 容許 CSS 1
nowrap 合併 忽略 不容許 CSS 1
pre 保留 保留 不容許 CSS 1
pre-wrap 保留 保留 容許 CSS 2.1
pre-line 合併 保留 容許 CSS 2.1

(注:在 CSS1/2 下,white-space 屬性只可應用於塊級元素;在 CSS 2.1 下,可應用於全部元素。)學習

若是咱們須要某個容器元素具備相似 <pre> 元素的空白符處理行爲,則爲它設置 {white-space: pre;} 樣式便可。測試

對 pre-wrap 的需求

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

所以,{white-space: pre;} 樣式有時候並不能知足咱們的指望。好比,在某些不須要特別嚴謹的場合,或者排版某些對換行不敏感的代碼片段(好比 HTML 或 CSS)的時候,咱們不但願代碼片斷中的一行長代碼令它的容器元素產生水平滾動條,由於那樣不便閱讀。咱們但願在這種狀況下,長代碼自動換行就好。spa

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

對 pre-wrap 的另外一種需求

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

表單中的文本域(<textarea> 元素)能夠接受包含換行符的文本數據,這是它有別於文本框(text 類型的 <input> 元素)的重要特徵之一,因此咱們一般也稱它爲「多行文本框」。

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

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

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

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

[現象:cnBeta 評論的兩種不一樣形態]

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

杯具的 IE6 和 IE7

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

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

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

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

好比,有以下 HTML 結構:

<div class="content">這是一段多行文本數據
其中某些文本行會很是長從而溢出容器好比你如今看到的這行
行與行之間有換行符
但沒有使用 HTML 換行標籤</div>

咱們須要將 .content 元素設置爲 pre-wrap 樣式,理想狀況下只須要編寫以下 CSS 代碼就能夠了。

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

但爲了應付 IE6,7,咱們須要將上述 CSS 代碼修改以下:

.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;} 來完成。

插播 word-wrap 的相關資料

CSS 發展至今經歷了多個版本,但它對文本排版的控制仍然不夠精確和靈活。因而微軟的 IE 瀏覽器開發了一些私有屬性,擴展了 CSS 的文本排版功能,尤爲難得的是,這些擴展屬性大多考慮到了非拉丁語系語言的排版規則。因爲這些私有擴展屬性確實頗有價值,它們被整理並收錄到了 CSS3 草案中。

word-wrap 屬性就是其中頗有表明性的例子。它決定了文本行超過容器的邊界時是否斷開轉行。目前這一屬性已經獲得了絕大多數主流瀏覽器的支持。

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

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

 
 
G
M
T
 
 
Detect languageAfrikaansAlbanianAmharicArabicArmenianAzerbaijaniBasqueBelarusianBengaliBosnianBulgarianCatalanCebuanoChichewaChinese (Simplified)Chinese (Traditional)CorsicanCroatianCzechDanishDutchEnglishEsperantoEstonianFilipinoFinnishFrenchFrisianGalicianGeorgianGermanGreekGujaratiHaitian CreoleHausaHawaiianHebrewHindiHmongHungarianIcelandicIgboIndonesianIrishItalianJapaneseJavaneseKannadaKazakhKhmerKoreanKurdishKyrgyzLaoLatinLatvianLithuanianLuxembourgishMacedonianMalagasyMalayMalayalamMalteseMaoriMarathiMongolianMyanmar (Burmese)NepaliNorwegianPashtoPersianPolishPortuguesePunjabiRomanianRussianSamoanScots GaelicSerbianSesothoShonaSindhiSinhalaSlovakSlovenianSomaliSpanishSundaneseSwahiliSwedishTajikTamilTeluguThaiTurkishUkrainianUrduUzbekVietnameseWelshXhosaYiddishYorubaZulu
 
AfrikaansAlbanianAmharicArabicArmenianAzerbaijaniBasqueBelarusianBengaliBosnianBulgarianCatalanCebuanoChichewaChinese (Simplified)Chinese (Traditional)CorsicanCroatianCzechDanishDutchEnglishEsperantoEstonianFilipinoFinnishFrenchFrisianGalicianGeorgianGermanGreekGujaratiHaitian CreoleHausaHawaiianHebrewHindiHmongHungarianIcelandicIgboIndonesianIrishItalianJapaneseJavaneseKannadaKazakhKhmerKoreanKurdishKyrgyzLaoLatinLatvianLithuanianLuxembourgishMacedonianMalagasyMalayMalayalamMalteseMaoriMarathiMongolianMyanmar (Burmese)NepaliNorwegianPashtoPersianPolishPortuguesePunjabiRomanianRussianSamoanScots GaelicSerbianSesothoShonaSindhiSinhalaSlovakSlovenianSomaliSpanishSundaneseSwahiliSwedishTajikTamilTeluguThaiTurkishUkrainianUrduUzbekVietnameseWelshXhosaYiddishYorubaZulu
 
 
 
 
 
 
 
 
 
Text-to-speech function is limited to 200 characters
 
 
Options : History : Feedback : Donate Close
相關文章
相關標籤/搜索