Search code examples
cssvertical-alignment

Vertically align div in a parent of variable height


I have a wrapper, whose height is variable (depending on the content in the left box). I want the button inside this wrapper to be vertically aligned inside the right side box.

I am not able to get it to work, though I have tried quite a few things, including css-tricks' post on centering, which I've put under comments. I tried tinkering with flexbox too, but didn't work.

.wrapper {
    width: 20em;
    margin: 1em;
    border: 1px solid #999;
    overflow: hidden;
}
.left {
    float: left;
    width: 70%;
}
.right {
    position: relative;
    overflow: hidden; /* to induce block formatting context */
}
.button {
    width: 3em;
    border: 1px solid #999;
    margin: 0 auto;

    /*
    // The below didn't work! the `button` vanishes.
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    */
}
<div class="wrapper">
  <div class="left">Every person is worth just as much as the things they busy themselves with.</div>
  <div class="right">
    <div class="button">button</div>
  </div>
</div>


Solution

  • The primary issue here is that you need the left and right divs to have the same height automagically. Other than javascript, only flexbox and css tables allow for that. So...

    Flexbox can do that.

    .wrapper {
      width: 20em;
      margin: 1em;
      border: 1px solid #999;
      overflow: hidden;
      display: flex;
    }
    .left {
      flex: 0 0 70%;
    }
    .right {
      flex: 1;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .button {
      width: 3em;
      border: 1px solid #999;
      text-align: center;
    }
    <div class="wrapper">
      <div class="left">Every person is worth just as much as the things they busy themselves with.</div>
      <div class="right">
        <div class="button">button</div>
      </div>
    </div>

    OR...CSS Tables

    .wrapper {
      width: 20em;
      margin: 1em;
      border: 1px solid #999;
      overflow: hidden;
      display: table;
      table-layout: fixed;
    }
    
    .left {
      display: table-cell;
      width: 70%;
    }
    
    .right {
      display: table-cell;
      width: 30%;
      vertical-align: middle;
      text-align: center;
    }
    
    .button {
      width: 3em;
      border: 1px solid #999;
      margin: auto;
    }
    <div class="wrapper">
      <div class="left">Every person is worth just as much as the things they busy themselves with.</div>
      <div class="right">
        <div class="button">button</div>
      </div>
    </div>