前言
vertical-align属性相信是很多初学前端布局小伙伴比较陌生和比较难以理解的一个属性。很多时候在想用vertical-align属性实现垂直居中的时候总是不起效果,只能去用别的方式实现。相信这是不少初学者的苦恼,下面让我从基本概念和用法、前端实现两个方面简单谈谈。
基本概念和用法
-
首先我们要先了解HTML+CSS中的各种 “线”
- 顶线:中文汉字的的上端沿;
- 中线:横过英文字母x的中间的线;
- 基线(baseline)并不是汉字文字的下端沿,而是英文字母“x”的下端沿;
- 底线:中文汉字的下端沿;
- 内容区:指底线和顶线包裹的区域;内容区的大小依据font-size的值和字数进行变化。
-
baseline的确定规则
- inline-table元素的baseline是它的table第一行的baseline。
- 父元素【line box】的baseline是最后一个inline box 的baseline。
- inline-block元素的baseline确定规则。
- 规则1:inline-block元素,如果内部有line box,则inline-block元素的baseline就是最后一个作为内容存在的元素[inline box]的baseline,而这个元素的baseline的确定就要根据它自身来定了。
- 规则2:inline-block元素,如果其内部没有line box或它的overflow属性不是visible,也就是overflow: hidden 和 inline-block元素里面没有内容,那么baseline将是这个inline-block元素的底margin边界。
-
CSS中的4种box
- 包含框(containing box):每一个block都算containing box,它包含 line boxes,line boxes的高度垂直堆叠形成了 containing box的高度,如例中div的高度。
- 行框(line boxes):块内的内容渲染的每一行,都可以看成是一个行框,也可以说,每一行都是一个行框。line boxes的行数,由block的宽度及内容决定,当然是在不限制高度的情况下。一行内有多个行内框,一个一个的inline boxes组成了line boxes,行框是包含一行内行内框最高点和最低点。它的高度,由行内最大line-height决定。
- 行内框(inline boxes):inline boxes不会让内容成块显示,而是排成一行。在块元素(无论是 block 或 inline-block)中没有被内联元素包含的文本和内联/行内元素就是行内框。
- 行内容区(content area):content area 是一种围绕文字看不见的box。content area的大小与font-size大小相关。一般选择文本后,有背景颜色的就是内容区了。
-
Vertical-align的属性值:
值 描述 baseline 默认。子元素放置在父元素的基线上。 sub 垂直对齐文本的下标。 super 垂直对齐文本的上标。 top 把元素的顶端与行中最高元素的顶端对齐。 middle 把此元素放置在父元素的中部。 bottom 把元素的顶端与行中最低的元素的顶端对齐。 % 允许使用负值。值是父盒子的line-height的值乘以百分比。 -
Vertical-align的属性的应用对象:
- 应用于inline水平和table-cell元素
- inline水平就是inline元素和inline-block元素
- table-cell元素就是<td>
- 默认状态下的图片、按钮、文字和单元格
- 应用于inline水平和table-cell元素
-
更改元素显示水平的方法:
- display更改元素的显示水平,例如:display:inlink:转成行内快
- CSS声明更改元素的显示水平,例如:float:left:左浮动,会自动转成块元素
了解了以上概念和方法后,我们用可以用来前端实现
前端实现
- 首先我们实现的inline水平的居中,也就是内联元素和内联元素的居中,匿名内联元素也同理。
<head>
<style>
div {
height: 500px;
background-color: rosybrown;
}
img {
vertical-align: middle;/*该元素的中线与父元素的baseline(span的baseline)对齐*/
}
</style>
<body>
<div>
<img src="../image/dog.jpg" alt="">
<span>123</span>
<!-- 父元素【line box】的baseline是最后一个inline box 的baseline。就是这里的span -->
</div>
</body>
</head>
- 我们会发现图片并没有实现垂直居中,这是为什么呢?原因是不是vertical-align:middle不起作用,而是太短了,行高不够看不到效果。如果我们想要的是图片居中要怎么办呢,请看一下代码
<head>
<style>
div {
height: 500px;
line-height: 500px;/*行高设为高度就可实现*/
background-color: rosybrown;
}
img {
vertical-align: middle;/*该元素的中线与父元素的baseline(span的baseline)对齐*/
}
</style>
<body>
<div>
<img src="../image/dog.jpg" alt="">
<span>123</span>
<!-- 父元素【line box】的baseline是最后一个inline box 的baseline。就是这里的span -->
</div>
</body>
</head>
第二种方法采用更改显示水平的方法,也就是用display:table-cell,将块元素转成单元格形式。
强调:起作用的是table-cell自身,所以display和vertical-align必须写在同一元素内
<head>
<style>
div {
display: table-cell;
vertical-align: middle;
height: 500px;
background-color: rosybrown;
}
img {
vertical-align: middle;/*该元素的中线与父元素的baseline(span的baseline)对齐*/
}
</style>
<body>
<div>
<img src="../image/dog.jpg" alt="">
<span>123</span>
<!-- 父元素【line box】的baseline是最后一个inline box 的baseline。就是这里的span -->
</div>
</body>
</head>
- 如果发现图片还是没有居中,那么极有可能你的元素的显示水平被更改或者继承了别的样式,成为了块级元素,此时需要检查代码,或者采取其他居中方式,具体可见我上一篇文章。
总结
使用该种方法的局限性确实是比较大,又比较难以理解,所以我个人也很少会用到,如果说想用这种方法,但是没有效果,首先你需要确定父元素的基线在哪里,根据baseline来进行调整,其次,你需要在检查你的元素是否是inline水平和table-cell元素,这是该元素应用范围。
网友评论