有哪些好方法能处理 display: inline-block 元素之间出现的空格?

关注者
233
被浏览
35,971

14 个回答

泻药。

此乃历史问题。不难理解,空白字符压缩(white space collapse)是西文排版的必然结果。SGML、TeX都是如此。不过对于不使用空格作为词分界的语言,比如东亚语言来说,就造成了问题。所以其实这是行内(inline)的问题(inline-block也是将其本身作为inline,内部作为block),题目或许应修改下。

在CSS控制空白字符压缩特性尚未得到普遍支持之前,可行的办法有:

1. CSS trick,如设font-size/line-height为0。但此种方法副作用过多,完全不可取

2. 某些元素不写结束标签不会产生额外的空白节点,比如li元素。缺点是不是所有元素都可以用这个方法,且要求使用HTML语法,而不能用XHTML语法。

3. 特殊的标签写法,如:

<ul

><li>1</li

><li>2</li

><li>3</li

></ul>

个人认为此种也是削足适履的方式,不建议。

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写法也是可以达到这个目的的,如果蛋疼,请尝试:

<ul
><li>1</li
><li>2</li
><li>3</li
></ul>
li{ display:inline-block; }

使用 Smarty 等模版语言虽然可以变相解决掉空白的问题,但是如果仅仅是为了解决空隙问题,引入模版成本相对较高。对于那些有情怀的想调试页面的「设计师」妹子情何以堪!

综上所述,「font-size:0」未尝不是一个简单快速的 CSS 技巧。但请记住这只是一种技巧,切不可舍本求末。更多请参阅:《

inline-block 未来

在这个杜蕾斯纷飞的夜晚,或者在这个右手很忙的夜晚,是选择杜蕾斯还是右手,你们感受一下吧!