text-align 属性在 chrome 下的一个 bug 产生的原因

StephenLi
  • 7k
<style>
  div {
    width:100%;
    text-align:center;
  }
  ul {
    display:inline-block;
    min-width:800px;
    margin:0 auto;
  }
  li {
    float:left;
    height:30px;
    width: 200px;
    margin-left:1px;
    margin-bottom:1px;
    list-style-type: none;
    background-color: lightblue;
  }
</style>
<div>
<ul>
  <li>1</li>
</ul>
<ul>
  <li>2</li>
</ul>
</div>

请输入图片描述
此时如果用 chrome 打开上述代码,会发现样式出现问题。但是如果我把 ul 标签的缩进改好,如下:

<div>
  <ul>
    <li>1</li>
  </ul>
  <ul>
    <li>2</li>
  </ul>
</div>

请输入图片描述
样式恢复正常,或者不加缩进,只是去除两个 ul 标签之间的空格:

<ul>
  <li>1</li>
</ul><ul>
  <li>2</li>
</ul>

请输入图片描述
样式同样恢复正常。我找了下原因,我认为是因为外层 divtext-align 属性起了作用,当 text-aligncenter 或者 right 时,就会出现这个现象,为 left 时正常。大家分析下出现 bug 的原因在哪儿呢?

这个问题的出现是因为我在回答 @Dont 提出的问题时发现的,虽然问题得到了解决,但是总感觉不知道根源出在哪儿。

回复
阅读 7.3k
4 个回答
mcfog
  • 21.9k
✓ 已被采纳

虽然看问题的第一眼就知道问题在于空的textNode,但这个问题也还是激发了我对缩进的兴趣,先回答这个问题,稍后研究下Chrome对HTML源码缩进的处理吧。


答案正文

其实就是ul和ul之间有个空格而已。HTML在inline的情况下,对标签之间一个或跟多的空格字符都会显示为一个空格

请输入图片描述

所以会有删掉换行那个空格就没了,至于text-align,压根和这个问题没关系,不信你可以调了text-align以后再反选页面观察一下,空格只不过是挪到第一个ul的后面去了而已

至于缩进排版以后和firefox天生没有,我认为是由于这个显示空格的行为通常是恼人的,不同浏览器各自有一些非标准方法来判断是否显示这个空格

// 我同意这个css本身质量不怎么样,为啥这里要用inline-block呢,效果上来看明明是块级的啊

ShingChi
  • 810

ul 里用了 display:inline-block,很明显错位空隙是因为它产生的,而不是 text-align 导致的。不仅在 chrome,其实在现代浏览器里,基本都会产生不同的效果。这个空隙的产生和字体大小,以及文字间距、空白处理等都有很大的关系,具体原理及研究可以查看下面这篇文章:

http://ued.taobao.com/blog/2012/08/inline-block/

n͛i͛g͛h͛t͛i͛r͛e͛
  • 31k

有意思。我希望你能做一个在线的例子让我检查一下这个 Bug,因为我复制了你的源代码在 jsfiddle 里,但奇怪的是并没有出现那个 Bug。难道和 Chrome 的版本有关?我现在用的是 v34

http://jsfiddle.net/nightire/w6SCh/


UPDATE:

啊哈,我终于重现了,由于 jsfiddle 默认的预览是嵌在 iframe 里,并且在潜入之前代码都是应该压缩了的,所以不会看到 Bug 的重现。但是如果单独载入以上代码就可以看到区别了。方法是用这个 urlhttp://jsfiddle.net/draft/,这个 url 会打开你最近一次 jsfiddle 代码的单页实例(前提是你有账号并且登录过了,而且只能看你自己的,不能看别人的)。

Anyway,确认之后我开始读你的 css,然后我注意到你对 ul 使用了 display: inline-block;

“为什么要做这个?”,我开始想。然后我意识到,因为里面的 li 都是向左浮动的,为了不让父容器也浮动起来,所以声明了行内块元素——这实际上很让我吃惊!我以前不知道这也可以清除浮动的。

With that said,既然是为了清除浮动,如果采用更常规的方法会怎么样呢?于是我把 display: inline-block; 改成了 overflow: hidden;,这是一个简易版的,不考虑低级别浏览器的实现方式。于是你题目中的 Bug 消失了……和 HTML 的缩进/空格没关系,和父元素上的 text-align 也没有关系,这其实是 inline-block 渲染上的问题。

我的记忆不太可靠了,模糊记得 inline-blockchrome 上的渲染问题已经是老生常谈了,不知道为什么一直没有得到改善。上上个月我还因为这个和人在 SO 吵了一架……

实际上我想说这件事情的另外一方面。inline-block 不应该用于布局/排版的目的上,就像这个属性值的名字所暗示的那样:inline-block 首先是 inline,其次才是 block
也就是说它本质上还是行内元素,只不过在此基础上使其拥有相对完整的盒模型,可以自由定义高度等等。但因为它本质上是行内元素,所以一个很重要的特点就是它是会受空格影响(white-space dependent)的——不管是 space 还是 tab 还是别的什么。

因此如果你在布局上依赖 inline-block 的话,你就得小心各种空格给你带来的困扰。我建议最好不要依赖它做布局,一定要用也请做一些处理吧。比如以下两个都不错:

http://jsfiddle.net/nightire/w6SCh/1/

inline-block导致的,推荐看下《一丝的inlinle-block的前世今生》

1 篇内容引用
宣传栏