杂谈 height, line-height, display, vertical-align

先声明一下,测试环境为 IE7+ , Chrome, Firefox, 不爱测那么多浏览器。。。

 

坑爹的行内元素

HTML:

<div>
    <span>文字</span>
</div>

CSS:

body {
    font-family: '宋体';
    font-size: 12px;
}

 

这种情况下,span 和 div 都是由文字撑开高度,但是高度各有不同。

div: 所有浏览器都是height: 12px

span: IE7 IE8 Chrome 是height: 12px,  IE9 IE10 Firefox 是height: 14px

 

第一个例子就这么坑爹,可见这里的水多深。我们先来看line-height,在Firefox 是line-height: 15px,而IE9/10 是 line-height: normal;

也许你会说这就是原因所在,于是设置了以下这段CSS

body {
    font-family: '宋体';
    font-size: 12px;
    line-height: 1em;
}

 

很不幸,没用!虽然设置line-height后,各个浏览器的 line-height 是一样了,但是高度还是不同。

再来看display

span {
    display: block;
}

 

好吧,这样就相同了,设置成 inline-block 也是可以的。有这样的问题还要行内元素干嘛,inline 全部设置成 inline-block 算了

 

垂直对齐

HTML:

<div>
    <span>文字</span>
</div>

CSS:

span {
    display: inline-block;
    *display: inline;
    *zoom: 1;
}
body {
    font-family: '宋体';
    font-size: 12px;
    line-height: 1em;
}
div {
    border: 1px solid red;
    height: 18px;
}
span {
    border: 1px solid blue;
}

 

所有浏览器表现一致

这也是垂直对齐最简单的情况,如果出现文字 + 图标,特别是图标的高度和文字不同时,情况会复杂很多。

 

文字 + 图标 

我们先来看图标比文字高度小的情况:

HTML:

<div>
    <span>文字<button></button></span>
</div>

CSS:

span {
    display: inline-block;
    *display: inline;
    *zoom: 1;
}
body {
    font-family: '宋体';
    font-size: 12px;
    line-height: 1em;
}
div {
    border: 1px solid red;
    height: 18px;
}
span {
    border: 1px solid blue;
    vertical-align: top;
}
button {
    border: none;
    margin: 0;
    padding: 0;
    background-color: green;
    width: 10px;
    height: 10px;
    vertical-align: baseline;
}

 

因为大多css reset 喜欢设置 vertical-align: baseline,所以这里加了这么一句。渲染结果主要有以下两种: 

IE8+, Chrome

IE7, Firefox

 

第二个结果比较费解,第一它以底部对齐,第二它撑大了高度,span不再是12px,而是又变成了第一个问题中的14px。

 

看来baseline这种对齐方式很不靠谱,所以我决定采用 top(text-top 和 text-bottom 在 Firefox 中有点问题,span 高度会变为13px,所以不用这两个),这回所有浏览器都表现一致了

如果想实现垂直居中对齐,也许有些人会用vertical-align: middle,但是这方式特别不靠谱,就像刚才我们设置成 baseline 一样,各个浏览器表现还不一样,所以我的解决方法是:

1. vertical-align: top; 先把元素定到顶部

2. position: relative; top: 1px 进行位移调整

 

文本垂直居中

刚才说了图标的垂直居中,现在来看文本,一般的做法是 height 和 line-height 设置成相同的值

 

<div style="height: 20px;line-height: 20px">文字</div>

这样肯定能垂直居中,但是如果里面不是文本节点,而是套了一个行内元素呢?

 

<div style="height: 20px;line-height: 20px"><span>文字</span></div>

如果 span 是 display: inline; 那么还是会居中。

 

大家都知道 IE 有个 hasLayout,这里会有什么影响呢?

 

line-height 属性具有继承性,所以 span 的 line-height 也是 20px。

当 span 是行内元素,或者对于IE来说,是不具有 hasLayout 的时候,span 的高度小于 div,垂直居中表现完美。

当 span 是 inline-block,或者对于IE来说,具有 hasLayout 的时候,span 继承自父元素的 line-height 就会发挥作用,即撑满父容器。

 

对于IE8+ 和其他标准浏览器来说,只要这个盒模型的高度比 div 小,那么垂直居中还是正常的;如果比 div 大,就会顶部对齐

但对于IE7,不管这个盒模型多大,直接就顶部对齐了

 

所以呢,要套行内元素时,它只能是 display: inline (IE 下别触发hasLayout)

 

接着这个话题再复杂化一点,如果文本的实际高度,即一般都是12px,小于 height 和 line-height 的值,这时再加入一个图标,这时的垂直对齐是怎样的呢?

 

HTML:

<span>文字<button></button></span>

CSS:

span {
    display: inline-block;
    *display: inline;
    *zoom: 1;
}
body {
    font-family: '宋体';
    font-size: 12px;
    line-height: 1em;
}
span {
    border: 1px solid blue;
    height: 20px;
    line-height: 20px;
}
button {
    border: none;
    margin: 0;
    padding: 0;
    background-color: green;
    width: 10px;
    height: 10px;
    vertical-align: top;
}

 

结果分两种

IE8+, Chrome, Firefox

IE7

IE7这种行为真是匪夷所思,居然和 text-top 一样,但是如果把HTML改成下面这样就正常了

<span><span>文字</span><button></button></span>

 

这样看,IE好像把文本节点当作对齐的标准了。

 

所以如果有垂直对齐的需求,特别是 文本节点 + 行内元素 的组合,一定要给文本节点套一个 display: inline-block( IE 下触发hasLayout) 的行内元素,这样才能保证兼容性

posted @ 2012-08-25 00:59  越己  阅读(1301)  评论(1编辑  收藏