您现在的位置:首页 >> 前端 >> 内容

详解line-height与vertical-algin

时间:2017/1/16 9:59:44 点击:

  核心提示:关于line-height与vertical-align这两个属性,相信很多人都知道这两个属性的用法,但往往很多时候并不能达到我们想要的效果,看了很多网上的教程,写的都不是很明白,今天就把我的研究成果...

关于line-height与vertical-align这两个属性,相信很多人都知道这两个属性的用法,但往往很多时候并不能达到我们想要的效果,看了很多网上的教程,写的都不是很明白,今天就把我的研究成果分享给大家吧,如有觉得不对的地方,请留言帮助我一起改进。

首先我们来看下官方给出的line-height属性的解释:line-height属性会影响行框的布局。在应用到一个块级元素时,它定义了该元素中基线之间的最小距离而不是最大距离。line-height 与 font-size 的计算值之差(在 CSS 中成为“行间距”)分为两半,分别加到一个文本行内容的顶部和底部。可以包含这些内容的最小框就是行框。

<!DOCTYPE html>  
<html lang="en">  
<head>  
<meta charset="UTF-8">  
<title>Document</title>  
</head>  
<body style="margin: 0">  
<p style="background: black;line-height: 100px;">  
<span style="background: red;font-size: 40px">English</span>  
</p>  
</body>  
</html>

根据官方的解释,p的的高度应该为100px,然而在浏览器debug模式下的高度确实108px,而且上下的半行距并不一样

详解line-height与vertical-algin

这到底是为什么呢?这个问题曾困

关于line-height与vertical-align这两个属性,相信很多人都知道这两个属性的用法,但往往很多时候并不能达到我们想要的效果,看了很多网上的教程,写的都不是很明白,今天就把我的研究成果分享给大家吧,如有觉得不对的地方,请留言帮助我一起改进。

首先我们来看下官方给出的line-height属性的解释:line-height属性会影响行框的布局。在应用到一个块级元素时,它定义了该元素中基线之间的最小距离而不是最大距离。line-height 与 font-size 的计算值之差(在 CSS 中成为“行间距”)分为两半,分别加到一个文本行内容的顶部和底部。可以包含这些内容的最小框就是行框。

根据官方的解释,p的的高度应该为100px,然而在浏览器debug模式下的高度确实108px,而且上下的半行距并不一样

详解line-height与vertical-algin

这到底是为什么呢?这个问题曾困扰我很长时间,最后查了多方资料,才知道原来在HTML5文档声明下,块状元素内部的内联元素的行为表现,就好像块状元素内部还有一个(更有可能两个-前后)看不见摸不着没有宽度没有实体的空白节点,这个假想又似乎存在的空白节点,我们可以称之为“幽灵空白节点”。这个幽灵空白节点有默认的字体大小和行高,所以上面的例子其实是这样的:

详解line-height与vertical-algin

左边框为span行内框(行内框即内联元素形成的框,包括了内联元素因为line-height形成的上下间距),右边框为幽灵空白节点的行内框,它们两的高度都是100px(父元素指定了line-height:100px),因为一行内的所有内联元素都要相对父元素的基线(本行内行高最大的第一个内联元素的基线)对齐,而空白幽灵节点的默认字体小于40px,因此空白幽灵节点行内框向下移动了一点。

如果我们同时指定父元素字体的大小:

此时结果和我们预期的一样:

详解line-height与vertical-algin

我们可以看到此时p的高度和指定的行高是一样的,之所以会这样,是因为我们给父元素加上font-size的时候就给幽灵空白节点指定了字体大小,只要让其字体大小和以及行高都和内联元素(该例中也就是span元素)一样,那么它们的行内框的顶部以及基线都会在同一条水平线上,也就不会上移或者下移了。(ps:家里好冷,我的双手已经快僵了)

好了,发了下牢骚,现在我们来浓重介绍下line-height的好基友(ps:怎么突然想起了全酱,好尴尬),也就是vertical-align,之所以叫它们是好基友,是因为vertical的表现基本依赖于line-height。

同样,我们先来看一下官方给出的vertial-algin的解释:vertial-algin属性定义行内元素的基线相对于该元素所在行的基线的垂直对齐。允许指定负长度值和百分比值。这会使元素降低而不是升高。在表单元格中,这个属性会设置单元格框中的单元格内容的对齐方式

描述
baseline 默认。元素放置在父元素的基线上。
sub 垂直对齐文本的下标。
super 垂直对齐文本的上标
top 把元素的顶端与行中最高元素的顶端对齐
text-top 把元素的顶端与父元素字体的顶端对齐
middle 把此元素放置在父元素的中部。
bottom 把元素的顶端与行中最低的元素的顶端对齐。
text-bottom 把元素的底端与父元素字体的底端对齐。
length  
% 使用 "line-height" 属性的百分比值来排列此元素。允许使用负值。
inherit 规定应该从父元素继承 vertical-align 属性的值。

根据官方的解释我们来看一个例子:

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>Document</title>  
</head>  
<body style="margin: 0">  
    <p style="background: black;">  
        <span style="background: red;font-size:60px;line-height: 60px">English</span>  
        <span style="background: blue;font-size:20px;line-height: 60px;vertical-align: bottom">English</span>  
    </p>  
</body>  
</html>

大多数情况下,我们期待的是两个English的底部应该对其,然而结果确实这样的:

详解line-height与vertical-algin

两个English的底部并没有对其,但细心的同学可能会发现,两个内联元素是上下垂直对齐的,为什么会产生这种情况呢,我们的代码明明是指定vertical-align:bottom,别急,我们慢慢来分析。

首先,它们的行高是一样的,都是60px,咦,好像有点感觉了,给内联元素添加vertical-align样式,其基准是不是以该元素的行高(也即该元素的行内框)来算呢,没错,你猜对了,给第二个内联元素添加vertical-align:bottom后,它们的行内框的底部在同一条水平线上,因为他们的行高都是60px,此时他们的顶部也在同一条水平线上,因为第二个元素的上下间距是一样的,此时就产生了两个元素上下垂直居中的效果,虽然我们指定的vertical-align:bottom。

如果代码是这样:

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>Document</title>  
</head>  
<body style="margin: 0">  
    <p style="background: black;">  
        <span style="background: red;font-size:60px;line-height: 60px">English</span>  
        <span style="background: blue;font-size:20px;line-height: 20px;vertical-align: bottom">English</span>  
    </p>  
</body>  
</html>

结果就和我们预期的一样了:

详解line-height与vertical-algin

这里因为第二个元素的行高为20px,和其字体的大小一样,所以其字体内容的底部刚好就是其行内框的底部,也就得到了我们想要的结果了。

好了,解决了这个问题,我们再来看一个例子:

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>Document</title>  
</head>  
<body style="margin: 0">  
    <p style="background: black;">  
        <span style="background: red;font-size:60px;line-height: 100px">English我</span>  
        <span style="background: blue;font-size:20px;line-height: 20px;vertical-align: text-bottom">English</span>  
    </p>  
</body>  
</html>

按照官方表面的解释,我们期待的应该是蓝色English行内框的底部应该和红色红内框内容的底部对齐,然而结果是这样的:

详解line-height与vertical-algin

我们可以明显的看到蓝色English并没有和红色English的内容的底部对齐,读到这里,可能很多同学都在想,就一个属性,咋就这么多坑呢,呵呵,其实不是坑多,而是我们没有仔细的理解css官方的释义:

text-bottom 把元素的底端与父元素字体的底端对齐。
注意这句话:父元素字体的底端。这里其实有个陷阱,它这里的对齐是根据父元素内的幽灵空白节点的底端来对齐的,在不给父元素设置字体大小和行高的情况下,幽灵空白节点有个默认的字体大小和行高,这个默认的值和红色English的行高和字体大小是不一样,这也就导致了和我们预期的结果不一样的效果。

如果我们给父元素加上行高和字体大小:

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>Document</title>  
</head>  
<body style="margin: 0">  
    <p style="background: black;font-size:60px;line-height: 100px">  
        <span style="background: red;font-size:60px;line-height: 100px">English我</span>  
        <span style="background: blue;font-size:20px;line-height: 20px;vertical-align: text-bottom">English</span>  
    </p>  
</body>  
</html> 
详解line-height与vertical-algin

此时的结果就和我们预期的一样了,之所以会这样,是因为幽灵空白节点的行高和字体大小与红色English的行高和字体大小一模一样。

属性值top和text-top,它们刚好和bottom以及text-bottom相反,我就不赘述了,关于属性值middle、sub、supper,我们下次再说,不知不觉以及零点了,该睡觉了,真累

扰我很长时间,最后查了多方资料,才知道原来在HTML5文档声明下,块状元素内部的内联元素的行为表现,就好像块状元素内部还有一个(更有可能两个-前后)看不见摸不着没有宽度没有实体的空白节点,这个假想又似乎存在的空白节点,我们可以称之为“幽灵空白节点”。这个幽灵空白节点有默认的字体大小和行高,所以上面的例子其实是这样的:

 

详解line-height与vertical-algin

左边框为span行内框(行内框即内联元素形成的框,包括了内联元素因为line-height形成的上下间距),右边框为幽灵空白节点的行内框,它们两的高度都是100px(父元素指定了line-height:100px),因为一行内的所有内联元素都要相对父元素的基线(本行内行高最大的第一个内联元素的基线)对齐,而空白幽灵节点的默认字体小于40px,因此空白幽灵节点行内框向下移动了一点。

如果我们同时指定父元素字体的大小:

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>Document</title>  
</head>  
<body style="margin: 0">  
    <p style="background: black;line-height: 100px;font-size:40px">  
        <span style="background: red;font-size:40px">English</span>  
    </p>  
</body>  
</html> 

此时结果和我们预期的一样:

详解line-height与vertical-algin

我们可以看到此时p的高度和指定的行高是一样的,之所以会这样,是因为我们给父元素加上font-size的时候就给幽灵空白节点指定了字体大小,只要让其字体大小和以及行高都和内联元素(该例中也就是span元素)一样,那么它们的行内框的顶部以及基线都会在同一条水平线上,也就不会上移或者下移了。(ps:家里好冷,我的双手已经快僵了)

好了,发了下牢骚,现在我们来浓重介绍下line-height的好基友(ps:怎么突然想起了全酱,好尴尬),也就是vertical-align,之所以叫它们是好基友,是因为vertical的表现基本依赖于line-height。

同样,我们先来看一下官方给出的vertial-algin的解释:vertial-algin属性定义行内元素的基线相对于该元素所在行的基线的垂直对齐。允许指定负长度值和百分比值。这会使元素降低而不是升高。在表单元格中,这个属性会设置单元格框中的单元格内容的对齐方式

 

描述
baseline 默认。元素放置在父元素的基线上。
sub 垂直对齐文本的下标。
super 垂直对齐文本的上标
top 把元素的顶端与行中最高元素的顶端对齐
text-top 把元素的顶端与父元素字体的顶端对齐
middle 把此元素放置在父元素的中部。
bottom 把元素的顶端与行中最低的元素的顶端对齐。
text-bottom 把元素的底端与父元素字体的底端对齐。
length  
% 使用 "line-height" 属性的百分比值来排列此元素。允许使用负值。
inherit 规定应该从父元素继承 vertical-align 属性的值。

 

 

根据官方的解释我们来看一个例子:

大多数情况下,我们期待的是两个English的底部应该对其,然而结果确实这样的:

详解line-height与vertical-algin

两个English的底部并没有对其,但细心的同学可能会发现,两个内联元素是上下垂直对齐的,为什么会产生这种情况呢,我们的代码明明是指定vertical-align:bottom,别急,我们慢慢来分析。

首先,它们的行高是一样的,都是60px,咦,好像有点感觉了,给内联元素添加vertical-align样式,其基准是不是以该元素的行高(也即该元素的行内框)来算呢,没错,你猜对了,给第二个内联元素添加vertical-align:bottom后,它们的行内框的底部在同一条水平线上,因为他们的行高都是60px,此时他们的顶部也在同一条水平线上,因为第二个元素的上下间距是一样的,此时就产生了两个元素上下垂直居中的效果,虽然我们指定的vertical-align:bottom。

如果代码是这样:

结果就和我们预期的一样了:

 

详解line-height与vertical-algin

这里因为第二个元素的行高为20px,和其字体的大小一样,所以其字体内容的底部刚好就是其行内框的底部,也就得到了我们想要的结果了。

好了,解决了这个问题,我们再来看一个例子:

按照官方表面的解释,我们期待的应该是蓝色English行内框的底部应该和红色红内框内容的底部对齐,然而结果是这样的:

 

详解line-height与vertical-algin

我们可以明显的看到蓝色English并没有和红色English的内容的底部对齐,读到这里,可能很多同学都在想,就一个属性,咋就这么多坑呢,呵呵,其实不是坑多,而是我们没有仔细的理解css官方的释义:

text-bottom 把元素的底端与父元素字体的底端对齐。
注意这句话:父元素字体的底端。这里其实有个陷阱,它这里的对齐是根据父元素内的幽灵空白节点的底端来对齐的,在不给父元素设置字体大小和行高的情况下,幽灵空白节点有个默认的字体大小和行高,这个默认的值和红色English的行高和字体大小是不一样,这也就导致了和我们预期的结果不一样的效果。

 

如果我们给父元素加上行高和字体大小:

详解line-height与vertical-algin

此时的结果就和我们预期的一样了,之所以会这样,是因为幽灵空白节点的行高和字体大小与红色English的行高和字体大小一模一样。

 

属性值top和text-top,它们刚好和bottom以及text-bottom相反,我就不赘述了,关于属性值middle、sub、supper,我们下次再说,不知不觉以及零点了,该睡觉了,真累

Tags:详解 解L LI IN 
作者:网络 来源:a409051987