<div class="text">
<span>Some Text</span>
</div>
There was some talk about CSS not allowing elements to be in vertical center of container of viewport. This document explains few methods to do vertical align. The real problem is that browser support is not best, especially bad is support of MS Internet Explorer, that is currently most used browser.
This document is currently bit illogical, because I'm working on it. (Adding more stuff about blocks)
If you want something in your table vertically centered, just add vertical-align:middle for table cell.
I is not complicated at all to vertically center things if you can use same unit for all measures - then you can set elements top margin. So if you have 100px high div and 50px high image, when you set margin-top:25px for image it is aligned in the middle of div.
As centering by setting margins is far better supported than other methods, so that should be used when ever possible.
There is several aproaches for centering content. In practice, we need to have parent element with bigger height than element we are trying to align in the middle of it.
<div class="text">
<span>Some Text</span>
</div>
.text, .image, .block /* All container divs*/
{width:14em;height:8em;margin:0.5em;
border:thick solid;background:#fff;}
.text {border-color:#99f;} /* pastel blue border */
<div class="image">
<img src="blue.gif"
alt="blue square">
</div>
.text, .image, .block /* All container divs*/
{width:14em;height:8em;margin:0.5em;
border:thick solid;background:#fff;}
.image {border-color:#f99;} /* pastel red border */
.image img {width:50px;height:50px;} /* image size */
<div class="block">
<div>
Block element, with long enough content to wrap.
</div>
</div>
.text, .image, .block /* All container divs*/
{width:14em;height:8em;margin:0.5em;
border:thick solid;background:#fff;}
.block {color:#ff4;} /* pastel yellow border */
.block div {border:dashed;width:10em;} /* to make it more interesting*/
Easy way to center short pieces of text and images is using line-height as big as container height. This only works for inline elements.
div {line-height:8em;}
img {vertical-align:middle;}
Notice that vertical-align is only used for image. That is because it is not needed for text, as it aligns nicely whitout it.
This method does not work nicely at all if image is higher than container, or if text wraps. So don't use it if that may happen.
Browsers | How it works |
---|---|
Opera 7.51p1, 8b3; Mozilla 1.4.1; FF1; Konqueror 3.1.4-6; MacIE5; Safari 1.1.1 | Works |
IE5.5; IE6; Opera 6 | Text centering works |
This method is quite handy, if you know height of element or image you want to center.
div {position:relative;}
span, .block div
{position:absolute;top:0;bottom:0;margin:auto;}
span {height:1em;}
.block div {height:2.4em;}
Notice that I have limited height of text and block. This means I need to know it. In case of using 1em for 2 words, you can be somewhat confident that they won't wrap. But in case of block with more than one line of text, it is harder to guess right height. 2.4em is good, if TMR is used. But if Arial, for example, it won't work. Setting font explicitly don't help much (for example my default settings show both in same font)
div {position:relative;}
.block div {position:absolute;top:0;bottom:0;margin:auto;}
.block div {height:2.4em;display:table;}
This version makes box strech, instead of overflowing, but to have it center, you still need to guess the height right.
div {position:relative;}
img {position:absolute;top:0;bottom:0;margin:auto;}
.image {min-height:50px}
For image, this is easier, because you know dimensions in pixsels. But you need to set min-height for container, as you are using different units for height.
Browsers | How it works |
---|---|
Opera 6.04, 7.51p1, 8b3; FF1; Konqueror 3.1.4-6; Safari 1.1.1 | Works |
Mozilla 1.4.1; | Works, if container is not floated |
IE5.5; IE6; MacIE5; | Does not work |
NN4 | Must be hidden from NN4 |
Works and it should work, as vertical-align aplies to
table-cell and behaves differently when used for
table-cell. Problem is that you can't now specify percentage
width for div, as it is undefined. OTOH, you can just
but it in another div and say display:table
for outer div.
This method also works for block level content.
.text, .image, .block {display:table-cell;}
div, img { vertical-align:middle;}
Notice that vertical-align is used also for image. That
is because otherwise it won't be exactly centered. You could
also use img {display:block;}
.
Notice that browser may act strangely when using display:table-cell and float for example, as float don't apply to table-cell. So you can't able to use float and this method. Also, if multible elements with display:table-cell are adjecent, like in this page, they will be considered as one table.
Min-height is not necessary in this method, as display:table-cell will strech with content, if it is too big.
Browsers | How it works |
---|---|
Opera 6.04, 7.51p1, 8b3; Mozilla 1.4.1; FF1; Konqueror 3.1.4-6; Safari 1.1.1 | Works |
IE5.5; IE6; MacIE5; | Does not work. |
Negative margin may cause content to be rendered even outside canvas, if browser don't support min-height.
div {min-height:50px !important;}
img {position:relative;top:50%;margin-top:-25px;}
span{position:relative;top:50%;margin-top:-0.5em;}
Buggy in Opera 7.5p1, 8.01 border width somehow interferes and content won't be in exact center. Works in IE6, IE5.5 and MacIE5 and Safari 1.1.1. Example with text needs to be hidden from NN4. Breaks in Mozilla 1.4.1 and Konqueror 3.1.4-6 for some odd reason. Opera 6 is differently buggy
This method is well supported, but negative margin may cause content to be rendered even outside canvas, if browser don't support min-height.
div {position:relative;min-heigth:50px !important;}
img {position:absolute;top:50%;margin-top:-25px;}
span{position:absolute;top:50%;margin-top:-0.5em;line-height:1}
Buggy in Opera 6 and 7.5p1 and Konqueror 3.1.4-6 and Safari 1.1.1, border width somehow interferes and content won't be in exact center. Works in IE5.5, IE6 and MacIE5. Example with text needs to be hidden from NN4. Breaks in Mozilla 1.4.1 for some odd reason if float is used. See note about that earlier in this page.
This method is well supported, but negative margin may cause content to be rendered even outside canvas.
div {padding-top:4em;
height:8em; /* This is part of*/
voice-family: "\"}\""; /* Tantek hack */
voice-family:inherit; /* as is following*/
height:4em;
}
html>body div {height:4em;} /* be nice to Opera rule*/
img {margin-top:-25px;}
span{margin-top:-0.5em;display:block;}
This is prone to break when content is bigger than container + padding. And min-height can't be used because half of visible height of div is actually padding. So if 25px > 4em, this looks nasty.
Probably works in Opera 4+, Mozilla, Konqueror 3.1.4-6, IE6 and MacIE5 and Safari 1.1.1, older IEs with Tantek's box modell hack. If you don't bother to support older IEs just remove all lines with comments
Setting line height equal to container width, and using inline-block for content should center thing vertically. This method don't work in current browsers
.block {line-height:8em;}
.block div {display:inline;display:inline-table;display:inline-block;
vertical-align:middle;}
If you wonder why there is display:inline, that is because it is needed for inline-block to be recognized by IE6 standards mode. Inline-table is for Opera 5+.
Browsers | How it works |
---|---|
IE6 | Does not work |
Opera 7.5, 8b3; | Does not work, breaks badly (would work little better when display:inline-table would be after display:inline-block) |
FF1 | Breaks very badly |
I haven't been able to test this with Opera <7, IE<6, MacIE, any khtml. It migh actually work on one of these