去除inline-block元素间间距的N种方法

这篇文章发布于 2012年04月24日,星期二,22:38,归类于 CSS相关。 阅读 599779 次, 今日 13 次 99 条评论

 

一、现象描述

真正意义上的inline-block水平呈现的元素间,换行显示或空格分隔的情况下会有间距,很简单的个例子:

<input /> <input type="submit" />

间距就来了~~
表单控件之间的间距例子

我们使用CSS更改非inline-block水平元素为inline-block水平,也会有该问题:

.space a {
    display: inline-block;
    padding: .5em 1em;
    background-color: #cad5eb;
}
<div class="space">
    <a href="##">惆怅</a>
    <a href="##">淡定</a>
    <a href="##">热血</a>
</div>

inline-block水平元素间的间距示意 张鑫旭-鑫空间-鑫生活

您可以狠狠地点击这里:inline-block元素间间距demo

这种表现是符合规范的应该有的表现(如果有人认为是bug就太()ay ()oy 了)。

不过,这类间距有时会对我们布局,或是兼容性处理产生影响,需要去掉它,该怎么办呢?以下展示N种方法(欢迎补充)!

二、方法之移除空格

元素间留白间距出现的原因就是标签段之间的空格,因此,去掉HTML中的空格,自然间距就木有了。考虑到代码可读性,显然连成一行的写法是不可取的,我们可以:

<div class="space">
    <a href="##">
    惆怅</a><a href="##">
    淡定</a><a href="##">
    热血</a>
</div>

或者是:

<div class="space">
    <a href="##">惆怅</a
    ><a href="##">淡定</a
    ><a href="##">热血</a>
</div>

或者是借助HTML注释:

<div class="space">
    <a href="##">惆怅</a><!--
    --><a href="##">淡定</a><!--
    --><a href="##">热血</a>
</div>

等。

三、使用margin负值

.space a {
    display: inline-block;
    margin-right: -3px;
}

margin负值的大小与上下文的字体和文字大小相关,其中,间距对应大小值可以参见我之前“基于display:inline-block的列表布局”一文part 6的统计表格:
inline-block元素间间隔大小与字体和文字大小之前的关系表截图

例如,对于12像素大小的上下文,Arial字体的margin负值为-3像素,Tahoma和Verdana就是-4像素,而Geneva为-6像素。

由于外部环境的不确定性,以及最后一个元素多出的父margin值等问题,这个方法不适合大规模使用。

四、让闭合标签吃胶囊

如下处理:

<div class="space">
    <a href="##">惆怅
    <a href="##">淡定
    <a href="##">热血</a>
</div>

注意,为了向下兼容IE6/IE7等喝蒙牛长大的浏览器,最后一个列表的标签的结束(闭合)标签不能丢。

在HTML5中,我们直接:

<div class="space">
    <a href="##">惆怅
    <a href="##">淡定
    <a href="##">热血
</div>

好吧,虽然感觉上有点怪怪的,但是,这是OK的。

您可以狠狠地点击这里:无闭合标签去除inline-block元素间距demo

无闭合标签与inline-block水平元素间距的去除 张鑫旭-鑫空间-鑫生活

五、使用font-size:0

类似下面的代码:

.space {
    font-size: 0;
}
.space a {
    font-size: 12px;
}

这个方法,基本上可以解决大部分浏览器下inline-block元素之间的间距(IE7等浏览器有时候会有1像素的间距)。不过有个浏览器,就是Chrome, 其默认有最小字体大小限制,因为,考虑到兼容性,我们还需要添加:
类似下面的代码:

.space {
    font-size: 0;
    -webkit-text-size-adjust:none;
}

您可以狠狠地点击这里(去年制作的一个简单demo):font-size:0清除换行符间隙demo

补充:根据小杜在评论中中的说法,目前Chrome浏览器已经取消了最小字体限制。因此,上面的-webkit-text-size-adjust:none;代码估计时日不多了。

六、使用letter-spacing

类似下面的代码:

.space {
    letter-spacing: -3px;
}
.space a {
    letter-spacing: 0;
}

根据我去年的测试,该方法可以搞定基本上所有浏览器,包括吃“东鞋”、“西毒(胶囊)”、“南地(沟油)”、“北钙(三鹿)”的IE6/IE7浏览器,不过Opera浏览器下有蛋疼的问题:最小间距1像素,然后,letter-spacing再小就还原了。

七、使用word-spacing

类似下面代码:

.space {
    word-spacing: -6px;
}
.space a {
    word-spacing: 0;
}

一个是字符间距(letter-spacing)一个是单词间距(word-spacing),大同小异。据我测试,word-spacing的负值只要大到一定程度,其兼容性上的差异就可以被忽略。因为,貌似,word-spacing即使负值很大,也不会发生重叠。

您可以狠狠地点击这里:word-spacing与元素间距去除demo

与上面demo一样的效果,这里就不截图展示了。如果您使用Chrome浏览器,可能看到的是间距依旧存在。确实是有该问题,原因我是不清楚,不过我知道,可以添加display: table;display:inline-table;让Chrome浏览器也变得乖巧。

.space {
    display: inline-table;
    word-spacing: -6px;
}

八、其他成品方法

下面展示的是YUI 3 CSS Grids 使用letter-spacingword-spacing去除格栅单元见间隔方法(注意,其针对的是block水平的元素,因此对IE8-浏览器做了hack处理):

.yui3-g {
    letter-spacing: -0.31em; /* webkit */
    *letter-spacing: normal; /* IE < 8 重置 */
    word-spacing: -0.43em; /* IE < 8 && gecko */
}

.yui3-u {
    display: inline-block;
    zoom: 1; *display: inline; /* IE < 8: 伪造 inline-block */
    letter-spacing: normal;
    word-spacing: normal;
    vertical-align: top;
}

以下是一个名叫RayM的人提供的方法:

li {
    display:inline-block;
    background: orange;
    padding:10px;
    word-spacing:0;
    }
ul {
    width:100%;
    display:table;  /* 调教webkit*/
    word-spacing:-1em;
}

.nav li { *display:inline;}

也就是上面一系列CSS方法的组组合合。

九、结语

其他去除间距的方法肯定还有,欢迎大家通过评论方式进行补充。上文部分方法可能有测试不周全之处,因此,部分细节上可能会有纰漏,欢迎指正。

参考文章:Fighting the Space Between Inline Block Elements

(本篇完)

分享到:


发表评论(目前99 条评论)

  1. abaddonpoet说道:

    我只想说opera被干掉了,这是可喜可贺

  2. balulu说道:

    zan~

  3. 解决方法说道:

    左浮动也可以float: left;

  4. zhenjun115说道:

    这样可以去掉间隙:

    button1
    button2

    .btn-group { position: relative;}
    .btn-group > .btn { float: left }

  5. nicholasurey说道:

    这些方法会不会在代码压缩了之后出现问题

  6. 风雷灵鱼说道:

    我给input输入框写了vertical-align:top;还是会有纵向间距啊,虽然间距变小了,但还是会有,求解

    • afei说道:

      同样问题求解!

      场景:其父元素设置了font-size: 0;并给input设置了vertical-align:top;
      主要问题:在IE7(其他情况没问题),top和right又出现了1px的间距,求解

  7. vlon说道:

    在其父元素设置
    font-size: 0;
    letter-spacing: -4px;

    可以兼容IE7+、Firefox、chrome、opera、safari、sogo、360、uc,已测试过。

    • 邱dada说道:

      font-size: 0;是为了兼容哪些浏览器捏?
      测了一下,letter-spacing: -999px;就已经够用了…

  8. 未知说道:

    看完了所有的解决办法,感觉最好的解决方法是:忍了…………
    去掉空格其实是好方法方法(反正最后得压缩代码去空格的情况下就不用考虑这个间隙问题了……666)

  9. wen说道:

    vertical-align:top; 就可以了

  10. 周殿飞说道:


    div{display: inline-block;background: red;height: 20em;width: 40em;}
    div div{background: blue;height: 20em;width: 20em;}
    div div div{background: green;height: 10em;width: 20em;}
    有没有高手知道纵向之间为什么有间距

    • 哭笑说道:

      设置vertical-align:top。(vertical-align这个是设置元素的垂直排列的,
      用来定义行内元素的基线相对于该元素所在行的基线的垂直对齐;top就是垂直对齐文本的顶部
      。)

  11. 罗梦婷说道:

    font-size我在safari里没效果,是因为版本问题?

  12. 一顿乱写说道:

    真不想喷你,这么垃圾写上去有什么用,傻逼

  13. 肖国梁说道:

    嗯,代码放在评论中就全乱了,我提交的代码大家就不要用了,我想说的是可以去除空格,但不一定非得在HTML中去除呀,可以在JS中隐形的去除,这样也不会觉得很别扭

  14. 肖国梁说道:

    这篇文章写的不错,不过这些方法都是有不太好使的,有人说浮动来解决,如果用浮动的话就没必要写成inline-block了,因为违反了初衷,我有一个笨的方法就是在JS里面把它们给处理掉
    引入JQUERY后,
    var se=$(‘.space’);
    var se_html=se.html();
    se_html=se_html.replace(/\s*</g,'\s*/g,’>’);
    se.html(se_html);

    • ww说道:

      思路不错,瑕疵是加载慢的话,画面一开始还是会有间距,适合不太在意体验的页面上用。

  15. Pulsate说道:

    第七个
    .space {
    word-spacing: -6px;
    }
    .space a {
    word-spacing: 0;
    }

    我使用发生重叠,chrome

  16. riophae说道:

    刚才试了试 display: table; 发现在 Chrome 和 Safari 下有效, 但是 Firefox 还是有问题; 后来换了个思路, 给 inline-block 级别元素设置 display: table-cell; 问题立刻解决.

    • 皱凯凯凯凯说道:

      这个半font-size间隔的问题是由空格或者换行等字符引起的?float可以解决问题,很好理解。但是设置display: table-cell是什么原理呢?它把那字符怎么了?

  17. Unreal说道:

    只需要给父元素加上 display:table 就行了,亲测有效,有bug请联系我:ekpg@msn.com

  18. zhu说道:

    博主,我测了一下,word-spacing这个方法是有效的,但值要改为-8px。 letter-spacing的值为-8px,在chrome和firefox下可以,但在IE下又是无效的,请问这是为何?

  19. mabi说道:

    找到另一种比较兼容的解决方案,由于留言不能发布代码,故写在了百度博客上,大家可以去看看http://hi.baidu.com/hbswyb/item/cf3da3312fc04408ceb9fe80
    方案的基本思路就是间隙由空格产生,需要在每个行元素后面增加一个空的元素使用负边距来消除空格,一个空格大概是8px宽。

    上一条评论可以删除啦。

  20. mabi说道:

    除了在页面结构删除多余空格,其他方法没一个能够兼容所有浏览器,这么写不能向后兼容,而且问题多多,建议这篇文章删除,以免误导大家。

  21. 任光辉说道:

    font-size:0; 在pc上基本没什么问题,但在手机上清除不了间距,看来这问题不休止啊~~~~

  22. 任光辉说道:

    五个div,每一个width:20%;
    letter-spacing:.31em;
    在我的chrome下最右边有1-2像素的空白,
    手机上也是。那个方法不好用啊。

  23. kueen说道:

    旭哥,经过测试,34.0版本的chrome下使用word-spacing毫无问题,难道是版本的原因? 因此突发奇想,为什么chrome没有版本切换功能

  24. 轩脉刃说道:

    最终使用font:0px这样的方法解决了。。。

  25. 思齐说道:

    font-size:0 在ie6下不管吧??

  26. 独自流浪说道:

    设置font-size:0,在特殊情况下,会导致IE8卡死耶

  27. DS说道:

    font-siez:0;的方法很坑爹啊,还是改变排版吧

  28. snowinmay说道:

    浮动就行了呀

  29. yetazhan说道:

    有能在低端的手机浏览器上处理这个问题的方法吗

  30. vimest说道:

    还真是font-size的方法比较完美

  31. lan说道:

    测试了很多方法觉得这个还行
    .nav ul{font-size:0;}
    .nav li{display:inline-block; font-size:14px;}
    .nav li{*display:inline;}

  32. zoowar说道:

    这是什么原因呢?在我的电脑上所有的浏览器我都测试一遍了,根本就没有出现可耻的空隙。连超级变态的IE6我都看了下,还是没有出现。这个问题真的很奇怪。

  33. bz说道:

    博主,第六个方法letter-spacing在ie6下无效,第七个方法word-spacing设置足够大的时候会在(ie6,chrome)中发生重叠

  34. 一鹿说道:

    老早以前就发现这个问题了 我都是用写到一行上来解决 结果代码看上去很乱 博主这不错 吸收了…… 呵呵

  35. wyysf说道:

    opera下也有最小字体问题,兼容性好实用的是负margin!

  36. helloint说道:

    无闭合标签去除inline-block元素间距demo
    这个demo在ie8(ie9调试)下最后一个元素低1像素.

  37. 超毛说道:

    有时候这个间隙挺好的,比如数字页码之间的间隙,但IE居然没间隙,还得对IE写个hack

  38. luhuan说道:

    最近刚好碰到这个问题,就用了第一种笨办法

  39. 瞬间的永恒说道:

    以前遇到这种问题,都是马虎的忽略啦,这次好好学习了

  40. 小斯说道:

    之前用font-size:0,但是在safari不管用,只好用float顶替了。。。。。表示当时没想到还有这么多种方法,作者好才啊

  41. claycheng说道:

    怎么不写写你和姑娘的故事啦

  42. 马潇湘说道:

    今天突然想这个地方来,就来看看!~

  43. alex说道:

    图片用font-size: 0;
    文字则用letter-spacing和word-spacing + display:table ;

    学到了!

  44. zz说道:

    真是及时雨啊,刚遇到这个问题。

  45. wmtimes说道:

    怎么感觉有些写法很无赖,但是确实是解决了bug

  46. 丿随风说道:

    已经习惯有空就来楼主的空间逛逛了,必须顶!

  47. 低调@旋律说道:

    letter-spacing ie8 ie9 safari中的间距消失了 ie6 7 ff opera ch的间距依旧

  48. 低调@旋律说道:

    试了第五种方法 设字体的方式 ie6 和ie7 显示1px的间距,chrome下没有间距,safari下有间距没有消失,不是很管用那

  49. 低调@旋律说道:

    还真没研究过这个问题,现在正在做表单,我用的span元素包围每一个表单项,没有设置边距值,表单项与表单项之间的间距就是用的这个换行间隔组成的,看到你的这篇文章,的确受教了呵呵。鑫哥有没有关于表单样式设计的文章呢。

  50. 小杜说道:

    一直font-size:0这种解决方法,现在的chrome没有最小字体的问题了

    • 罗梦婷说道:

      你好,我在safari里没效果,是版本问题?因为我是在windows下下的safari,版本比较低,高版本的有效果吗?

      • 柚子说道:

        是不是safari是不是也有最小字体限制?可以加上-webkit-text-size-adjust:none试试