CSS第九篇:CSS属性-vertical-align

CSS属性-vertical-align

  1. 盒子概念
    1. 每一个HTML元素都会产生一个盒子(box)
      1. 块级元素(div)产生一个块级盒子(block-level-box)
      2. 行内级元素(span)产生一个行内级盒子(inline-level-box)
      3. inline-box元素产生一个行内级盒子(inline-level-box)
    2. 多个行内级盒子可以在同一行显示
  2. 行内级盒子(inline-level box)的高度
    1. 行内级非替换元素(比如span、strong、a)高度:line-height的高度 (注意,可不是内容高度)

       //span的高度是30,不是14px
       span {
           background-color: #0f0;
           font-size: 14px;
           line-height: 30px;
       }
      
    2. inline-block元素高度:margin-box的高度
    3. 行内级替换元素(img、input)高度:margin-box的高度

       /* strong高度为margin-box的高度 */
       strong {
           display: inline-block;
           width: 50px;
           height: 50px;
           background-color: #0f0;
           margin-top: 50px;
       }
      
  3. line box(行盒、线盒)
    1. 一行中包含所有inline-level(包括inline-block)的矩形区域叫做line box
    2. line box的宽度
      1. 一般来说,linebox的左右边缘紧贴着containing block的左右边缘,line box宽度等于包含块宽度
      2. 如果有浮动,floated box可能会夹在containing block和line box的边缘之间,导致line box的宽度变窄
    3. line box的高度
      1. 当一个inline-level box的高度小于包含它的line-box的高度时,inline-level box的垂直对齐方式由vertical-align属性决定
      2. line box的高度经常不一样(比如有的line box包含了img元素,有的line box只包含了文本)
    4. 举例:
      1. line box的定义

         <style>
             div {
                 margin: 0 auto;
                 border: 1px solid #000;
                 width: 700px;
                 height: 400px;
             }
             span {
                 background-color: #0f0;
                 font-size: 14px;
                 line-height: 30px;
             }
             /* strong高度为margin-box的高度 */
             strong {
                 display: inline-block;
                 width: 50px;
                 height: 50px;
                 background-color: #0f0;
                 margin-top: 50px;
             }
             img {
                 margin-top: 40px;
             }
         </style>
         <body>
         <div>
             <!-- 行内级替换元素 -->
             <!--无基线-->
             <img src="./images/car.png" alt="">
             <!-- 行内级非替换元素 -->
             <span>span</span>
             <!-- inline-block元素 -->
             <!--无基线-->
             <strong></strong>
         </div>
         </body>
        

        pic

vertical-align

  1. vertical-align用来设置行内级盒子(inline-level box)在line box(行盒)中垂直方向的位置
    1. 对于非替换行内(non-replaced inline)元素而言,用来对齐的是高度为line-height的box
    2. 对于其他元素而言,用来对齐的是margin box
    3. text-align:设置行内级盒子水平方向的布局(对齐方式)
    4. vertical-align:设置行内级盒子垂直方向的布局(对齐方式)
  2. vertical-align取值
    1. baseline(默认值):把行内级盒子的基线与父盒的基线对齐,如果没有基线(盒子内部无文字显示),margin-bottom边缘与父盒基线对齐
      1. 父盒子基线:父盒子内部输入xxx,x的底部水平线
      2. 行内级盒子基线:子盒子无文字内容,则是无基线(img是无基线行内级盒子); 子盒子有内容,则为xxx的底部水平线
    2. sub:把行内级盒子的基线降到父盒下标的适当位置
      1. 与super相反
    3. super:把行内级盒子的基线升到父盒上标的适当位置
      1. 父盒子是底数,行内盒子是指数
    4. <percentage>:把行内级盒子提升或者下降一段距离(距离相对于line-height计算),0%意味着同baseline一样
    5. <length>:把行内级盒子提升或者下降一段距离,0cm意味着通baseline一样
    6. middle:行内级盒子的中心点与父盒基线加上x-height(小写字母x的高度)一半的线对齐
    7. text-top:把行内级盒子的顶部同父盒子的内容区域顶部对齐
    8. text-bottom:把行内级盒子底部同父盒子的内容区域底部对齐
    9. top:把行内级盒子的顶部跟line box顶部对齐
    10. bottom:把行内级盒子的底部跟line box底部对齐

举例说明

  1. baseline举例:

     <style>
         body {
             font-family: "宋体";
         }
         div {
             margin: 0 auto;
             border: 1px solid #000;
             width: 400px;
             height: 200px;
             font-size: 25px;
         }
         span {
             background-color: #0f0;
             font-size: 14px;
             line-height: 14px;
         }
         strong {
             display: inline-block;
             width: 50px;
             height: 50px;
             background-color: #0f0;
             margin-bottom: 20px;
         }
           
     </style>
     <body>
     <div>
     中国divxxx
     <!-- 行内盒子有基线 -->
     <!-- <span>哈哈哈spanxxx</span> -->
     <!-- 行内盒子没有基线 -->
     <!-- <strong></strong> -->
     <!-- 行内盒子有基线 -->
     <strong>456 xx</strong>
     </div>
     </body>
    

    pic

    1. 左图父盒子字体比span字体大,所以span距离顶部有一段举例,以父盒子字体baseline为准
    2. 中图子盒子无基线,则子盒子margin-bottom对齐父盒子的baseline
    3. 右图子盒子有基线,则子盒子baseline对齐父盒子的baseline
  2. sub、super、percentage、length举例:

     <style>
         body {
             font-family: "宋体";
         }
         div {
             margin: 0 auto;
             border: 1px solid #000;
             width: 400px;
             height: 200px;
             font-size: 14px;
         }
         span {
             background-color: #0f0;
             font-size: 14px;
             line-height: 14px;
             /* vertical-align: sub; */
             /* vertical-align: super; */
             /* vertical-align: 70%; */
             vertical-align: 7px;
    
         } 
     </style>
        
     <body>
     <!-- 跟sub、sup效果一样 -->
     <!-- <sub>123</sub>
     <sup>345</sup> -->
     <!-- 父盒子 -->
     <div>
         123
         <!-- 行内盒子 -->
         <span>456</span>
     </div>
     </body>
    

    pic

  3. 常见现象
    1. 父控件高度不设置,为auto,子控件为img元素设置一个图片,会发现底部自动有一段距离,不是父控件完全包裹子控件,为什么?
    2. 原因:img元素无基线,因此默认对齐方式为img的margin-bottom与父控件的基线对齐

       <style>
           div {
               margin: 0 auto;
               border: 1px solid #000;
               width: 400px;
               font-size: 14px;
           }
           span {
               background-color: #0f0;
               font-size: 14px;
               line-height: 14px;
           } 
           strong {
               display: inline-block;
               width: 50px;
               height: 50px;
               background-color: #0f0;
               margin-bottom: 20px;
           }
       </style>
              
       <body>
       <div>
           <!-- 父控件输入内容 -->
           <!-- 123xxx
           <span>span</span> -->
           <img src="./images/test.png" alt="">
           <!-- <strong>xxx</strong> -->
       </div>
       </body>
      

      pic

  4. middle举例

     <style>
         body {
             font-family: "宋体";
         }
         div {
             margin: 0 auto;
             border: 1px solid #000;
             width: 400px;
             font-size: 50px;
             line-height: 50px;
             /* 设置为0,图片就能居中了 */
             /* font-size: 0px; */
         }
            
        img {
            width: 40px;
            height: 40px;
            vertical-align: middle;
        }
     </style>
     <body>
     <div>
         中国Engxxx
         <img src="./images/test.png" alt="">
     </div>
     </body>
    

    pic

    1. 可以明确的看出,行内盒子并不是标准垂直居中在父盒子中间。那么如何让行内盒子垂直居中呢?
    2. 将父盒子的font-size: 0;设置为0即可
    3. 父盒子的font-size为0,那么父盒子的baseline+0.5*x-height就重合在父盒子的以line-height为高度的中线了
  5. text-top、text-bottom、top、bottom举例

     <style>
         div {
             margin: 0 auto;
             border: 1px solid #000;
             width: 400px;
             font-size: 20px;
             line-height: 40px;
         }
         span {
             background-color: #0f0;
             font-size: 15px;
             line-height: 30px;
             /* vertical-align: text-top; */
             /* vertical-align: text-bottom; */
             /* vertical-align: top; */
             vertical-align: bottom;
    
         } 
           
     </style>
        
     <body>
     <div>
         中国Engxxx
         <span>哈哈哈ngxxx</span>
     </div>
     </body>
    

    pic

vertical-align应用

  1. 解决掉图片底部空隙问题

     div {
         margin: 0 auto;
         border: 1px solid #000;
         width: 400px;
         font-size: 14px;
     }
     /* 解决掉图片底部空出距离问题:一旦不是baseline对齐,那么底部就不会空出距离 */
     img {
          /* vertical-align: top; */
         vertical-align: bottom;
     }
     <div>
         <img src="./images/test.png" alt="">
     </div>
        
    

元素的居中总结

  1. 标准流的居中
    1. 水平居中
      1. 子元素为行内非替换元素(span、strong)

         /*设置到父元素上 */
         /*水平居中 */
         text-align: center;
        
      2. 子元素为行内替换、inlie-block元素(同上)
      3. 子元素为block元素

         /* 设置到子元素上 */
         /* 水平居中*/
         margin-left: auto;
         margin-right: auto;
        
    2. 垂直居中
      1. 子元素为inline元素:height=line-height

         /*设置到父元素上 */
         height = 100px;
         /*垂直居中: line-height== height */
         line-height: 100px;
        
        1. 注意:height=line-height只能让单行文本垂直居中
      2. 子元素为行内替换、inlie-block元素

         /*设置到父元素上 */
         /* 字体设置为0 */
         font-size: 0;
         /* line-heiht==height */
         line-height: 100px;
                    
         /*设置到子元素上 */
         vertical-align: middle;
                    
         /*父元素内部必须有文字内容 */
         <div class="div2">
             <!-- 必须有内容 -->
             xxx
             <img src="./images/car.png" alt="">
         </div>
        
      3. 子元素为block元素,无法垂直居中

  2. 脱标绝对定位
    1. 方法1:

       /* 父元素 */
       .div4 {
           /* 父相 */
          position: relative;
       }
       /* 子元素 */
       .div5 {
           /* 子绝 */
           position: absolute;
           left: 0;
           right: 0;
           bottom: 0;
           top: 0;
           margin: auto;
       }
      
    2. 方法2:

       /* 父元素 */
       .div4 {
           /* 父相 */
          position: relative;
       }
       /* 子元素 */
       .div5 {
           /* 子绝 */
           position: absolute;
           /* 左边距离父控件的一半= 父控件宽度*50% */
           left: 50%;
           /* 向左移动当前控件的一半 */
           margin-left: -25px;
      
           /* 顶部距离父控件的一半= 父控件高度*50% */
           top: 50%;
           /* 向上移动当前控件的一半 */
           margin-top: -25px;
       }
      
  3. 使用flex布局(略)

行内替换、inlie-block元素居中举例

<style>
    .div1,.div2 {
        width: 100px;
        height: 100px;
        background-color: #f00;
         /* 水平居中 */
        text-align: center;
        /* inline-block垂直居中 */
        /* 字体设置为0 */
        font-size: 0;
        /* line-heiht==height */
        line-height: 100px;
    } 
    /* inline-block元素 */
    strong {
        display: inline-block;
        width: 50px;
        height: 50px;
        background-color: #ff0;
        /* 垂直居中 */
        vertical-align: middle;
    }
    img {
         /* 垂直居中 */
         vertical-align: middle;
    }
 </style>
 
 <body>
 <div class="div1">
     <!-- 必须有内容 -->
     x
     <strong></strong>
 </div>
 <br><br><br>
 <div class="div2">
     xxx
     <img src="./images/car.png" alt="">
 </div>
 </body>
Table of Contents