有哪些好方法能處理 display: inline-block 元素之間出現的空格?


瀉藥。

此乃歷史問題。不難理解,空白字元壓縮(white space collapse)是西文排版的必然結果。SGML、TeX都是如此。不過對於不使用空格作為詞分界的語言,比如東亞語言來說,就造成了問題。所以其實這是行內(inline)的問題(inline-block也是將其本身作為inline,內部作為block),題目或許應修改下。

在CSS控制空白字元壓縮特性尚未得到普遍支持之前,可行的辦法有:

1. CSS trick,如設font-size/line-height為0。但此種方法副作用過多,完全不可取

2. 某些元素不寫結束標籤不會產生額外的空白節點,比如li元素。缺點是不是所有元素都可以用這個方法,且要求使用HTML語法,而不能用XHTML語法。

3. 特殊的標籤寫法,如:

& &>&1& &>&2& &>&3&&>&

個人認為此種也是削足適履的方式,不建議。

4. 刪掉空白。缺點,源代碼排版會面臨困難。

5. 我認為目前來說最優雅的方法,使用不產生額外空白節點或者支持空白控制的模板語言。比如Jade、Smarty({strip} | Smarty)等。缺點,你不是直接寫HTML,即使沒有其他使用模板的必要。另外閱讀生成的代碼比較困難。不過這兩個缺點對於專業前端工程師來說基本上不成為問題。


真是討厭,七夕發這樣的問題,我是回答呢還是回答呢?

誠然,如@賀師俊 老師所言,這是一個歷史遺留問題。

空白字元壓縮(white space collapse)是西文排版的必然結果。SGML、TeX都是如此。不過對於不使用空格作為詞分界的語言,比如東亞語言來說,就造成了問題。

我們知道造成「inline-block」元素空隙的本質是 HTML 中存在的空白符(whitespace)。

於是最近有人在「www-style」發郵件提出:增加一個「white-space: ignore」來忽略空白符。並且通過 JS 來模擬了一個「white-space:none」去除 inline-block 空隙的 Demo。

其實早在 2005 年,《CSS3 Text Effects Module》中就有了「white-space-collapse」屬性,用來設置或者檢索元素內包含的空白字元。有如下取值:

  1. collapse:將一系列空白摺疊為一個單獨的字元(或者在某些情況下,沒有字元)

  2. preserve:阻止用戶代理摺疊空白,換行符保留為強制換行符。

  3. preserve-breaks:該值將與「collapse」一樣摺疊空白字元,但保留換行符為強制換行符。

  4. discard:拋棄所有空白。

現在該屬性被轉移到《CSS Text Level 4》中,該規範中, 「white-space」分為兩部分:

  1. white-space-collapse

  2. text-wrap

所以,按照原題目,最「優雅」的解決方案應該是使用「white-space-collapse:discard」

ul{ white-space-collapse:discard; }
li{ display: inline-block;}

但是,由於該屬性本身存在的諸多問題以及瀏覽器廠商沒有及時跟進和實現,也只能望洋興嘆,需要更多中文社區的人參與討論並完善規範。

時間過的真快,一下子回到現實。

曾經在《inline-block 前世今生》一文中,我極度推薦用「font-size:0」的方法實現去除空隙的目的。但現在越發覺得問題之所在:父元素設置「font-size:0」,那麼所有子元素必須重置一遍,帶來嚴重的耦合問題。

.dib-wrap {
font-size:0;/* 所有瀏覽器 */
*word-spacing:-1px;/* IE6、7 */
}
.dib-wrap .dib{
font-size: 12px;
letter-spacing: normal;
word-spacing: normal;
vertical-align:top;
}
@media screen and (-webkit-min-device-pixel-ratio:0){
/* firefox 中 letter-spacing 會導致脫離普通流的元素水平位移 */
.dib-wrap{
letter-spacing:-5px;/* Safari 等不支持字體大小為 0 的瀏覽器, N 根據父級字體調節*/
}
}
.dib {
display: inline-block;
*display:inline;
*zoom:1;
}

當然,不符合人類的奇怪HTML寫法也是可以達到這個目的的,如果蛋疼,請嘗試:

&

    &1&&2&&3&&

    li{ display:inline-block; }

    使用 Smarty 等模版語言雖然可以變相解決掉空白的問題,但是如果僅僅是為了解決空隙問題,引入模版成本相對較高。對於那些有情懷的想調試頁面的「設計師」妹子情何以堪!

    綜上所述,「font-size:0」未嘗不是一個簡單快速的 CSS 技巧。但請記住這只是一種技巧,切不可舍本求末。更多請參閱:《inline-block 未來》

    在這個杜蕾斯紛飛的夜晚,或者在這個右手很忙的夜晚,是選擇杜蕾斯還是右手,你們感受一下吧!


    @一絲的這篇inline-block 前世今生行文規範是吾輩楷模


    這是我自己最常用、也認為最靠譜的兩個方法:

    • 父元素設置 font-size:0,inline-block 的元素 font-size 再單獨設置為正常大小;
    • 刪除 HTML 文件中 inline-block 元素之間的空格和空行。


    這個問題收藏過一篇文章

    Fighting the Space Between Inline Block Elements

    把裡面提到的方法摘要過來。

    1. Remove the spaces 去掉源代碼中的空白

    & & one&& two&& three& &

    &

    & &one&&two&&three& &

    &

    & &one&&