173

I am trying to get blue container in the middle of pink one, however seems vertical-align: middle; doesn't do the job in that case.

<div style="display: block; position: absolute; left: 50px; top: 50px;">
    <div style="text-align: left; position: absolute;height: 56px;vertical-align: middle;background-color: pink;">
        <div style="background-color: lightblue;">test</div>
    </div>
</div>

Result:

enter image description here

Expectation:

enter image description here

Please suggest how can I achieve that.

Jsfiddle

Vladimirs
  • 7,364
  • 4
  • 37
  • 68
  • 2
    Is there a reason why are you using `position: absolute` everywhere? – Vucko Feb 11 '15 at 13:08
  • the `vertical-align: middle;` works with `display: inline-block` or table layout – ctf0 Feb 11 '15 at 13:09
  • check this link: http://www.vanseodesign.com/css/vertical-centering/ ;) – Jordi Castilla Feb 11 '15 at 13:11
  • @Vucko yes - that is prerequisite as this is just simplified version of very complex layout, but absolute position in both top divs is key thing. – Vladimirs Feb 11 '15 at 13:19
  • @Vladimirs I can only think of `margin-top: calc((56px - 16px) / 2)`, where `56px - parent height`, `16px - element height/font-size` - [JSFiddle](http://jsfiddle.net/dcsc6ey6/) – Vucko Feb 11 '15 at 13:32
  • @Vucko thanks, but problem is that `test` text changes dynamically and it might be more than in one line so that seems requires some javascript, but I am looking for css-only solution. – Vladimirs Feb 11 '15 at 13:40
  • Can you expain why and the needs , you inbricate 2 elements in absolute position ? – G-Cyrillus Feb 11 '15 at 14:26

9 Answers9

385

First of all note that vertical-align is only applicable to table cells and inline-level elements.

There are couple of ways to achieve vertical alignments which may or may not meet your needs. However I'll show you two methods from my favorites:

1. Using transform and top

.valign {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
    /* vendor prefixes omitted due to brevity */
}
<div style="position: absolute; left: 50px; top: 50px;">
    <div style="text-align: left; position: absolute;height: 56px;background-color: pink;">
        <div class="valign" style="background-color: lightblue;">test</div>
    </div>
</div>

The key point is that a percentage value on top is relative to the height of the containing block; While a percentage value on transforms is relative to the size of the box itself (the bounding box).

If you experience font rendering issues (blurry font), the fix is to add perspective(1px) to the transform declaration so it becomes:

transform: perspective(1px) translateY(-50%);

It's worth noting that CSS transform is supported in IE9+.

2. Using inline-block (pseudo-)elements

In this method, we have two sibling inline-block elements which are aligned vertically at the middle by vertical-align: middle declaration.

One of them has a height of 100% of its parent and the other is our desired element whose we wanted to align it at the middle.

.parent {
    text-align: left;
    position: absolute;
    height: 56px;
    background-color: pink;
    white-space: nowrap;
    font-size: 0; /* remove the gap between inline level elements */
}

.dummy-child { height: 100%; }

.valign {
    font-size: 16px; /* re-set the font-size */
}

.dummy-child, .valign {
    display: inline-block;
    vertical-align: middle;
}
<div style="position: absolute; left: 50px; top: 50px;">
    <div class="parent">
        <div class="dummy-child"></div>
        <div class="valign" style="background-color: lightblue;">test</div>
    </div>
</div>

Finally, we should use one of the available methods to remove the gap between inline-level elements.

Community
  • 1
  • 1
Hashem Qolami
  • 88,138
  • 25
  • 132
  • 151
72

use this :

.Absolute-Center {
    margin: auto;
    position: absolute;
    top: 0; left: 0; bottom: 0; right: 0;
}

refer this link: https://www.smashingmagazine.com/2013/08/absolute-horizontal-vertical-centering-css/

22

Use flex blox in your absoutely positioned div to center its content.

See example https://plnkr.co/edit/wJIX2NpbNhO34X68ZyoY?p=preview

.some-absolute-div {    
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -moz-flex;
  display: -ms-flexbox;
  display: flex;

  -webkit-box-pack: center;
  -ms-flex-pack: center;
  -webkit-justify-content: center;
  -moz-justify-content: center;
  justify-content: center;

  -webkit-box-align: center;
  -ms-flex-align: center;
  -webkit-align-items: center;
  -moz-align-items: center;
  align-items: center;
}
Chris Aelbrecht
  • 1,701
  • 16
  • 24
  • 1
    Yes, flexbox is the way to go in 2021! Although make sure to use `top: 0; bottom: 0; left:0; right 0;` so that first its dimensions become same as that of relatively positioned parent div, and then magic of flexbox kicks in! – Jaladh Singhal Jan 06 '21 at 15:11
19

Center vertically and horizontally:

.parent{
  height: 100%;
  position: absolute;
  width: 100%;
  top: 0;
  left: 0;
}
.c{
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
}
Juan Angel
  • 460
  • 4
  • 6
5

You may use display:table/table-cell;

.a{
   position: absolute; 
  left: 50px; 
  top: 50px;
  display:table;
}
.b{
  text-align: left; 
  display:table-cell;
  height: 56px;
  vertical-align: middle;
  background-color: pink;
}
.c {
  background-color: lightblue;
}
<div class="a">
  <div  class="b">
    <div class="c" >test</div>
  </div>
</div>
G-Cyrillus
  • 85,910
  • 13
  • 85
  • 110
  • Thanks, your example works perfect, however `.b` missing `position: absolute;` which is important to get other things displayed property which I not included to keep code clearer. I know that makes no sense having table-cell absolutely positioned but maybe there is another approach that will allow to retain `position: absolute;` in both `.a` and `.b` classes? – Vladimirs Feb 11 '15 at 13:31
  • if a is absolute position, and b (the child) giving it it's size, b is itself in absolute position towards the rest of the content. unless a is suppose to remain unsized i do not understand the purpose of absolute inside absolute ? – G-Cyrillus Feb 11 '15 at 14:24
2

Here is simple way using Top object.

eg: If absolute element size is 60px.

.absolute-element { 
    position:absolute; 
    height:60px; 
    top: calc(50% - 60px);
}
Sainul Abid
  • 89
  • 1
  • 8
  • 2
    Using `calc` is helpful, though this should be `top: calc(50% - 30px)` for it to actually be centered. – brainbag Jun 21 '18 at 09:55
2

An additional simple solution

HTML:

<div id="d1">
    <div id="d2">
        Text
    </div>
</div>

CSS:

#d1{
    position:absolute;
    top:100px;left:100px;
}

#d2{
    border:1px solid black;
    height:50px; width:50px;
    display:table-cell;
    vertical-align:middle;
    text-align:center;  
}
Hicham
  • 21
  • 6
1

You can do it by using display:table; in parent div and display: table-cell; vertical-align: middle; in child div

<div style="display:table;">
      <div style="text-align: left;  height: 56px;  background-color: pink; display: table-cell; vertical-align: middle;">
          <div style="background-color: lightblue; ">test</div>
      </div>
  </div>
Arindam Sarkar
  • 214
  • 1
  • 10
  • 3
    it's possible that your answer is good but you can improve it very much by adding some description of what your code does... – DaFois Nov 10 '18 at 09:27
0

For only vertical center

    <div style="text-align: left; position: relative;height: 56px;background-color: pink;">
        <div style="background-color: lightblue;position:absolute;top:50%;    transform: translateY(-50%);">test</div>
    </div>

I always do like this, it's a very short and easy code to center both horizontally and vertically

.center{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
<div class="center">Hello Centered World!</div>
Karan Goyal
  • 153
  • 1
  • 7
  • This answer has already been given in the accepted answer. – TylerH Aug 17 '20 at 18:59
  • That mean's i can't add any new things here @TaylerH – Karan Goyal Aug 17 '20 at 19:06
  • There are plenty of other questions asked each day in [tag:html] or [tag:css] for you to try and answer. You should only post an answer if you can add something new to any existing answers. Repetition of content doesn't help anyone. – TylerH Aug 17 '20 at 21:39