htmlcsssvgalignmentvertical-alignment

Vertical Alignment of SVG in CSS


I have a problem with inline SVG alignment. I have created a button with some text and an SVG. And while the alignment works correctly when the SVG is at least as big as the text it fails when the SVG height is smaller than the text.

I have created a test case with a two-colored background button to indicate where exactly the middle is. You can see if you look closer that the second case is not perfectly aligned because the height of the SVG is less than the one from the text.

Is there any way to fix this? Doing it some other way (no js please)?

a {
  display: inline-block;
  margin: 10%;
  background-image: linear-gradient(to bottom,white 0%, white 50%, red 50%, red 100%);
  padding: 5%;
}

svg {
  fill: blue;
  height: 1em;
  vertical-align: middle;
}

#arrow-right {
  height: 0.9em;
}
<a href="#">
  GO
  <svg version="1"  xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 10 16" style="enable-background:new 0 0 10 16;" xml:space="preserve">
    <path d="M0,0v16l10-8L0,0z"/>
  </svg>
</a>

<br/>

<a href="#">
  GO
  <svg version="1" id="arrow-right" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 10 16" style="enable-background:new 0 0 10 16;" xml:space="preserve">
    <path d="M0,0v16l10-8L0,0z"/>
  </svg>
</a>


Solution

  • jsfiddle 1 - You can use position:relative on the container and position:absolute on the objects like this:

      position: absolute;
      top: 50%;
      -webkit-transform: translateY(-50%);
      -ms-transform: translateY(-50%);
      transform: translateY(-50%);
      left: 0;
      right: 0;
      margin: auto;
      text-align: center;
    

    The top: 50% moves the object to the container's vertical center picking the top of the object as reference (not its center), so the transform: translateY moves it a distance of 50% of it's size upwards to let it exactly on the middle of the container (by the objects center).

    ps: the text-align:center; left:0; right:0; and margin:auto are for horizontal align.

    jsfiddle 2 - Or use display:flex on the container with align-items to vertical align the content like this:

      display: -webkit-flex; /* Safari */  
      display: flex;
      -webkit-align-items: center; /* Safari 7.0+ */
      align-items: center;
      -webkit-justify-content: center;
      justify-content: center;
    

    ps: the justify content is for horizontal align.