Harter Harter - 2 years ago 80
HTML Question

Vertically center text inside a div

I'm trying to vertically center some text inside a div. Sounds easy but I can't get it. Here's the code, sorry for the bad formatting and practices, it's something whipped up fast and dirty:



<div id="container" style="text-align:center ;border: 5px solid blue; display:flex; flex-direction:row ; justify-content:center; height:100px">
<div id="first" style=" min-height:100px; min-width:200px; background-color:green">
<div style="vertical-align:middle">
first box
</div>
</div>
<div id="second" style=" min-height:100px; min-width:200px; background-color:yellow">
<div style="vertical-align:middle">
second box
</div>
</div>
<svg version="1.1" id="SVG" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 300 300" preserveAspectRatio="xMidYMid meet" height="100%" width: "auto">
<!--snipped away svg code-->

</svg>
<div id="third" style="min-height:100px; min-width:200px; background-color:red">
<div style="">
third box
</div>
</div>
<div id="fourth" style="min-height:100px; min-width:200px; background-color:cyan; vertical-align:middle ">
<p>
fourth box
</p>
</div>

</div>





As you can see, there's four boxes around a central svg image. Horizontally centering the elements inside the "container" div was easy, vertically centering the text inside each of those elements is not. Not at all.

I've tried various solutions, none of which worked like intended (the text just goes up to the top of the box). Am I missing something obvious or am I trying to do something impossible?

I'm looking for a flexible solution, something that can work without knowing the exact height in pixels of the boxes nor the container.

Answer Source

Since you are using flexbox, you don't need to use vertical-align.

Here are two things to consider:

  1. When you create a flex container only the child elements become flex items. Any descendant elements beyond the children are not flex items and flex properties don't apply to them.

    Your div boxes wrapping your text are not flex items. They are children of flex items (#first, #second, etc.) and flex properties don't apply.

  2. If you want to apply flex properties to the children of flex items, you need to make the flex item a flex container, as well.

    Try this:

    #first { 
        display: flex; 
        justify-content: center; 
        align-items: center;
    }
    
    #second { 
        display: flex; 
        justify-content: center; 
        align-items: center;
    }
    

#first {
  display: flex;
  justify-content: center;
  align-items: center;
}

#second {
  display: flex;
  justify-content: center;
  align-items: center;
}
<div id="container" style="text-align:center ;border: 5px solid blue; display:flex; flex-direction:row ; justify-content:center; height:100px">
  <div id="first" style=" min-height:100px; min-width:200px; background-color:green">
    <div style="vertical-align:middle">first box</div>
  </div>
  <div id="second" style=" min-height:100px; min-width:200px;  background-color:yellow">
    <div style="vertical-align:middle">
      second box
    </div>
  </div>
  <svg version="1.1" id="SVG" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 300 300" preserveAspectRatio="xMidYMid meet" height="100%" width: "auto">
       <!--snipped away svg code-->

</svg>
  <div id="third" style="min-height:100px; min-width:200px; background-color:red">
    <div style="">
      third box
    </div>
  </div>
  <div id="fourth" style="min-height:100px; min-width:200px; background-color:cyan; vertical-align:middle ">
    <p>
      fourth box
    </p>
  </div>

</div>


Re: vertical-align

The reason vertical-align: middle wasn't working for you is because this property centers within the inline dimension. So it actually was vertically centering the text... within its line-height. To get the behavior you expect, specify a line-height equal to the container height.

#third {
    vertical-align: middle;
    line-height: 100px;
}

#first {
  display: flex;
  justify-content: center;
  align-items: center;
}

#second {
  display: flex;
  justify-content: center;
  align-items: center;
}

#third {
  vertical-align: middle;
  line-height: 100px;
}
<div id="container" style="text-align:center ;border: 5px solid blue; display:flex; flex-direction:row ; justify-content:center; height:100px">
  <div id="first" style=" min-height:100px; min-width:200px; background-color:green">
    <div style="vertical-align:middle">first box</div>
  </div>
  <div id="second" style=" min-height:100px; min-width:200px;  background-color:yellow">
    <div style="vertical-align:middle">
      second box
    </div>
  </div>
  <svg version="1.1" id="SVG" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 300 300" preserveAspectRatio="xMidYMid meet" height="100%" width: "auto">
       <!--snipped away svg code-->

</svg>
  <div id="third" style="min-height:100px; min-width:200px; background-color:red">
    <div style="">
      third box
    </div>
  </div>
  <div id="fourth" style="min-height:100px; min-width:200px; background-color:cyan; vertical-align:middle ">
    <p>
      fourth box
    </p>
  </div>

</div>

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download