37

I have a div which contains two child divs, and they are intended to be part of fluid layout, so I can't set a fixed size for them in px.

There are two goals here:

  1. Align the two child divs horizontally, which I have achieved using float: left and float: right respectively.

  2. Vertically center the text (within the child divs) relative to the parent div. The text is short and takes a single line by design.

What I have now: http://jsfiddle.net/yX3p9/

Apparently, the two child divs do not take the full height of the parent div, and therefore their text are not vertically centered relative to the parent div.

Conceptually, to achieve the goals above, we can either make the child divs vertically centered within the parent div, or we can make the child divs take the full height of the parent div. What is the robust way to do so?

*Browser support: IE 9+ and other usual modern browsers.

MLister
  • 9,252
  • 17
  • 59
  • 89
  • If you want to take two child height to be full length of div then you can use height:100% !important.. but even that doesnt align the contents to center – Guruprasad J Rao Aug 01 '13 at 14:28

7 Answers7

45

I prefer the usage of transform above the above answers.

top: 50%;
transform: translateY(-50%);
-ms-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-webkit-transform: translateY(-50%);
-o-transform: translateY(-50%);

In my experience it works in many situations and on all major browsers (even IE9+).

If you use SCSS, you might even like to implement this mixin:

@mixin v-align($position: absolute){
    position: $position;  top: 50%;  
    transform: translateY(-50%);
    -ms-transform:translateY(-50%); /* IE */
    -moz-transform:translateY(-50%); /* Firefox */
    -webkit-transform:translateY(-50%); /* Safari and Chrome */
    -o-transform:translateY(-50%);
}
Bart Burg
  • 4,618
  • 7
  • 50
  • 86
31

I updated your fiddle: http://jsfiddle.net/yX3p9/7/

I used display: table-cell; in order to use vertical-align: middle;

Ferdinand Torggler
  • 1,264
  • 10
  • 11
  • You could set the line-height to the parent div. But in your case, the parent has a percentage as height, so you can't do that. A line-height of 100% would mean that the line should have the same height as the text. – Ferdinand Torggler Aug 01 '13 at 14:59
6

Use line-height. If it's just one line of text, a high line-height will effectively position the text in the middle of the line.

Or try display:table-cell in combination with vertical-align.

DanMan
  • 10,986
  • 4
  • 38
  • 58
  • how does `line-height` work in this scenario? Tried `display:table-cell` and `vertical-align`, but didn't work. – MLister Aug 01 '13 at 14:16
2

In addition to using CSS tables, you can also use absolute positioning to get a similar layout.

Using your HTML as is (no extra elements), apply the following CSS:

html, body {
    height: 100%;
    width: 100%;
    font-size: 13px;
}
.parent {
    background-color: grey;
    height: 20%;
    line-height: 1.6em;
    font-size: 1.6em;
    min-height: 1.6em;
    position: relative;
}
.left, .right {
    position: absolute;
    top: 50%;
    margin-top: -0.8em;
}
.left {
    background-color: yellow;
    padding-left: 20px;
    left: 0;
}
.right {
    background-color: red;
    padding-right: 20px;
    right: 0;
}

You can see the demo fiddle at: http://jsfiddle.net/audetwebdesign/cByHa/

In the .parent container, set the line-height to an explicit value (1.6em as the font size), position: relative and min-height to maintain enough height for the text.

The two child elements .left and .right are positioned absolutely with top: 50% and use margin-top: -0.8em to get vertical centering (use one-half of line-height value).

Use the left and right offsets (or padding) to adjust the child elements horizontal position as needed.

Marc Audet
  • 44,417
  • 10
  • 61
  • 82
1
<div style="position:relative;white-space:nowrap">
  <img style="visibility:hidden; width:1px; height:100%; verticle-align:middle" />
  <img src="the-image-url" style="position:relative;left:-1px;" />
</div>

This should work.

Shrdi
  • 333
  • 3
  • 12
0
    html, body {
    height: 100%;
    width: 100%;
    font-size: 13px;
}

.parent {
    height: 50px;
    background-color: grey;
    font-size: 1.6em;
}

.left {
    margin-left: 2%;
    float: left;
    background-color: yellow;
    height:100%;   
}

.right {
    margin-right: 2%;
    float: right;
    background-color: red;
    height:100%;    
}
.parent span{
    display:table;
    height:100%;
}
.parent em{
    display:table-cell;
    vertical-align:middle;

}

http://jsfiddle.net/yX3p9/13/

QArea
  • 4,887
  • 1
  • 11
  • 22
0

Make Height and Width as 100% in child element. This was the child will occupy entire space of parent and vertical-align:middle property will work. I used it in a case when parent was a <div> and child was a <table>. Table was marked to take height and width as 100%.

Aliaksandr Sushkevich
  • 9,760
  • 6
  • 35
  • 41
Vikas P
  • 11