Yeah, yeah, I know this is yet another question about vertical alignment with CSS and it's been done a million times before. Rest assured that I have come across this problem many times and I've already done the reading about various ways to centre vertically with CSS. I'm asking here because none of those ways do quite what I want to do, and I just want to make sure that my suspicion (that CSS vertical alignment is broken and will not do what I want it to do) is definitely correct.
First up, here's my test case: http://www.game-point.net/misc/testAlign/
Here's the criteria:
This seems to be impossible even in CSS3, let alone CSS2. The annoying thing is that I'm almost there; the position:absolute; top:-50%;
DIV works to set the top of that DIV to halfway down the container DIV. The problem is that the inner DIV, with style position:relative; top:-50%;
doesn't do anything to move the content up by half its height, to centre it fully, because CSS says that an absolutely positioned DIV doesn't have a height and therefore top:-50%
is meaningless. As far as I can tell, this is just a fundamental flaw in CSS for no particular reason. An absolutely positioned element does have a height, and I don't know why CSS pretends it doesn't. I just wanted to ask whether anyone had any ideas as to how I could achieve the desired effect, pictured at the bottom, given the criteria I outlined above. Ironically IE6/7/8's 'broken' box model, in quirks mode, gives me this very effect. Shame they're 'fixing' it in IE9 so it won't anymore.
The CSS just sizes the div, vertically center aligns the span by setting the div's line-height equal to its height, and makes the span an inline-block with vertical-align: middle. Then it sets the line-height back to normal for the span, so its contents will flow naturally inside the block.
OK, my suspicion was indeed correct and this is not possible (I think it's a flaw in CSS and they should provide a means of vertical alignment within a DIV without specifying inner element heights).
The least bad solution I ended up with was this: specify the height of the 'middle' DIV - that is, the DIV which is displayed using position:absolute
and contains the real content. I've added it to the test case page at http://www.game-point.net/misc/testAlign/ under the heading With line-height:100% and hardcoded 'middle' DIV height. This solution means that you must know the height of the content to be vertically centred in advance, which sucks because the browser calculates this and you shouldn't need to specify it, but it's the only way (until CSS gets its act together). I used em
s to specify the height too, so that zooming text in and out doesn't ruin the vertical centring. Turns out that for the 2 lines of 'Centred text' I had, this height equates to exactly 2 em
s (at least on my machine). If I were to change that content's height, or it were to change dynamically to say 3 lines or 1 line, the parent div
's hardcoded em
height would also have to change.
So, here's the code I finally ended up with if anyone's interested:
<div style="border:1px solid black; padding-left:60px; width:250px; position:relative; word-wrap:break-word;">
TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest
<!-- Unfortunately, must set this DIV's height explicitly or the contained DIV's relative positioning won't work, as this DIV is considered to have NO implicit height -->
<div style="position:absolute; display:block; top:50%; left:0px; height:2em;">
<div style="position:relative; top:-50%; background-color:#00aa00; line-height:100%;">
Centred text<br/>
Centred text
</div>
</div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With