写在前面
大家好,我是一溪风月🥸,一名前端工程师,目标是成为一名独立开发者,这篇文章我们来了解和学习一下vertical-align这个属性,vertical-align用来指定行内元素(inline)或表格单元格(table-cell)元素的垂直对齐方式。也就是说,对于块级元素,vertical-align是不起作用的。所以设置vertical-align生效的元素为:inline、inline-block以及table-cell
一.基线基本知识
想要用好vertical-align,基线是必须了解的前置知识
-
baseline
: 小写字母x
的下边界 -
x-height
: 小写字母x
的高度,CSS
中有一个专门表示这个高度的单位 ex -
cap height
: 大写字母的高度.cap
是Capital
的前三个字母,Capital
本身就有大写字母的意思 -
ascender
: 一些字母从baseline
到高过x-height
并且通常高过cap height
的部分, 比如小写字母b
的竖直笔画 -
descender
: 在baseline
下面的部分, 比如g
或者p
的下半部分. -
ascend
:baseline
到ascender
的高度 -
descend
:baseline
到descender
的高度
二.行高与行盒
行高( line-height ):两行文字基线之间的距离
-
content area
: 围绕文字看不见的 Box,其大小与 font-size 有关 -
inline boxes
: 不会成块显示,而是并排显示在一行的 boxes ,如span
,a
,em
等标签以及匿名 inline boxes(即不含把标签的裸露的文字) -
line boxes
: 由一个一个的 inline boxes 组成,一行即为一个 line box -
containing box
: 外层盒子模型,包含了其他的 boxes -
起作用的前提:元素为 inline 水平元素或 table-cell 元素,包括
span
,img
,input
,button
,td
以及通过 display 改变了显示水平为 inline 水平或者 table-cell 的元素。这也意味着,默认情况下,div
,p
等元素设置 vertical-align 无效
💡Tips:值得注意的是:例如 float 和 position: absolute ,一旦设置了这两个属性之一,元素的 display 值被忽略,强制当成 block 方式处理,因此,vertical-align 也就失去了作用。
三.vertical-align
属性vertical-align
影响一个内联级元素垂直方向上的布局。具体适用于display
值为inline
,inline-block
或table-cell
的元素,它有以下取值。
值 | 描述 |
---|---|
baseline | 默认。此元素(基线)放置在父元素的基线上。 |
middle | 使元素的中部(中线)与父元素的基线加上父元素x-height 的一半对齐(近似垂直居中) |
top | 把元素的顶端与行中最高元素的顶端对齐。 |
bottom | 把元素的顶端与行中最低的元素的顶端对齐。 |
text-top | 把元素的顶端与父元素字体的顶端对齐(字体很重要)。 |
text-bottom | 把元素的底端与父元素字体的底端对齐(字体很重要)。 |
sub | 垂直对齐文本的下标。 |
super | 垂直对齐文本的上标。 |
length | 使元素的基线对齐到父元素的基线之上的给定长度。可以是负数。0px 等同于baseline |
% | 使元素的基线对齐到父元素的基线之上的给定百分比,该百分比是line-height 属性的百分比,可以是负数。0% 等同于baseline |
inherit | 规定应该从父元素继承 vertical-align 属性的值。 |
需要注意的是:除了 top 与 bottom 是使元素相对于行内元素垂直对齐外,其他属性值都是相对于父元素。所以,在开发时,我们只需要关注当前元素和父级,两元素前后并没有直接影响
四.常见问题与解决方案
例一 图片下方有间隙
html
<div class="parent">
<img src = "./cat.jpg" >
</div>
css
.parent {
background-color: #679def;
}
img{
width:200px;
}
问题: 在一个没有设置宽高的盒子中加入一个图片什么下面有一个边距?
原因: vertical-align的默认值为base-line,既与行块的基线对齐,而基线考虑到有下沉字母的原因离元素底部是有一小段距离的,因此自然图片下方空出一部分
解决方案:
1.把父元素的font-size:0px。
这样设置的话行内普通流的高度就0,高度消失了基线到底部的距离也就消失了(自己的理解,如果有错误欢迎在评论区说明)
2.在img中添加vertical-align:bottom
第一种方式其实有很大问题的,这样设置的话,会影响所有子元素的文本大小,所以建议采用第二种方式,让当前元素的基线跟父元素的底部对齐而不是基线
例二 没有垂直居中
html
<div>
<img src = "./cat.jpg" >
</div>
css
div{
width: 300px;
background-color: #cccccc;
line-height:200px;
height:200px;
}
img{
height:190px;
vertical-align: middle;
}
问题:为什么设置了vertical-align: middle;但并没有真正得垂直居中,上边距明显大于下边距
分析:
当子元素(图片)设置了 vertical-align:middle,并不是绝对居中,而只能说是近似居中。子元素的垂直中心线与父级元素基线的位置往上二分之一 X 高度(X 的中心) 所在线对齐,通俗一点讲,就是图中红线表示父元素的垂直中心线,蓝线表示子元素的垂直中心线,可以明显的看到 蓝线 与 X 的中心保持一致,但较红线偏低。如果绝对居中的话,两条线应该完全重合。
为什么会产生这种现象呢?主要原因在于文字具有下沉特性,从而导致蓝线无法绝对与红线对齐。当文字大小足够小时,我们可以忽略。从而近似的实现居中效果。但是文字越大,影响就越明显
解决方案: 解决方案一:设置父元素的font-size:0px
middle是指元素的中部与父元素的基线加上父元素x-height的一半对齐
那么如果font-size:0px的话不就指元素的中部直接指向父元素基线了嘛,而中间的普通流高度为0那么基线也就指向了元素行高的垂直中心位置。
但是如果是在子元素下面有文本的情况下,这个方法不推荐使用,至于为什么就不赘述了~
解决方案二:去掉父元素的line-height值,添加一个高度等于父元素的子元素,并且设置vertical-align:middle
如果把图片vertical-align设置成middle,然后去掉line-height添加一个高度为100%的子元素代码如下
html
<div>x
<img src = "./cat.jpg" >
<div class="middle-help"></div>
</div>
css
div{
width: 300px;
background-color: #cccccc;
height:200px;
}
img{
height:100px;
vertical-align: middle;
}
.middle-help{
height: 100%;
vertical-align: middle;
width: 1px;
background-color: black;
display: inline-block;
}
效果:
- 红线代表父元素基线
- 黄线代表父元素基线加上x-height的一半,即子元素中心对齐的线
这样那个高度为100%的元素中部正好对应是父元素的基线 + x-height/2,这样实现了元素的对齐
扩展:为什么要去掉line-height:200px?因为设置行高会影响子元素的基线,相对于上面会使基线下移,而父元素总是参考最下方的基线位置。下图为父元素添加了line-height:200px,可以看到父元素基线被下拉的一点点。
例三 基线受子元素影响
html
<div></div>
<div>x</div>
css
div{
width: 100px;
height: 100px;
background-color: #cccccc;
display: inline-block;
}
效果:
问题: 为什么相同得div加上一个x两个盒子就错位了?
扩展学习:如果我在第二个盒子中添加overflow:auto;居然对齐了。为什么?
html
<div style="overflow: auto">x</div>
解答:
因为行内块元素如果内部没有文字的时候它的基线为元素底部,如果有文字则为内部文字基线位置,细心的同学会发现,第二个盒子字母x的底部是和第一个盒子的元素底部对齐的 至于为什么给第二个元素设置overflow:hidden就对齐了,那是因为开启和BFC,其内部与外界隔离了
总结
这篇文章到这里就结束了🚀,这篇文章主要讲解了,vertical-align及其案例的使用,以及开发中遇到的奇怪现象和对应的解决方案,相信通过不断的学习你会发现CSS不是玄学~