實現單行文字兩端對齊時,使用   當作空格和使用 white-space: pre 的原生空格有什麼區別?哪個更好一些?

最近有一個項目頁面中製作的時候,UI 大致是這樣的(這是一個發表評論的頁面):

優 點:XXXXX

缺 點:XXXX

友善度:XXXX

使用心得:XXXX

為了保證對齊,所以我在寫 HTML 的時候,在「優」和「點」之間用了4個 nbsp 當空格。但是 leader 在檢驗的時候說這裡不能用 NBSP,要用空格,然後在 CSS 裡面加 white-space:pre。

因為為了保證項目進度(事實上我們最近很缺人~),我也沒有太多的時間去和 leader 討論這個,就按照他說的進行了修改。

但是我還是很想弄清楚這樣有什麼不好的,因為我記得剛剛開始學 XHTML 的時候,裡面貌似有規定空格和大於小於什麼的都需要轉義,所以空格一般都是用 NBSP。

雖然只是小問題,但是還是想請教一下,非常感謝……


首先提問者並沒有把他的意圖描述清楚。如果意圖都未描述清楚,自然就難以進行「哪種更好一些」的比較,因為比較的基準就不存在。而描述原始意圖的補充說明現在已經被刪掉了,得查看日誌才看得到。這裡我照錄一下:

最近有一個項目頁面中製作的時候,ui大致是這樣的(這是一個發表評論的頁面):

優 點:XXXXX

缺 點:XXXX

使用心得:XXXX

為了保證對齊,所以我在寫html的時候,在「優」和「點」之間用了4個nbsp當空格。但是leader在檢驗的時候說這裡不能用nbsp,要用空格,然後在css裡面加white-space:pre。然後說現在基本沒有網站用nbsp當空格了。

因為為了保證項目進度(事實上我們最近很缺人~),我也沒有太多的去和leader討論這個,就按照他說的進行了修改。

但是我還是很想弄清楚這樣有什麼不好的……因為我記得剛剛開始學xhtml的時候,裡面貌似有規定空格和大於小於什麼的都需要轉義,所以空格一般都是用nbsp

雖然只是小問題,但是還是想請教一下,非常感謝……

另外,這種情況下,大家做頁面會用空格嗎?因為我目前沒有發現有什麼css屬性可以比較好的控制文字的兩邊對齊顯示……

可見提問者的意圖是文字排版對齊。理論上說,所有排版樣式需求都應該以CSS達成。所以無論是用NBSP還是一般SP+white-space:pre都是不正確的。原理@梁海已經說過了,不重複。

正確的做法是@米粽 說的text-align:justify。但是還需要加上CSS3草案的text-justify:distribute 。

「正確的做法」存在的問題是:除了IE之外,尚無瀏覽器實現text-justify:distribute。且IE必須還加上text-align-last:justify。

是的,儘管IE常為我們所不齒,但是在文字排版和國際化方面,IE是做的最好的。僅就兩端分布對齊這個特例而言,IE領先了其他瀏覽器10年以上。

@梁海 提到的CJK的justify問題也確實存在。直到最近WebKit引擎才實現CJK的text-align:justify(即相當於text-justify:inter-ideograph)。不過即使很早就已經實現CJK兩端對齊的Gecko,由於沒有實現text-align-last,所以無法實現最後一行或單行的兩端分布對齊。而本例的本質恰好是單行的兩端分布對齊。

@梁海 和其他人提到的workaround包括:全形空格和letter-spacing。從效果上說是可行的。但是letter-spacing是一個糟糕的方案,因為你必須手動計算letter-spacing,而且對於字數不同的label,letter-spacing也是不同的。這就造成了內容和格式的強耦合,完全違背了內容與樣式分離的要求。這很好理解,因為letter-spacing並沒有表達出真正的設計意圖(兩端分布對齊)。這是我在博客、論壇、問答等中始終強調的,CSS是一門針對排版和設計的DSL,其可維護性來自於準確的表達設計意圖。

下面說一下我個人推薦的解決方案:

一、實用主義方案:使用全形空格。解說如下:

全形空格從某種程度上說可以是一種workaround。但是這個世界上並沒有絕對的事情。比如,對於作品名,有&標籤,但是有多少中文前端開發者使用?幾乎沒有。這是因為在西方,書名要用斜體,因此通過&標籤附加上樣式是順理成章的。但是在中文裡習慣用書名號,而不是斜體,所以儘管&可以提供額外的語義,但是也沒有人去用。我們可以思考一個問題:書名號是內容呢還是樣式呢?

在輕率的給出答案之前,可以再思考一下&的例子。應該用引號,還是應該用&標籤?這個問題倒是中西共通的。

經過仔細思考,我想大家會發現,結構和語義細化到何種程度實際上是有彈性的。固然用&標籤提供了更精細的語義,但是在許多場合未必有用。回到書名號的例子,從一般感覺來說,標點符號會被作為內容,但是如果考慮到書名號在橫排時用《》,而在豎排時用浪線,就會發現書名號也有作為樣式的一面。

就提問者的用例而言,恰好也是一個方塊字排版才會出現的樣式需求。(阿拉伯文、泰文等或許也會有類似的需求,這超出我的知識範圍,請懂這些文字排版的同志補充了。)在西文里是沒有這樣的樣式的。而在傳統中文排版中,如@梁海 所說,恰恰就是以空格來控制的。因此我們可以將全形空格理解為類似標點符號的作用。這樣我們就不用為沒有用CSS達成效果而耿耿於懷了。

二、理想主義方案:

label {

text-align: justify;

text-align: end; /* 對於除了IE之外的瀏覽器用尾對齊覆蓋之前的兩端對齊方式 */

text-align-last: justify;

text-justify: distribute;

}

這裡的理念是:

不同瀏覽器的表現不一樣是可接受的。

在IE和將來正確實現CSS3-text模塊的瀏覽器中將兩端分布對齊。【註:因為手頭沒有IE9和IE10無法測試,有可能需要增加額外的hack。】

在當前除IE以外的主流瀏覽器中將右對齊。這是一種常見的label對齊設計,這裡假設以此作為fallback是能為設計師所接受的。

以上。


建議各位選用 @賀師俊 給出的方案。:)

- - -

看了問題補充說明的日誌才知道原來有那麼一大段說明,於是才明白是個什麼狀況。其實最好還是把補充說明寫出來。沒看到原來補充說明的同學請親手翻閱日誌……

NBSP(U+00A0,Unicode 叫它「NO-BREAK SPACE」,HTML 里可用「nbsp;」表示)是常規空格(U+0020,就是最常用的西文、半形空格)的一個變體。NBSP 和常規空格的區別包括:它不允許斷行(所謂「NO-BREAK」);另外因為它不常規,所以它一般不會被當作普通空格合併。

NBSP 本來應該用在文本中需要避免斷行的地方,比如數值的數字和單位之間(比如「100 km」不應該在中間換行)。但由於種種原因它被濫用了,人們不希望空格合併的時候就用它。這是一種已經成為事實標準的骯髒做法……不過 Unicode 里確實也沒有別的更合適的空格字元可以這麼用了。

當 NBSP 被用來控制字元的位置,問題就更大了。因為 NBSP 和常規空格對字體來說是幾乎一樣的,所以字體渲染時常規空格該有多大 NBSP 就會顯示為多大,所以在不同的字體渲染情況下可能會有意料之外的效果(主要是不同字體的空格與 em(即字型大小)之比不一樣)。尤其用 NBSP 來控制中文字元位置的時候,因為 NBSP 和中文字元所佔寬度(1 em)之比在不同字體中不一樣,所以實在太傻了。

white-space: pre 這個值「prevents user agents from collapsing sequences of white space」[1],它相當於讓普通空格實現了一些人們常常用 NBSP 實現的事情。受這條 CSS 屬性控制的普通空格當然也會受字體渲染的影響——在和字體的關係方面,普通空格和 NBSP 沒什麼區別。

之前問題補充說明中提到的情況,應該有這兩種方案可以考慮:

  • 全形空格(U+3000)

    這應該是最直截了當的方案,問題只在於污染了文本(多了字元)。全形空格的寬度永遠等於 1 em。
  • letter-spacing: 2em

    這應該是最乾淨的方案,最符合這個情況的本質。

另外,有人提到了「text-align: justify」,這個不太好用。因為,據我所知,CSS3 之前它在 IE 之外的許多瀏覽器里不會對中文字元有效果(CSS3 里明確定義了這個值對 CJK 字元的效用,所以最新的瀏覽器開始支持了),除非你在兩個字中間加上一個普通空格(但這樣還不如用全形空格那麼乾淨),而且還得建立一個寬度固定的 box。

我想,這個問題中最關鍵的一點在於眾所周知的「內容和格式分離」,這也是 CSS 為 HTML 以及互聯網帶來的最大變革。 這是前端工程師們必須理解的——支不支持就是另一回事了。

我們應該明白:

  • 常規空格是內容。它的地位類似與任何英文字母和標點的字元,但又的確有些特殊的性質。
  • NBSP 是內容,它是一種特殊的空格。如今它被濫用來控制格式,用內容來控制格式實在很臟。

  • white-space: pre 當然是格式,但它在這種情況下要達到許多人期望的效果則一樣是依賴很髒的內容——多個用來控制格式的空格。

  • 全形空格也是內容。但為什麼用它來控制漢字位置就更能接受一些呢?因為中文向來有用和漢字一樣寬的空格控制格式的習慣,比如學校里教導的「寫作文時每段開頭空兩格」,而且全形空格和漢字等寬,能完美控制漢字的位置問題。

  • letter-spacing: 2em 是格式,它是用為西文字體排印準備的技術來控制中文字元的間距。

[1]「This value prevents user agents from collapsing sequences of white space. Lines are only broken at preserved newline characters.」 http://www.w3.org/TR/CSS2/text.html#white-space-prop


我補充一下:firefox12開始支持 -moz-text-align-last 從而實現單行(末行)東亞文字的兩端對齊@梁海

上面是我寫的一個例子

主要的CSS如下:

text-align: justify;

text-justify: inter-ideograph;/* IE 私有屬性 */

-moz-text-align-last: justify;

-ms-text-align-last: justify;/* IE 8+ 支持 */

text-align-last: justify;/* IE5.5+ 支持 */

可惜我測試了Chrome 22.0.1215.0 依然沒有支持,Opera 那貨就別提了。等到 webkit 都支持了 用這種方法做兩端對齊就非常不錯了!@賀師俊


看到這個問題,我也遇到過,解決方案:

1。使用全形空格

2。給第二個字加一個span,margin-left:1em


本人很少使用空格去對字元進行樣式設定(也不提倡),所以沒法回答你的原本問題

使用空格來對頁面進行排版的優缺點

優點:省事,避免殺雞用牛刀

缺點:不同字體的空格大小不同

css可以用來控制字體,兩邊對齊的方案也有,不過都不完美。

不過個人觀點是,正文裡面的文字排版沒必要那麼講究吧。實在追求美觀就用圖片吧。

對 @梁海 同學的使用letter-spacing的辦法表示讚賞。


nbsp;被視為字元,相當於一個英文字母或者數字,會受到font-family/font-size/font-weight影響。 而且碰到font-family:"arial,simsun"這種定義就更麻煩了,空格使用的是Arial的寬度,而非宋體寬度。

通常情況下為了對齊,不要用空格,text-indent或者padding-left可以更精確,也不會受到其他因素影響。

如果是為了純中文文本對齊的話(補充問題),使用全形空格是比較好的辦法,上面提到寬度污染都可以避免。


插入 nbsp; 對於想插入空格而言像是硬編碼。

推薦css方式。


我建議使用#12288;(全形空格)代表空格,萬一你的項目後期想更換字體,使用nbsp;的話在不同的字體下差異很大。。。


貢獻一個更好記的空格形式 emsp; 這個空格的寬度正好是1em。

另外還有 ensp; 這是0.5em的空格。

所以可以寫成:

優 emsp; emsp; 點

優 ensp; 缺 ensp; 點

使 用 心 得

來源:小tips: 使用 等空格實現最小成本中文對齊 ? 張鑫旭


網上找到的方法,巧妙的利用偽類,其實是多行文本的對齊

代碼如下:

h1:after{display:inline-block;content:"";overflow-x:hidden;overflow-y:hidden;width:600px;height:40px;}

display必須為inline-block,因為需要與h1的文本後面產生換行,才能誘發瀏覽器將h1視為多行文本,第一行文本就會有兩端對齊效果了。後面的overflow等屬性與h1一致。

&&&