6

my question is more or less self-explanatory, I am trying to find a standard dynamic way to centralize an element in the y-axis, much like the:

margin: auto;

For the x-axis. Any ideas?

I am talking about the following piece of code, empty page, align one image in the center.

<div id="main" style="display: block;"> 
    <img style="margin: auto; display: block;" 
    src="http://www.example.com/img.jpg" />
</div>

Any help will be appreciated! :)

kxk
  • 576
  • 2
  • 11
  • 30

8 Answers8

8

Just give up and use tables on this one, with vertical-align: middle. You can get away with just a single-row, single-cell table without feeling too guilty (I sleep like a baby about it). It's not the most semantic thing in the world, but what would you rather maintain, a tiny one celled table, or figuring out the exact height and doing absolute positioning with negative margins?

Daghall
  • 589
  • 6
  • 10
Russell Leggett
  • 8,795
  • 3
  • 31
  • 45
  • How would you deal with the height of the table? By default the table cells would try to minimize the overall height I think. However, setting the table height to 100% would probably do the trick. – Marc Audet Mar 24 '11 at 16:56
  • This approach would be very useful if, in addition to the image, you had a caption and your wanted the image-caption block vertically centered. – Marc Audet Mar 24 '11 at 17:13
  • Yeah this is probably the best idea up to now. It is frustrating that there is no simple dynamic way of doing this. Does anyone know why such a discrimination against the y-axis? – kxk Mar 25 '11 at 10:46
1

If you know the height of the element that you're trying to center, you can do this:

img {
  display: block;
  height: 500px;
  position: absolute;
  top: 50%;
  margin-top: -250px; /* 50% of your actual height */
}
scurker
  • 4,733
  • 1
  • 26
  • 25
1

I know only one way for that:

#mydiv {
   position: fixed;
   top: 50%;
   left: 50%;
   width: 100px;
   height: 100px;
   margin-top: -50px;
   margin-left: -50px;
}

This is for x and y axis - but width/height and margins have to be changed for every element. I hate it :-)

Additionally you get problems if the element is larger than the browser-window.

MacGucky
  • 2,494
  • 17
  • 17
  • Still I have to know the size of the image in order for this to work. I am looking for something more dynamic. – kxk Mar 25 '11 at 10:42
  • Yes, thats the problem for all solutions other than the table-based approach. You could get around that problem by using javascript (get width/height via javascript and set the appropriate css). – MacGucky Mar 25 '11 at 11:11
1

The best known method is to use absolute positioning. You set the top amount to 50% and then set a margin top of minus half of the element.

#main {
    position: relative;
}
#main img {
    position: absolute;
    top: 50%;
    margin-top: -(half your image height)px;
}
Alex
  • 7,320
  • 1
  • 18
  • 31
1

Here is a variation using vertical-align

http://jsfiddle.net/audetwebdesign/r46aS/

It has a down side in that you need to specify a value for line-height that will also define the height of the containing element that acts like the viewport (outlined in blue).

Note: You may be able to get around the window height issue by setting a height to the body or html element (100%) but you would need to try it out (see 3rd reference).

However, the good thing is that you don't have to do some math based on the dimensions of the image.

Here are some references related to vertical alignment:

http://css-tricks.com/what-is-vertical-align

http://blog.themeforest.net/tutorials/vertical-centering-with-css

http://www.jakpsatweb.cz/css/css-vertical-center-solution.html

and sometimes I have to remember the basics so I reread:

http://www.w3.org/TR/CSS21/visudet.html

This may not solve OP's problem, but may be useful in other contexts.

Marc Audet
  • 46,011
  • 11
  • 63
  • 83
  • 1
    One drawback of this approach is that you can't use it for multiple lines of text because of the line-height hack. – Marc Audet Mar 24 '11 at 17:14
0

Using #menu img { vertical-align: middle; } in my style sheet works great for the latest versions of FireFox, Opera, Safari and Chrome, but not in IE9. I have to manually add style="vertical-align: middle" to every line of img code. For example:

<li><a href="../us-hosts.php">
    <img src="../images/us-button.png" width="30" height="30"
         alt="US Hosts" style="vertical-align: middle;"/>&nbsp; US Hosts</a>
</li>
slfan
  • 8,950
  • 115
  • 65
  • 78
0

Try this css:

margin-top:auto;
margin-bottom:auto;
display:block;
Kevin Yao
  • 59
  • 4
0

The answers are kind of outdated so here's a more modern solution:

display: flex;
align-items: center;
Maksiks
  • 94
  • 11