How does the vertical-align property work?

后端 未结 2 624
北荒
北荒 2020-11-27 08:48

I do not understand when vertical-align will and won\'t work.

Every time I run into a use case for vertical-align it seems to be a coin tos

2条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-11-27 09:07

    The easiest way to understand why it's not working it to add many line of text because vertical-align will align on the respective line (the line-box) and not the whole container like you may think.

    So if we add more text we have the following.

    #outer {
      box-sizing: border-box;
      border: red 1px solid;
      height: 200px;
      text-align: center;
    }
    
    #inner {
      border: blue 1px solid;
      height: 200px;
      width:180px;
      display: inline-block;
      overflow:hidden;
    }
    
    .header {
      display: inline;
      border: green 1px solid;
      margin: 0;
    }

    Some Text Some Text Some Text

    Some Text Some Text Some Text

    Some Text Some Text Some Text

    Basically nothing to align and all the alignments are almost equivalent simply because the text is defining the line-box thus its height is equal to the height of the line box and there is no room for alignment.

    Now let's increase the height of the line (using line-height)

    #outer {
      box-sizing: border-box;
      border: red 1px solid;
      height: 200px;
      text-align: center;
    }
    
    #inner {
      border: blue 1px solid;
      height: 200px;
      width:180px;
      line-height:200px;
      display: inline-block;
    }
    
    .header {
      display: inline;
      border: green 1px solid;
      margin: 0;
      line-height:1em;
    }

    Some Text Some Text Some Text

    Some Text Some Text Some Text

    Some Text Some Text Some Text

    See how each line is now bigger and each text is aligned on its respective line that has a height of 200px and we can clearly see how the alignment are different.

    In this case, the text has enough room to be aligned like you want and we see the magic if we keep only one line of text:

    #outer {
      box-sizing: border-box;
      border: red 1px solid;
      height: 200px;
      text-align: center;
    }
    
    #inner {
      border: blue 1px solid;
      height: 200px;
      line-height: 200px;
      display: inline-block;
    }
    
    .header {
      display: inline;
      border: green 1px solid;
      margin: 0;
      line-height:1em;
    }

    Some Text

    Some Text

    Some Text

    Some Text

    You may also note how middle and baseline are very close because:

    Aligns the middle of the element with the baseline plus half the x-height of the parentref

    There is only a half x-height of difference.

    Another important fact to note is that if we don't set a line height to the inline element this one will inherit the line-height of his parent and alignment like top won't have any effect.

    #outer {
      box-sizing: border-box;
      border: red 1px solid;
      height: 200px;
      text-align: center;
    }
    
    #inner {
      border: blue 1px solid;
      height: 200px;
      line-height: 200px;
      display: inline-block;
    }
    
    .header {
      display: inline;
      border: green 1px solid;
      margin: 0;
    }

    Some Text

    Some Text

    Some Text

    Aligns the top of the element and its descendants with the top of the entire line.

    Having the same line-height means that the element is already at the top and also the bottom of the line box so both top bottom will behave like baseline (the default value).


    The height of the line-box can also be controled by the height of elements. You may have a big font-size for one element that will make the height of the line bigger and have enough room to align small texts next to it in the same line box:

    #outer {
      box-sizing: border-box;
      border: red 1px solid;
      height: 200px;
      text-align: center;
    }
    
    #inner {
      border: blue 1px solid;
      height: 200px;
      display: inline-block;
    }
    
    .header {
      display: inline;
      border: green 1px solid;
      margin: 0;
    }
    @keyframes change {
      from {font-size:20px;}
      to {font-size:100px;}
    }

    Text

    T

    Text

    Text

    Text

    You can also constrol the line box by setting height of inline-block element:

    #outer {
      box-sizing: border-box;
      border: red 1px solid;
      height: 200px;
      text-align: center;
    }
    
    #inner {
      border: blue 1px solid;
      height: 200px;
      display: inline-block;
    }
    
    .header {
      display: inline;
      border: green 1px solid;
      margin: 0;
    }
    .elem {
     display:inline-block;
     background:red;
     width:2px;
     height:5px;
     animation:change 5s linear alternate infinite;
    }
    @keyframes change {
      from {height:20px;}
      to {height:100px;}
    }

    Text

    Text

    Text

    Text

    As a conclusion: to align using vertical-align you should have a line box that has a height bigger enough (explicitely set or set by other elements) where you can align your element. If your element is defining the line-box (which is the common case) then there is nothing to align.


    Some good questions to have more detais:

    Vertical align not working on inline-block

    Inline elements and line-height

    My inline-block elements are not lining up properly

    Why is this inline-block element pushed downward?

提交回复
热议问题