摘要:方法二利用,设置元素结构,并应用实现垂直居中,这种方法的实现可用于多行文本,要求及以上版本。
让元素居中对齐是非常常见的需求,首先是水平居中,要实现水平居中行内元素只需要在其父元素上设置text-align: center即可,对于块级元素来说让它的margin-left: auto和margin-right: auto即可(width不可为auto),那么垂直居中呢?找下css属性发现了vertical-align,感觉就是它了,设置个vertical-align: middle,怎么没有达到预期效果?下面来详细介绍下vertical-align这个属性以及实现垂直居中的若干方法。
vertical-align属性是干什么的根据W3C Spec中对vertical-align属性的定义:
This property affects the vertical positioning inside a line box of the boxes generated by an inline-level element.
什么是line box?同样来自W3C Spec
The rectangular area that contains the boxes that form a line is called a line box.
这个属性仅影响了单行中行内元素的垂直位置,那么我们会涉及到的元素应该是这样的:
inline
inline-block
既然我们要垂直居中,垂直居中是相对于垂直高度而言的,然而我们知道height对inline元素无效,那么line box的高度是怎么计算的呢?(还是引用W3C Spec)
The height of a line box is determined by the rules given in the section on line height calculations.
一个line box的高度是的计算方式如下:line box中的每一个行内元素都将加入到计算过程,如果是元素inline的则取其line-height的值,如果元素是inline-block或者是inline-table则取其margin-box的高度,最后这些值的最大值,即为line box的高度了。
好了,然后来看看vertical-align属性可以取哪些值:
可取值 | 说明 |
---|---|
baseline | 将元素的基线与父元素的基线对齐 |
middle | 将元素的中线与父元素的基线加上x一半的高度对齐 |
sub | 将元素置于基线下方合适的位置 |
super | 将元素置于基线上方合适的位置 |
text-top | 将元素的顶部与父元素正文区域的顶部对齐 |
text-bottom | 将元素的底部与父元素的正文区域的底部对齐 |
top | 将元素的顶部与line box顶部对齐 |
bottom | 将元素的底部与line box底部对齐 |
< percentage > | 基于基线上(正值)下(负值)移动元素,值通过百分比乘上行高而得 |
< length > | 基于基线上(正值)下(负值)移动元素 |
这里有两个概念:基线(baseline)和正文区域(content area)。
先来感受下,举个栗子:
http://jsfiddle.net/leozdgao/y4oexshn/6/embedded/result,html,css/
在第一个栗子中,直观地展示了vertical-align属性所有可取属性的表现。
在第二个栗子中,蓝色的线表示的就是基线(记得小时候英语练习本每行的第三根线么),绿色的轮廓表示的就是正文区域,这里故意加了个较大的行高,于是红色的轮廓表示的就是line box的轮廓了。
对于有正文的行内元素而言,它的基线正如上面的栗子中所展示的那样,那么对于没有正文的行内元素(这里指的是有大小的inline-block元素但没有正文或者类似与img video这样的replaced element),它们的基线位于它们margin box的底部。
我们发现在这些可取的值中,大部分都与它们的父元素(通常为line box)的基线有关,那么line box的基线在哪里?或者栗子里的蓝线是根据什么画出来的?在W3C Spec中是这样说的:
CSS 2.1 does not define the position of the line box"s baseline
是的,没有定义......不过好在浏览器之间的实现似乎没有什么区别,取的就是正常的一个文本的基线位置,这里就不再多纠结line box的基线是怎么计算的了。
这里额外说明下vertical-align: middle,根据上面的解释,什么是父元素的基线加上x一半的高度?还是来看个直观的栗子:
http://jsfiddle.net/leozdgao/hf3ocgd8/2/embedded/result,html,css/
蓝色的线依然表示基线,橙色的线表示的就是所谓的line box的基线加上x一半高度的位置。同时也展示了为什么仅给元素设置vertical-align: middle是没有办法达到效果的。
不过line box的基线并不是固定不动的,这次用一个实际的栗子来解释,比如在单行中有一张图片和一段文本,我们的需求是让文字垂直居中对齐:(我用一个inline-block的方块来模拟一张图片)
http://jsfiddle.net/leozdgao/pe8t1LLf/1/embedded/result,html,css/
第一个case是没有设置vertical-align时的样子,我们现在知道将文字部分设置vertical-align: middle是不正确的。在第二个case展示了在图片上应用vertical-align: middle,我们发现,为了满足图片中线与line box基线加上半个x高度的位置对齐,而图片位置不能移动了(整个line box就是它撑起来的),所以line box的基线被调整了。那么现在看上去好像是居中了?其实还是差一点,如case3中那样,这时将vertical-align: middle应用与文本上,就可以垂直居中了。
由此我们得到的结论是:对于那些直接影响着line box高度的行内元素来说,vertical-align对元素本身可能无影响,但会调整line box的基线。
垂直居中的若干种方法垂直居中的需求往往并不限于单行文本,可能会设计多行文本,或者多行文本配图片等等,下面整理的各种垂直居中的方案,并试着分析其优劣。
方法一:
将line-height设置为和height一样高,常用于导航栏或者标签页这样的单行文本居中,缺点是这种方法只能用于单行文本,如果还涉及到图片,可以根据上面一部分中提到的方法调整。
http://jsfiddle.net/leozdgao/150et323/embedded/result,html,css/
方法二:
利用css table,设置元素table结构,并应用vertical-align: middle实现垂直居中,这种方法的实现可用于多行文本,要求IE8及以上版本。
http://jsfiddle.net/leozdgao/00dgdbem/embedded/result,html,css/
方法三:
上下设置等高的padding或者margin值,个人觉得最笨的一种方法,唯一的优点是兼容所有浏览器,缺点是很不灵活,大小需要额外计算并写死。(不提供栗子)
方法四:
绝对定位,这种方法并不仅限于『居中』,一种是利用负的margin值来实现,另一种是用CSS3的translate来实现,优点的话同样是可以支持多行文本,只是负的margin会写死大小,仅适合与大小固定的元素,用translate要考虑css3的浏览器兼容问题,最大的局限性是绝对定位本身导致元素脱离文本流normal flow,多数情况下其父元素仅包括它一个子元素时会使用。
http://jsfiddle.net/leozdgao/h34zqLf2/1/embedded/result,html,css/
补充:支持CSS3的浏览器,也可以使用calc,像这样使用:
csstop: calc(50% - (300px / 2));
方法五:
同样是绝对定位,这个方法一般被称为Stretching,把4个定位方向全部设置为0,这种方式不会将大小写死,浏览器兼容性也很不错,但绝对定位的弊端上面也已经提到过了。
http://jsfiddle.net/leozdgao/5a9z676h/1/embedded/result,html,css/
这里简单解释下实现原理:我们发现了margin: auto,是的,我们给4个方向全部设置为0,即为元素提供了与其父元素相同的外边缘。接下来看W3C Spec中提到的:
If none of the three are "auto": If both "margin-top" and "margin-bottom" are "auto", solve the equation under the extra constraint that the two margins get equal values.
这是就垂直方向而言的:其中的three指的是top height bottom,就是margin值的计算结果会让元素尽可能居中。水平方向同理。
方法六:
隐藏一个浮动元素,这个浮动元素占父元素一半的高度,然后需要垂直居中的元素设置清除浮动,并设置大小为其高度一半的负margin-top,这个方法兼容任何浏览器,但总感觉有点hack的意味,不推荐。
http://jsfiddle.net/leozdgao/zoft69ao/1/embedded/result,html,css/
方法七:
FlexBox布局,浏览器需要支持,在移动端可大肆使用。
http://jsfiddle.net/leozdgao/4my89br7/1/embedded/result,html,css/
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/111071.html
摘要:垂直居中当设置此时的页面看似垂直居中,但是并没有完全垂直居中。中线位置字符的中心并不是字符内容的绝对居中位置。这种通过定高,元素垂直居中的方法不仅适用于现代浏览器,连浏览器也是支持的。 今天在写样式时,icon和文字都进行了垂直居中的处理,但是icon并没有垂直居中,后来发现由于 line-height 和 vertical 一起使用导致与预期样式不同,特此对 vertical-ali...
摘要:在中实现垂直居中很多时候会用到,不过我一直对的使用糊里糊涂,现在整理一下关于它的一些知识点。将盒子的垂直中心点与父级盒子基线往上一半高度的位置对齐。时位置与设置一致。我们可以将设为来让元素完全垂直居中。 在 css 中实现垂直居中很多时候会用到 vertical-align ,不过我一直对 vertical-align 的使用糊里糊涂,现在整理一下关于它的一些知识点。原文链接 1. 适...
摘要:在中实现垂直居中很多时候会用到,不过我一直对的使用糊里糊涂,现在整理一下关于它的一些知识点。将盒子的垂直中心点与父级盒子基线往上一半高度的位置对齐。时位置与设置一致。我们可以将设为来让元素完全垂直居中。 在 css 中实现垂直居中很多时候会用到 vertical-align ,不过我一直对 vertical-align 的使用糊里糊涂,现在整理一下关于它的一些知识点。原文链接 1. 适...
摘要:所以文字最终可以在整个中垂直居中显示。默认值为,即把元素放在父元素的基线上。万万没想到用两行代码就实现了只要给容器加上下面两条样式,就成功垂直居中了,都是多余了的。 请一定看到最后,flex太令人惊喜! ヾ(o◕∀◕)ノ 入个门 先来考虑这样一个问题:一行文字在一个固定高度的父div中怎样做到垂直居中?我们都知道设置父div的line-height 等于它的height就可以了,像下面...
摘要:所以文字最终可以在整个中垂直居中显示。默认值为,即把元素放在父元素的基线上。万万没想到用两行代码就实现了只要给容器加上下面两条样式,就成功垂直居中了,都是多余了的。 请一定看到最后,flex太令人惊喜! ヾ(o◕∀◕)ノ 入个门 先来考虑这样一个问题:一行文字在一个固定高度的父div中怎样做到垂直居中?我们都知道设置父div的line-height 等于它的height就可以了,像下面...
阅读 3559·2023-04-26 02:10
阅读 1296·2021-11-22 15:25
阅读 1665·2021-09-22 10:02
阅读 905·2021-09-06 15:02
阅读 3468·2019-08-30 15:55
阅读 598·2019-08-30 13:58
阅读 2773·2019-08-30 12:53
阅读 3040·2019-08-29 12:38