float:left; vs display:inline; vs display:inline-block; vs display:table-cell; 左浮动;行内展示;行内块展示;表格单元格展示。

283

我的问题:

  1. 在专业网页设计师中,是否偏好其中任何一种方法?

  2. 在绘制网站时,浏览器是否偏好其中任何一种方法?

  3. 这只是个人喜好吗?

  4. 我是否遗漏了其他技巧?

注:上述问题涉及设计多列布局


float:left;

http://jsfiddle.net/CDe6a/

float:left image

创建列布局时,这是我经常使用的方法,似乎可以正常工作。然而,父元素会折叠在自己身上,所以你需要记住之后添加 clear:both; 。另一个 缺点 是无法纵向对齐文本。

display:inline;

这似乎可以解决父元素折叠的问题,但会添加空格。

http://jsfiddle.net/CDe6a/1/

display:inline image

从html中删除空格似乎是解决此问题的最简单方法,但如果你对你的html非常挑剔,则不希望这样做。

http://jsfiddle.net/CDe6a/2/

no html whitespace image

display:inline-block;

看起来与 display:inline; 完全相同。

http://jsfiddle.net/CDe6a/3/

display:inline-block image

display:table-cell;

http://jsfiddle.net/CDe6a/4/

display:table-cell image

完美地工作。

我的想法:

我肯定错过了很多东西,例如会破坏布局的某些例外情况,但是 display:table-cell; 似乎效果最好,而且我似乎总是在 clear:both; 上犯错误。我已经阅读了许多关于这方面的文章和博客,但没有一个给出了我应该在网站布局中使用什么的明确答案。


4
参考html5boilerplate和Twitter Bootstrap的实现方式,并坚持使用它们。 - Robert Niestroj
1
有一篇关于解决CSS空格问题的好文章在css-tricks上:https://css-tricks.com/fighting-the-space-between-inline-block-elements/ - Lea Rosema
我尝试使用display: inline属性,但发现它不能正确处理子元素的填充。但是,如果我使用display: inline-block,这将自动处理。请参见链接 - http://codepen.io/prashdeep/pen/rVOyvd 请告诉我您对此的看法。 - zilcuanu
6个回答

203

在你提到的选项中:

  • float:left;
    我不喜欢使用浮动,因为需要额外的标记来清除浮动。就我而言,在CSS规范中,整个float的概念设计得很差。不过现在我们无法改变这一点。但重要的是它确实有效,并且在所有浏览器上都有效(甚至包括IE6 / 7),所以如果你喜欢,就可以使用它。

如果您想支持IE6或IE7,则可能不需要使用用于清除浮动的附加标记,只需使用:after选择器即可,但这并不是一个选项。

  • display:inline;
    这不应该用于布局,但在IE6 / 7中,display:inline; zoom:1是对于破损的inline-block支持的回退解决方案。

  • display:inline-block;
    这是我最喜欢的选项。它在所有浏览器中都能正常且一致地工作,但有一个例外情况是IE6 / 7仅支持某些元素。但请参见上文,以获取解决此问题的hacky解决方案。

inline-block的另一个重要注意事项是,由于其行内特性,元素之间的空格与文本单词之间的空格被视为相同,因此在元素之间可能会出现间隙。虽然有一些解决方法,但没有一种是理想的。(最好的方法就是在元素之间根本不使用空格)

  • display:table-cell;
    这是另一个可能会遇到浏览器兼容性问题的选项。老版本的IE根本不支持它。但即使对于其他浏览器,值得注意的是,table-cell旨在在被样式化为tabletable-row的元素内部使用;单独使用table-cell并不是预期的方式,因此您可能会发现不同的浏览器会以不同的方式处理它。

还有其他你可能错过的技术吗?是的。

  • 既然你说这是为多列布局,你可能想知道一个 CSS 多列布局特性,然而它并不被所有浏览器支持(即使在IE9中也不支持IE,且所有其他浏览器都需要厂商前缀),所以你可能不想使用它。但这是另外一种选择,你确实有提出这个问题。

  • 还有CSS FlexBox特性,它旨在允许文本从盒子流向盒子。这是一个令人兴奋的特性,将允许一些复杂的布局,但这仍然非常处于开发阶段--请参见http://html5please.com/#flexbox


2
你不需要额外的标记来清除浮动,可以看看我的答案。 - Lie Ryan
2
我总是使用inline-block,因为它恰好适用于这些情况。 - Rápli András
1
一种很好的方法来移除display:inline-block创建的空白,是在容器元素上设置font-size为0,然后在内联元素本身上设置所需的字体大小。这样可以避免需要在HTML中删除空格。 - AlexMorley-Finch
1
@AlexMorley-Finch:确实,那是一个好的解决方案。但请注意,如果您使用em作为字体大小,则无法使用该方法。这意味着它可能不适用于所有情况。您还可以查看我单独发布的此答案,其中涵盖了此问题以及处理空格问题的其他选项。 - Spudley
当使用服务器端生成网站/输出,如PHP或JavaScript时,你很少会遇到空格问题。只要你考虑到它,一切都会变得干净简单。 - Angry 84
显示剩余2条评论

35
我通常使用float: left;并添加overflow: auto;解决父元素折叠问题(为什么这样做有效,overflow: auto将扩展父元素而不是添加滚动条,如果您没有给它明确的高度,overflow: hidden也可以起作用)。我需要大部分垂直对齐的需求都是针对菜单栏中一行文本, 可以使用line-height属性来解决。如果我真的需要垂直对齐块级元素,我会在父元素和垂直对齐的项目上设置明确的高度,绝对定位,顶部50%和负边距。
我不使用display: table-cell的原因是当您拥有的项超过网站宽度时它的溢出方式。table-cell将强制用户水平滚动,而浮动将包装溢出菜单,使其仍可使用,无需水平滚动。
float: left和overflow: auto最好的一点是,它们可以一直使用到IE6,而无需任何hack,可能甚至更早。

enter image description here


这是一个非常好的观点,在许多流行的教程中都没有提到。有几个问题:这在不同的浏览器中是否经过实际测试?您选择的绘制两个块之间分隔符(例如导航和内容)的方法是什么?我问这个问题是因为如果上面的div高度不同,那么这将会很困难。 - Shital Shah
@ShitalShah:我不太确定你指的是什么,“this”,但我已经实现了无数个水平菜单,float left 和 overflow 在我看来是在许多不同的浏览器,新旧都能实现水平菜单最干净、最可靠的方法。对于添加分隔符,我通常使用左边框(或背景图像用于更高级的分隔符,如果您不需要关心旧浏览器,那么可以使用 CSS3 边框图像)。我不太明白你所说的不同高度是什么意思,能否解释得更详细些或提供一个 fiddle? - Lie Ryan
1
这让我对清理有了更多的了解,我不知道溢出可以这样做。我习惯于使用:after方法,在其中添加content:“。”和visibility:hidden。感谢您提供这个信息。 - chasethesunnn

9
我认为这取决于您需要什么:
  1. 如果只是需要三列布局,我建议使用 float

  2. 如果需要用于菜单,可以使用 inline-block。对于空格问题,您可以使用一些技巧,如 Chris Coyier 在这里描述的http://css-tricks.com/fighting-the-space-between-inline-block-elements/

  3. 如果需要创建一个多选项,其宽度需要在指定的框内均匀分布,则我更喜欢使用 display: table。这在某些浏览器中可能无法正确工作,因此这取决于您的浏览器支持情况。

最后,可能最好的方法是使用 flexbox。该规范已经几次更改,因此还不稳定。但是一旦确定,这将是我认为最好的方法。


加1分给Chris Coyier的文章链接。在他的列表中还有一个额外的方法,就是YUI的Pure CSS网格使用的方法:https://github.com/yui/pure/blob/master/src/grids/css/grids-core.css - Web_Designer

4

仅供参考,补充Spudley的回答,如果您知道列宽,还可以使用position: absolute和边距。

对我来说,在选择方法时主要问题是是否需要让列填满整个高度(等高),如果您不太在意旧浏览器,则table-cell是最简单的方法。


4
我更喜欢使用inline-block,虽然float也很有用。table-cell在旧版IE中无法正确渲染(inline-block也是如此,但我经常使用zoom: 1; *display: inline hack)。如果您有子元素的高度比父元素小,则float会将它们带到顶部,而inline-block有时会出错。
大多数情况下,浏览器都能正确解释一切,除非是IE。你总是要检查确保IE不会出问题,例如table-cell概念。
实际上,最终归结为个人偏好。
您可以使用一种技术来消除空白,即将父元素的font-size设置为0,然后将font-size返回给子元素,尽管这很麻烦,而且很恶心。

如果“你总是要检查IE不会出问题”,那么你总是会失望的。呵呵。 (另一方面,他说你应该始终检查你想支持的每个IE版本中你的代码是否有问题,这是非常正确的) - Spudley

1
我更喜欢使用inline-block,但是float仍然是一种有用的方式来组合HTML元素,特别是当我们有一个元素应该靠左,另一个应该靠右时,使用float可以写更少的代码,而在许多其他情况下,inline-block也能很好地工作。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接