css还是要从基础抓起啊

250 阅读4分钟

起源

首先感觉自己好失败!写了这么久的css还是没有整明白垂直居中这个属性,vertical-align,被测试纠了2两次不居中之后痛定思通决定整明白他。(ps.我们的测试一丢丢偏移,她都让你改,像素眼的人惹不起)。

你可能会说flex 中的align-items:center 小不就都解决了么,但是我们的应用还有一部分人用的手机可能还是android4.2的老古董,你也不能放弃啊,即使支持flex的安卓手机,有一些手机表现的表现的形式也不尽相同,存在差异。(测试就是能给你找到这样的手机,有过一个老系统版本的小米手机他就不居中,气死我了)

那你可能会说可以用绝对定位

  //方式1
  {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }
  
  //方式2
 {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
  }

方式1 不支持老古董,方式2 受限于内容大小要明确。pading-top 的方法同样要求大小明确,所以决定仔细研究一下vertical-align。

纠错

从我转前端开始,我就知道在浏览器中,文字会下沉,但是从来没做过实验,今天仔细研究了一下,原来不是这样的-_-!!

   .boxSpan{
        background: #6CC20E;
        font-size: 50px;
    }
    .spanMiddle{
        margin-top: -35px;
    }
    <span class="boxSpan">王</span>
    <hr class="spanMiddle">

汉字是居中的,但小写的字母的确会下沉。希望看到的大家不要学我一知半解就认为自己知道了。

开始vertical-align

该属性定义行内元素的**基线(中线)相对于该元素所在行的基线(中线)**的垂直对齐。允许指定负长度值和百分比值。这会使元素降低而不是升高。在表单元格中,这个属性会设置单元格框中的单元格内容的对齐方式。

  1. 首先要让vertical-align生效要求这个元素得是行内元素,及display取值得是inline、inline-block、table-cell 这类的属性才能生效。
  2. 该行内元素的基线你得整明白:在line box 中直接写一个字母"x" (这个字母不包含在其他标签里面),x的底部位置就是 line box 的基线位置。网上有很多图去说明基线的位置
  3. 该元素所在行的基线 可以这样去定义:行的基线是行内最后一个行内元素的基线,如果行内没有行内元素,那么就是盒子的底部边缘。

vertical-align:middle

midle这个是唯一一个让中线对齐的值, 根据基线的定义,中线就是在line box 中直接写一个字母"x" (这个字母不包含在其他标签里面),穿过x中心那个点的水平线就是中线。

为了让内容在盒子中居中,根据定义我们需要一个宽度为0内联元素放在行位,修改他的中线为行的中心然后在行中使用vertical-align:middle 就会居中了

    .box{
        background: #0e80d2;
        width: 300px;
        height: 300px;
    }
    i{
        display: inline-block;
        width: 1px;
        background: #ba1703;
        height: 100%;
        line-height: 100%;
        font-size: 0;
        vertical-align: middle;
    }
<div class="box">
    <i></i>
</div>

i元素为了设置行内的基线,将他的中线设置成整个行的中心位置,这样在i的前面的行内元素设为vertical-align: middle;就会垂直居中

    *{
        margin: 0;
        padding: 0;
    }
    .box{
        background: #0e80d2;
        width: 300px;
        height: 300px;
    }
    .boxSpan{
        background: #6CC20E;
        display: inline-block;
        vertical-align: middle;
        font-size: 50px;
        line-height: 50px;
    }
    .boxMiddle{
        margin-top: -150px;
    }

    i{
        display: inline-block;
        width: 1px;
        background: #ba1703;
        height: 100%;
        line-height: 100%;
        font-size: 0;
        vertical-align: middle;
    }
<div class="box">
    <span class="boxSpan">王</span>
    <i></i>
</div>
<hr class="boxMiddle">

这样内联元素就会垂直居中了

但是你会发现i和内联元素之间还有一点小空隙这时候给行.box 元素添加font-size: 0;就可以消除这个空隙

css2 的垂直居中就可以完美实现了…^_^