关于line-height导致的布局出错

line-height:属性设置行间距参数(行高,不允许使用负值)。

通常情况下,我们使用line-height是为了使内容上下居中,对行内元素实现高度的控制,通常情况下,line-height的设置都可以很好的完成它所要承担的工作,只是也有的时候,会出现一些特例,比如会导致布局出现问题。

1:line-height基础

W3C中,对于line-height这样描述:line-height属性会影响行框的布局,在应用到一个块级元素时,它定义了该元素中基线之间的最小距离而不是最大距离。

line-heightfont-size的计算值,分为两半,分别加到一个文本行的内容的顶部和底部。可以包含这些内容的最小框就是行框。

line-height的取值可以包含以下几种格式:

  • normal:默认取值,会根据内容设置合理的行间距。其实就是按照字体的大小进行高度设置。
  • number:设置为数字,此数字会与当前的字体尺寸相乘来射行间距。
  • length:设置固定的行间距。比如使用pxem等固定单位进行设置。
  • %:和number相同,基于当前字体的尺寸的百分比设置行间距。这个只是number的另外一种写法,和number完成的效果相同。唯一的区别在于子元素继承时,百分比时,子元素继承的是父元素计算后的line-height值,这个值,对所有子元素都是固定的,当为number时,子元素继承的是系数,子元素的line-height值,是根据子元素自身的font-size相乘获得的,子元素的line-height值是可能不同的。
  • inherit:规定从父元素继承line-height属性的值。
注:在父元素没有设置line-height属性时,元素中自带的line-height属性是normal,但是当一个元素设置了line-height属性时,它的所有的子元素,都会继承这一个line-height属性。

二:line-height的基本使用方法。

首先要明确一点,只有文本行出现的标签,line-height才是有效的,如果只是单纯的标签之间的嵌套,line-height是不会有作用的。比如:


.a{
    line-height:30px;
}



<div class = "a"></div>


事实上,上面这个标签在页面上是不会占据任何位置的,如果没有其他的marginpaddingborder的设置,这个div的大小就是width:100%height:0;因为它是一个空的。就算是嵌套了几层这样的标签,只要标签中没有文本出现,都是相同的情况。

那么如果有文本出现呢?这个就很明显了,就会根据line-height的设置,显示包含文本的标签的高度,并且使得文本的显示上下居中。这里就不考虑如果你把line-height设置的值,小于字体大小的情况了,应该没有人会去这么做吧?

简单的测试代码:这里就以设置line-height=30px进行对比:


//HTML代码
<div class = "b">这个是设置了height=30px,作为下面设置line-height对比所用。</div>
<div class = "a" style = "line-height:30px;">
       <div>这里设置了一个固定的line-height,值为30px</div>
</div>


//CSS代码
.a{border:1px solid #aaa;margin-top:10px;}
.a div{border:1px solid #eee;}
.b{height:30px;border:1px solid #aaa;margin-top:10px;}

该段代码的显示如下图:

line-height基本
由图中可以看出,两个模块显示的高度是相同的,唯一的差别就是,第二个div中的文字上下居中了,当然,这种设置也只适合单行文本的居中,如果你的文本是多行内容的话,就需要使用其他的方法,来实现文本的居中了,这里不做说明。

更多其他的line-height取值,及其不同取值的对比,请点击:line-height不同取值的显示demo

三:在浏览器下,会影响布局的情况

上面提到的line-height的使用方法,在各主流浏览器下都是可以兼容的,都是没有问题的,但是看看下面这段代码。


//CSS代码
.news{
    width:960px;
    margin:0 auto;
    font-size:12px;
}
ul,li{
    list-style:none;
    margin:0;
    padding:0;
}
.list{
    overflow:hidden;
    zoom:1;
    border:1px solid #aaa;
    margin-top:10px;
}
.list li{
    width: 148px;
    float: left;
    line-height: 30px;
    border-bottom: 1px #CCC dotted;
    border-right: 1px #ccc dotted;
    text-indent: 20px;
}


//HTML代码
<div class = "news">
    <ul class="list">
        <li>AAAAA:<span style = "font-size: 13px;">1112222</span></li>
        <li>BBBBBBB</li>
        <li>CCCCCCC</li>
        <li>DDDDDDD</li>
        <li>EEEEEEE</li>
        <li>FFFFFFF</li>
        <li>GGGGGGG</li>
        <li>HHHHHHH</li>
        <li>IIIIIII</li>
    </ul>
</div>

运行一下这段代码,然后看看在浏览器下,有什么区别?

看看这里的截图吧:

line-height基本

line-height基本

不知道你有没有看到这样的效果呢?

在有些浏览器下,会出现排版错位哦,如果你没有看到这样的效果,那么使用IE浏览器试试吧,或者你可以直接点击:line-height导致排版错位demo

这是什么原因导致的呢?如果你熟悉浮动的规则,那么你肯定一眼就能确认问题导致的因素,就是因为第一个浮动元素的高度,增加了,导致后面的元素在换行时,被卡在了第一个li的后面,可是,第一个li的高度,为什么增加了呢?

如果只是在一个项目中,突然发现了这么一个问题,那么要去确认这个问题的来源,你旧的一个个的去排除,然后确认出,是哪一个CSS的设置,导致了这个问题的出现,但是在我给出的这个最简单的demo里,相信你一眼就可以看出问题的原因了吧。因为第一个li中,有一个子标签的字体设置的大小,比原来的字体大小增加了1像素。其实在有些浏览器下,没有出现排版错乱,是因为这个字体变化太小,如果你把字体变成20px,那么在所有浏览器下,都会出现这个问题的。

如果想要看到其他浏览器下的这个排版的错误,那你可以点击这里:line-height在所有浏览器下导致排版错位demo

至于为什么会出现这个情况,我还没有能找到合理解释的原因,不过,出现这个排版错误的情况可以这么解释一下:在一段文本中,如果使用一个行内元素的标签,来对一段文字进行特殊处理,如果这个特殊处理中,有改变文字的字体大小,但又没有设置line-height属性为normal,那么就会影响到这个文本的父元素的所占的高度。而如果是在这个父元素上面,直接改变文字大小,则不会有影响。

所以呢,如果你要改变某一段文字的字体大小,使得这块内容更为突出,但是又不想对布局产生影响,那么你可以有两种方法进行处理:1,在该模块的父元素上面改变字体大小,这个不太好,因为会使得该段内容字体整体都会变化。2,在需要改动的部分,再次设置line-height:normal。这样就可以解决上面出现的问题了。你可以点击这里查看:line-height导致排版错位的;两种解决方法demo

这样看来,引起布局出错的根本原因,就是line-height的继承问题。那么具体为什么会出现这个影响呢?为什么出现这个原因,我现在还找不到一个合理的解释,如果您看了这篇文章,并且对此有过研究,希望您能指点。

文章写作的起因来自CSDN论坛的一个帖子:请教IE8兼容视图下CSS样式显示不正确问题

本文地址:http://www.zhangyunling.com/?p=21

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>