苏苏苏 發表於 2026-5-3 22:17:04

一文搞懂CSS中的vertical-align属性

<h2>vertical-align</h2>
<p>CSS中的vertical-align用于设置行内块或者行内元素行内元素的对齐方式,似乎使用起来很简单,但使用过程中的坑很多,我个人对于这个属性看了比较多的博客,也有点似懂非懂,以下是我的个人理解以及简要的总结。</p>
<h3>定义以及常见属性位置</h3>
<p>首先,MDN官方文档给的定义:<code>vertical-align</code>是设置元素的<strong>垂直排列</strong>的。用来定义行内元素的基线相对于该元素所在行的基线的垂直对齐。</p>
<p>它的值比较多:<code>baseline</code> | <code>sub</code> | <code>super</code> | <code>top</code> | <code>text-top</code> | <code>middle</code> | <code>bottom</code> | <code>text-bottom</code> | <code>inherit</code></p>
<p>我们这里只看常用的:</p>
<ul>
    <li><code>baseline</code>:使<strong>元素的基线</strong>与<strong>父元素的基线</strong>对齐</li>
    <li><code>middle</code>:使<strong>元素的中部</strong>与<strong>父元素的基线</strong>加上<strong>父元素字母x的一半</strong>对齐</li>
    <li><code>top</code>:使<strong>元素的顶部</strong>与其<strong>所在行的顶部</strong>对齐</li>
    <li><code>bottom</code>:使<strong>元素底部</strong>与<strong>所在行的底部</strong>对齐</li>
</ul>
<p>按照官方文档的分类:</p>
<ul>
    <li><code>baseline</code>与<code>middle</code>,使元素相对其父元素垂直对齐。</li>
    <li><code>top</code>与<code>bottom</code>,使元素相对整行垂直对齐。</li>
    <li>以下为行内元素/行内块的顶线、中线、基线、底线所在位置:</li>
</ul>
<h3>top与bottom的元素整行垂直对齐方式</h3>
<p>首先要明白什么叫整行。这里的整行指的是<strong>几个行内元素、行内块元素</strong>所在的那一行,整行的高度由该行最高的元素决定。</p>
<p>对于<code>top</code>与<code>bottom</code>的使用,以下是我的个人理解:</p>
<ul>
    <li>首先,我们要找&ldquo;大哥&rdquo;,即该行最高的元素。</li>
    <li>当我们对&ldquo;大哥&rdquo;使用<code>top</code>与<code>bottom</code>时,因为&ldquo;大哥&rdquo;本就是该行最高的元素了,因此使用这两种对齐方式,该元素不会有任何变化。</li>
    <li>该行其他元素使用<code>top</code>与<code>bottom</code>时,会依据&ldquo;大哥&rdquo;的顶线和底线来进行对齐。换句话说,只使用<code>top</code>与<code>bottom</code>时,该行排列的参照物就变成了&ldquo;大哥&rdquo;,其他元素相对于&ldquo;大哥&rdquo;进行对齐。</li>
</ul>
<p>情形1:(<code>box1:top</code>不变位置;<code>box2:top</code>,自动与box1顶线对齐;<code>span:bottom</code>,自动与box1底线对齐。)</p>
<p style="text-align:center"><img alt="image-20230502070255381.png" src="https://img.jbzj.com/file_images/article/202305/2023051115402375.png" /></p>
<p>情形2:(<code>box1:bottom</code>不变位置;<code>box2:top</code>,自动与box1顶线对齐;<code>span:bottom</code>,自动与box1底线对齐。)</p>
<p style="text-align:center"><img alt="image-20230502070509964.png" src="https://img.jbzj.com/file_images/article/202305/2023051115402376.png" /></p>
<p>以上两种情况,看似我使用的是同一张图,实质上两种box1的对齐方式并不相同。因此我们可以得出结论,只使用top与bottom时,最高元素不变,其余元素以最高元素(本质上其实就是最高元素就是该行高度)为参照物进行对齐。</p>
<h3>baseline与middle相对于父元素的对齐方式(相对于父元素的基线)。</h3>
<p>使用此类属性值时,我们首先要搞清楚<strong>父元素的基线位置</strong>和<strong>子元素的基线位置</strong>。</p>
<ul>
    <li><strong>子元素的基线位置</strong>
    <ul>
      <li>vertical-align的作用对象是 :inline-level element(内联级元素),内联级元素不同的display属性值对应的基线的位置也是不同的。</li>
    </ul>
    </li>
    <li>当display属性值为:
    <ul>
      <li><code>inline</code>,内联元素的baseline是里面文本字母 x 的下边缘线。(即使没有字母 x,也可以想象文中有一个字母 x 存在)</li>
      <li><code>inline-block</code>,行内块元素的baseline位置的确定规则分为以下三种情况:
      <ul>
            <li><code>inline-block元素盒子里没有内容</code>,baseline的位置为该盒子margin-bottom的边界(如果margin-bottom为0,那就是盒子的下边界)。如下图背景为蓝色的div。</li>
            <li><code>inline-block,元素盒子里有内容,并且其overflow属性值为 visible</code>,那么该盒子的baseline的位置就是内部内容的最后一个内容元素的baseline(依旧是找x的下边缘线)的位置。如下图背景为白色的div。</li>
            <li><code>inline-block,元素盒子里有内容,但是其overflow属性值为非 visible(比如 overflow: hidden )</code>,那么该盒子的baseline位置就是该盒子 margin-bottom 的边界。如下图背景为黄色的div。</li>
      </ul>
      </li>
    </ul>
    </li>
</ul>
<p style="text-align:center"><img alt="v2-82a4dc92ba7712d80b2763782e812490_720w.webp" src="https://img.jbzj.com/file_images/article/202305/2023051115402377.png" /></p>
<p><strong>父元素的基线位置</strong></p>
<ul>
    <li>
    <p>实际上,父元素的基线是由子元素的基线位置确定的。</p>
    </li>
</ul>
<blockquote>
<p>父元素内有子元素被设置 vertical-aling:baseline 并且有内容存在时,父元素的基线的位置是在子元素的基线所在位置,看下面两张图(绿色线代表基线):</p>
</blockquote>
<p style="text-align:center"><img alt="v2-1f82abef1e37a4a0b27d6020b1293d77_720w.webp" src="https://img.jbzj.com/file_images/article/202305/2023051115402478.png" /></p>
<blockquote>
<p>接着,我们给父元素另外一个带有内容的行内块元素,我们可以发现,另一个box位置向下偏移了,两个盒子基线对齐。这似乎存在前后矛盾。</p>
</blockquote>
<p style="text-align:center"><img alt="v2-f983afa953093e976cf919e7d8354cbe_720w.webp" src="https://img.jbzj.com/file_images/article/202305/2023051115402479.png" /></p>
<blockquote>
<p>我们调换两个元素字体大小,基线位置不变,依旧以字体大小最大的行内块元素的基线位置为准。</p>
</blockquote>
<p style="text-align:center"><img alt="v2-a81891117cc83f505b6620f7c227d3d8_720w.webp" src="https://img.jbzj.com/file_images/article/202305/2023051115402480.png" /></p>
<ul>
    <li>由此可知:在有子元素并且有内容的情况下,父元素基线所在的位置是取在子元素还在默认位置时(可以理解为父元素中只有一个子元素时),他们的基线与父元素顶部距离最大的那个位置,其他同行元素相对于父元素的基线对齐。事实上,不管元素有无内容,父元素的基线都是以距离顶部最大元素的那个位置为准。</li>
</ul>
<p>总结:<strong>父元素基线的位置由子元素确定,父元素基线所在的位置就取在子元素还在默认位置时(可以理解为父元素中只有一个子元素时)他们的基线与父元素顶部距离最大的那个位置,其他同行元素相对于父元素的基线对齐。</strong></p>
<p><strong>父元素基线确定的简单方法:为父元素添加其伪元素,其 content 的属性值为 x ,那么父元素的基线就可以看到了&mdash;&mdash;就是字母x的下边缘线</strong></p>
<p>下面看一个综合案例:</p>
<p style="text-align:center"><img alt="image-20230502093728377.png" src="https://img.jbzj.com/file_images/article/202305/2023051115402481.png" /></p>
<p>其中,<strong>红色盒子</strong>为带有内容的<code>中线对齐(middle)</code>行内块、<strong>蓝色盒子</strong>为带有内容的<code>基线对齐(baseline)</code>行内块、<strong>天蓝色部分</strong>为行内元素span、<strong>img图像</strong><code>默认基线对齐图像</code>、<strong>父元素内部的文字</strong>xxXXjjj以及<strong>伪元素</strong>(::after--inline-block)且含有xXj内容的行内块元素。</p>
<p>我们可以很清晰的看到:</p>
<ul>
    <li>红色部分中线与父元素基线向上1/2 x高度的位置对齐(CSS属性本身的小问题,可能有几个像素的误差,大体上对齐)</li>
    <li>蓝色部分基线为最后一行内容的基线,且与父元素基线对齐</li>
    <li>天蓝色span部分基线为内容的基线,且与父元素基线对齐</li>
    <li>img图像部分,基线为盒子最底部margin-bottom,此时margin-bottom为0,即图像盒子下边框为此盒子基线</li>
</ul>
頁: [1]
查看完整版本: 一文搞懂CSS中的vertical-align属性