PDA

View Full Version : Resolved Is TABLE the only good solution for vertical centering?



freedom_razor
Dec 17th, 2008, 08:38 PM
I've got some image I want to center on screen. HTML below:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"></meta>
<title>Sell your soul to the TABLES!</title>
<style>body, html {width:100%; height:100%; margin:0px; padding:0px;}</style>
</head>
<body>
...see options below...
</body>
</html>

Below some possible solutions:


<!--from Meyer's CSS Guide, only works in FireFox [IE7/Opera9 fail]------------------>
<style>#cent {position:absolute; top:0; right:0; bottom:0; left:0; margin:auto;}</style>
<img id="cent" src="gallery/nice.jpg" />



<!--would need some JavaScript to make it work for different sized images-->
<style>#box {width:600px; height:400px; position:relative; top:50%; left:50%;
margin:-200px 0 0 -300px; border: 1px solid black;}</style>
<div id="box"><img src="gallery/nice.jpg" /></div>



<!--TABLES, like all evil things have that special power of making your wishes come true, works in all browsers-->
<table style="width:100%; height:100%;"><tr><td style="text-align:center;">
<img src="gallery/nice.jpg" />
</td></tr></table>

I'm also aware of using display:table-cell [which doesn't work in IE7].
So, I want to ask if the easiest and working on all browsers method is a table? Or did I miss something?

itsallkizza
Dec 17th, 2008, 08:54 PM
This one's a little messy because of the IE browser hack (#) and the use of display:table and display:table-cell. But it works in all the browsers I've tested and "messy" is really unavoidable without Javascript:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Example</title>
<style type="text/css">
.container_with_unknown_height
{
display: table;
#position: relative;
overflow: hidden;

height: 600px; /* This can be anything - even auto (default). */

background-color: #ff0000; /* Just for visuals. */
}

.element_to_center-wrapper
{
#position: absolute;
#top: 50%;
display: table-cell;
vertical-align: middle;
}

.element_to_center-content
{
#position: relative;
#top: -50%;

background-color: #0000ff; /* Just for visuals. */
}
</style>
<script type="text/javascript">
// <![CDATA[
// ]]>
</script>
</head>
<body>

<div class="container_with_unknown_height">
<div class="element_to_center-wrapper"><div class="element_to_center-content">
Vertically Centered Content<br />
More Content<br />
More Content
</div></div>
</div>

</body>
</html>


Also try adding a whole lotta <br />s inside the container and deleting the height:600px from the CSS - it'll still center it (so it'll work with dynamically generated content).

Only real downside to this method is that it's outside the flow in IE (which means you need some content or a height in your container to stretch it out, and it won't interact with your container's real content).

Excavator
Dec 17th, 2008, 09:11 PM
Hello freedom_razor,
I found this a long time ago, it's not mine and now I don't know where I got it. If it works for you, don't give me any credit for anything but finding it.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"><html><head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"><title>CSS vertical center using float and clear</title> <style type="text/css">

* {
margin:0;
padding:0;
}

html, body {
height:100%;
}

body {
background-color:#fc6;
color:#630;
font:100.01%/1.4 sans-serif;
text-align:center; /* horizontal centering for IE Win quirks */
}

#distance {
width:1px;
height:50%;
background-color:#fc6;
margin-bottom:-13.75em; /* half of container's height */
float:left;
}

#container {
margin:0 auto;
position:relative; /* puts container in front of distance */
text-align:left;
height:27.5em;
width:45em;
clear:left;
background-color:#ff9;
border:1px solid #c93;
border-top-color:#fff;
border-left-color:#fff;
}

#container div {
font-size:80%;
float:right;
width:17em;
margin-left:2em;
}

#container div h2 {
font-size:120%;
font-weight:bold;
text-transform:uppercase;
margin:1em 0 0;
}

#container div h3 {
font-size:100%;
font-weight:bold;
margin:.5em 0 0 .75em;
}

#container ul {
margin-left:2em;
}

#container li span {
font-size:70%;
}


#container h1 {
font-size:120%;
padding-top:2.4em;
margin-left:2.4em;
}

#container p {
margin:1.5em 13.6em 1.5em 3em;
}

address {
font-weight:normal;
font-size:80%;
font-style:normal;
text-align:right;
margin:0 20em 0 3em;
}

</style><style type="text/css">@import("iemac-center.css");</style></head><body> <div id="distance"></div> <div id="container"> <div> <h2>Tested in</h2> <h3>Win XP SP1</h3> <ul> <li>Firefox 1.04</li> <li>Opera 6.06 / 7.23 / 8.0</li> <li>Netscape 6.1 / 7.1</li> <li>IE 5.0 / 5.5 / 6</li> </ul> <h3>Mac OS9</h3> <ul> <li>Mozilla 1.2.1</li> <li>Netscape 7</li> <li>IE 5</li> <li>WaMCom <span>[thx T. Jung]</span></li> <li>iCab 3.0 Beta 340 <span>[thx T. Jung]</span></li> </ul> <h3>Mac OSX</h3> <ul> <li>Safari 1.0.3 / 1.3</li> <li>Firefox 1.0.4</li> <li>Netscape 7</li> <li>Opera 6</li> <li>Camino</li> <li>IE 5</li> </ul> </div> <h1>CSS vertical centering using float and clear - crossbrowser (?)</h1> <p> This box stays in the middle of the browser's viewport.<br> The content does not disappear when the viewport gets smaller than the box. </p> <p>It even works in IE5 Mac - the doctype triggers this browser toquirks-mode and the IEMac-only stylesheet kills the height for html,body. </p> <address>fricca[at]uk2.net | 07.08.05</address> </div> </body></html>

BoldUlysses
Dec 17th, 2008, 09:23 PM
There's always the hybrid negative-margin/line-height method:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

<title>Vertical Centering</title>

<style type="text/css">

* {
margin:0;
padding:0;
}

div {
position:absolute;
margin-top:-200px;
top:50%;
height:400px;
width:100%;
background:#ddd;
line-height:400px;
}

img {
vertical-align:middle;
}

</style>

</head>

<body>

<div>
<img src="image1.jpg" alt="" title="" />&nbsp;
<img src="image2.jpg" alt="" title="" />&nbsp;
<img src="image3.jpg" alt="" title="" />&nbsp;
</div>

</body>
</html>

Pretty simple. Just make sure your container height is at least as tall as the tallest image you want in there. Checks out in Safari, FF3 and IE7.

Apostropartheid
Dec 17th, 2008, 11:14 PM
This is probably what you're looking for, though, and it works with all image sizes (taking ideas from Excavator [that's the dead center method, by the way.])


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-gb" lang="en-gb" dir="ltr">
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8"/>
<title>Vertical centering</title>
<style type="text/css">
html,
body {
height: 100%;
background: #000;
}
#image-container {
position: absolute;
top: 50%;
left: 50%;
}
img {
margin-top: -50%;
margin-left: -50%;
border: 20px #fff solid;
}
</style>
</head>
<body>
<div id="image-container">
<img src=http://imgsrv.fresh1027.com/image/wnew2/UserFiles/Image/artists/KT%20Tunstall.jpg
height="400" width="400" alt="KT Tunstall sitting on a stone wall."/>
</div>
</body>
</html>

freedom_razor
Dec 18th, 2008, 01:57 AM
Thank you for all the answers. I did some testing, and the method proposed by itsallkizza seems to work best [with little modification, I added 100% heights to have it center images properly]:


body, html {width:100%; height:100%; margin:0; padding:0;}
.container_with_unknown_height {position:relative; width:100%; height:100%;
display:table; text-align:center; overflow:hidden; }
.element_to_center-wrapper {#position:absolute; top:50%;
display:table-cell; vertical-align:middle;}
.element_to_center-content {#position:relative; top:-50%; left:-50%;}

As for display:table etc., I don't think it is messy. Apparently, that's how W3C wants to do vertical alignment in CSS3. Do you mind explaining what does the '#' hack do? I removed all but 2 of those #, and it works fine [does # make Firefox ignore the declaration but IE still reads it?]

@Excavator/CyanLight: that works well, as long as the image has equal height and width.
@msuffern: more or less the same as just negative margins. Works fine, but since some values are in px, on resizing the window scrollbars appear. Minor detail.

itsallkizza
Dec 18th, 2008, 02:42 AM
does # make Firefox ignore the declaration but IE still reads it
Correct. IE7 is the only browser to read lines with "#" in front and IE6 is the only browser to read lines with "_" in front.

Come to think of it, I didn't test IE6 - I might need to duplicate the # lines and add _ in front to make it work there.