深入了解vertical-align

写在前面


大家好,我是一溪风月🥸,一名前端工程师,目标是成为一名独立开发者,这篇文章我们来了解和学习一下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: 大写字母的高度. capCapital 的前三个字母, Capital 本身就有大写字母的意思

  • ascender: 一些字母从 baseline 到高过 x-height 并且通常高过 cap height 的部分, 比如小写字母 b 的竖直笔画

  • descender: 在 baseline 下面的部分, 比如 g 或者 p 的下半部分.

  • ascend: baselineascender 的高度

  • descend: baselinedescender 的高度

二.行高与行盒


行高( 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值为inlineinline-blocktable-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不是玄学~

相关推荐
拉不动的猪42 分钟前
vue与react的简单问答
前端·javascript·面试
污斑兔1 小时前
如何在CSS中创建从左上角到右下角的渐变边框
前端
星空寻流年1 小时前
css之定位学习
前端·css·学习
旭久2 小时前
react+antd封装一个可回车自定义option的select并且与某些内容相互禁用
前端·javascript·react.js
是纽扣也是烤奶2 小时前
关于React Redux
前端
阿丽塔~2 小时前
React 函数组件间怎么进行通信?
前端·javascript·react.js
冴羽2 小时前
SvelteKit 最新中文文档教程(17)—— 仅服务端模块和快照
前端·javascript·svelte
uhakadotcom2 小时前
Langflow:打造AI应用的强大工具
前端·面试·github
前端小张同学2 小时前
AI编程-cursor无限使用, 还有谁不会🎁🎁🎁??
前端·cursor