line-height,vertical-align及图片居中对齐问题根源解析

关于图片居中对齐的问题,进入前端行业虽然有一段时间了,觉得本身懂了,但是实际上仍是只知其一;不知其二,找了一些博客来看了一下,可是感受讲的有点碎,看完仍是只知其一;不知其二css

查阅了一下《css权威指南》,结合遇到的问题,这才了解到前先后后的问题根源。html

 

主要的问题以下:前端

1.line-height是个什么东西,范围在哪里,具体应用于什么元素?浏览器

2.vertiacal-alignline-height有什么关系,元素对齐究竟是一个什么样的过程。wordpress

3.图片对齐和文本对齐有什么区别?布局

4.浮动元素为何对齐会出现问题?测试

-------》解答这些问题,牵涉的碎片化知识:字体

基线,底端,行内框,行框,行距,替换元素及非替换元素,对齐ui

下面围绕着上面的三个问题,以及相应的碎片化知识点来进行解析问题。spa

通常来讲,之因此不了解vertical-align,是由于不清楚对齐后面的这些碎片化知识,而这些也是不少博客在解析的时候经常忽略的地方。

 

先说结论:

1.line-height是行高,主要做用是在文本上下行间距,基于文本产生影响文本元素位置的做用,对于行内元素的位置影响显著,可是对于块元素的影响甚微。

 

2.vertical-alignline-height的关系是:line-height是vertical-align的对齐依据。vertical-align主要是影响行内元素的对齐,不影响块元素布局

而决定行内元素对齐的有两个因素,1.元素自己的height(相似于图片和按钮等替换元素)2.还有其余spanem非替换元素的line-height。行框经过计算heightline-height,来将各个行内元素与行内的基线进行对齐。

可是当产生浮动的时候,浮动会对行内元素的布局产生特殊影响,所以不会按照原先的方式来进行对齐,此时设置了vertical-align每每没有效果

 

3.图片的对齐是将本身的底端,也就是图片的最下端与行框的默认基线进行对齐,对齐依据是底端影响图片对齐的依据是图片的heightpaddingborder大小。

而文本元素,例如<span>文本内容</span>,则是将自身的行内框基线与行框基线进行对齐,对齐依据是基线。影响行内文本元素的依据是line-height,以及元素自身的font属性。

 

4.元素浮动以后其实是从正常的文档流中除去了(所以会出现高度塌陷,父容器收缩的问题),可是同时又对文档产生着影响(最经典的就是环绕效果)。元素浮动相似于一个被除名的黑户,虽然不在土地登记簿上,可是的的确确占用一块地方,所以别的元素也不能所以占据浮动元素的空间,可是由于是黑户,因此别的元素会环绕它,好像它不存在同样。

元素浮动以后,会尽力往容器的左右两侧移动,尽量地“漂”到容器的最高处。

 

所以此时行内元素浮动以后,浮动的规则会覆盖vertical-align的规则,这个时候设置vertical-align每每会出现问题,最典型的就是对一个段落中的图片进行浮动,而后设置vertical-align,可是发现每每不起做用。

 

可是文本元素浮动以后每每不会受到影响,由于line-height实际上仍是做用于文本元素的,虽然文本元素的容器位置“漂”到其余位置,可是里面的文本由于line-height,仍然有行高,能够影响到行内元素的布局。

 -------------------------------------------------------------------------------------------------------------------------------------------------

 ------------------------------------------------我是分割线---------------------------------------------------------------------------------------

 -------------------------------------------------------------------------------------------------------------------------------------------------

结论如何推导出来

看完这些结论,想必不少人也是一时之间有些不明白因此然,由于不一样的人掌握的背景知识是不一样的,而这些结论的关键偏偏是这些关键性的碎片化知识,它们起到了穿针引线的做用。下面来梳理一下,究竟是怎么得出结论的。

 

  -------------------------------------------------------------------------------------------------------------------------------------------------

 ------------------------------------------------我是分割线--------------------------------------------------------------------------------------- 

---------------------------------------------------------------------------------------------------------------------------------------------------

 

1.核心问题:关于对齐

对齐涉及到两个对象,要对齐元素及对齐对象,一个对象是不可能对齐。好比日常在战队,从高往低对齐,每一个人都要有一个参考系,对着参考系进行对齐。

而行内元素的对齐,除了行内元素自己,还有一个参考系,这个参考系就是行框的基线,而行框的基线依据于行内框元素的基线位置。

 

1.1对齐延伸问题:什么是基线?

每个文本元素自身都会有四条线,顶线,中线,基线,底线。而基线通常是指文本元素中以x字母为准,x字母的下边缘为该文本元素的基线。

而行高则是两个文本行基线之间的距离,每每使段落产生间距。

可是也能够这样理解,行高 = 字体大小 + 上半行距 + 下半行距(其中上下半行距相等,这个等式能够从图中推导出来)

 

每个文本元素和文本行元素,都会有一条基线,基线的位置受到文本的字体格式以及line-height的影响。

 

 

1.2对齐延伸问题:什么是行框和行内框?

 

在每个段落行内,不一样的行内元素除了包裹自身内容的内容框以外,还会自动生成一个行内框,其中没有标签包裹的文本会生成匿名行内框,不一样的行内框会根据各自不一样的line-height产生行间距,而行框则会恰好包括最高的顶端和最低的底端,从而来生成行框。

 

 

行内框的基线很好计算,可是行框的基线如何计算呢?

行框的基线是立足于行内框中基线最低的元素,也就是line-height最大的文本元素

 

 下面的例子,能够测试出来,当设置其中一个行内文本元素的line-height超过其余行内元素的line-height的时候,整个容器会自动扩展,位置也会往下移动。

<!DOCTYPE html>

<html lang="zh-cn">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>测试行框基线</title>

<style>

p{border:1px solid red;line-height:20px;}

span{line-height:40px;} /*能够在浏览器中取消一下,观察一下位置变更*/

</style>

</head>

<body>

<p>

<span>文本内容1</span>   匿名文本内容    <em>文本内容2</em>   <img src="" alt="">

</p>

</body>

</html>

  

 

 

1.3对齐延伸问题:什么是替换元素。

替换元素是指元素的内容自己并不是文档直接表现的,换句话说,就是不一样的页面中,浏览器不能肯定其具体内容的元素,好比图片,按钮,由于图片的内容取决于图片引用的src属性源,按钮的类型则依据于其input类型,所以浏览器是不能肯定今天img元素里面是一张美女图片,那么明天加载的页面里面img是否是一张美女图片。

 

除了替换元素,其余的元素就是非替换元素。非替换元素和替换元素在行框中的影响,主要是其高度计算方式,替换元素在行框中的位置是由其heightpaddingborder来决定,而非替换元素在行框中的位置则是其line-height和字体样式。

 

 

1.4对齐延伸问题:图片等替换元素在行框中有什么影响。

若是只有文本元素的话,那么行框是很好计算基线位置的,可是若是有图片按钮等替换元素的话,那么计算方式就会变的稍微复杂一些。

css中,有两种高度方式,一种是height,一种是line-height,这两种会决定元素的高度和位置,对于图片等行内替换元素来讲,height是行框计算的依据,line-height对图片、按钮不会产生影响。

所以,若是有图片在行内的话,那么图片的底端会对齐文本的基线。

 

那么,若是图片的高度高于其余行内框的总体高度,这个时候会发生什么呢?

 

图片会在对齐原来的行框文本基线的基础上,撑开高度,使行框最高点恰好包括图片的顶端。

所以,当p段落里面的line-height都是40px的时候,加入图片以后,行框的高度就会比没有加入图片以前多50px - 40px=10px高度,所以基线就会下移10px的高度。

<p style=”line-height:40px;”>

<span>文本内容1</span> <em>文本内容2</em> <img src="img/img2.png" height="50px" width="50px" alt="高度图片">

</p>

 

 

1.5对齐延伸问题:浮动对行内元素产生了什么样的影响。

设置一个元素的浮动以后,元素会从正常的文档流中去除,可是同时也会对原来的文档流产生一些影响。

 

能够设想一下,在长方形区域的水面上,有不少人都想要有一个固定位置的水床(浏览器盒模型布局),可是固定水床须要登记(告诉浏览器的如何布局计算)。忽然有一天,有一我的想要在长方形区域的最左侧建一个水床(设置元素左浮动),它悄悄地从水底移动到最左侧,把原先的水床挤走(浮动元素会尽量移动在到容器最高处,及最左处或最右处),在最左侧那里建了一所水床,没有登记(没有告知父容器高度,所以产生高度塌陷)。其余的人不知道,在去最左端的固定水床的时候,发现已经有人固定了,所以只能固定在它旁边(浮动会产生环绕效果,而这一点就是由于浮动元素从正常文档流中去除掉的缘由)。

 

图片是属于替换元素,在行框中的计算中,是依据于图片的高度,若是图片进行浮动的话,对于行框来讲,图片不存在了,所以,行框仍是依据原来的文本行基线来计算基线,进行对齐。

 

所以,效果以下

<p style=”line-height:40px;”>

<span>文本内容1</span> <em>文本内容2</em> <img src="img/img2.png" height="100px" width="100px" alt="高度图片">

</p>

  

图片没有浮动:

 

图片左浮动:

 

 

没有图片:

 

 

2.对齐的过程

 

行内元素是默认设置的vertical-alignbaseline,也就是基线对齐。当一个文本行开始渲染的时候,

1.首先浏览器会找出每个元素的类型,是替换元素仍是非替换元素

2.而后根据它们的height或者line-height以及字体大小来生成每一个元素行内框

3.肯定行内框基线位置,肯定行框基线位置

4.根据每一个元素是否设置vertical-align来进行对齐。

 

3.关于居中对齐

vertical-alignmiddle是将元素行内框的中点与父元素基线上方0.5ex处的一个点对齐,这里的1ex相对于元素的font-size来计算x字母的高度,1ex等于该字体下x的字母高度。

多数浏览器会将1ex处理为0.5em,也就是0.5倍字体大小font-size

 

 

 参考文档:

《css权威指南》

张鑫旭文章:《css行高line-height的一些深刻理解及应用

 

原创文章,转载请注明地址!!!

相关文章
相关标签/搜索