37

I am making a website and I'm trying to vertically center:

 position: absolute; width:1200px; height:600px; top: 50%; left: 50%; margin-left: -600px; 

and my HTML is a single div

5
  • 1
    Doing left: 50%; and then margin-left: -600px; doesn't make much sense, since you're just canceling the one out with the other. Commented Mar 19, 2012 at 5:55
  • swenflea: I edited my question with information on the parent element's position effect. Commented Mar 19, 2012 at 6:19
  • Actually, can you be more specific with the Question? Do you want your DIV to be at the Center of the Page. I mean exact center....? Commented Mar 19, 2012 at 6:30
  • @JaredFarrish It keeps the div exactly in the middel, however, I prefer to use width:calc(50% - 600px) Commented Sep 20, 2016 at 8:38
  • 3
    @Swenflea, have you managed to fix this in the last seven years? If so, were any of the provided answers any good? If not, could you post your solution please? Commented Nov 28, 2019 at 16:48

7 Answers 7

59

Using Position - Static height needed

i{ -webkit-transform: translate(-50%,-50%); transform: translate(-50%,-50%); position: absolute; top: 50%; left: 50%; }
<i>center</i>

Edit: Using Flex (2021-10-19)

i { display: flex; align-items: center; /* vertical centering if flex-direction: row */ justify-content: center; /* horizontal centering if flex-direction: row */ /* extra styles */ background-color: limeGreen; min-height: 160px; }
<i>center</i>

enter code here 
Sign up to request clarification or add additional context in comments.

4 Comments

This is not going to work if your parent has no static height, unless you have height: 100%; on both your html and body. You can check my answer bellow if you need more info. Also, you don't really need position absolute on some situations. This can work wit position: relative; for those worried in opting for this solution that need to it to keep positioning relationship with other elements. Although, a position value other than position: static; is required to for the top and left to work. (or even bottom, right, orz-index)
@JomarSevillejo That's another technique. I just gave the answer by telling his current code. There can be flexbox/table-cell/line-height/ or anything else but why we're trying to let this guy rewrite his code? :)
@w3debugger I am not making the person change his answer. Please don't take it as offense. I simply warned everyone about how this method you showed, requires a static height if you use this with pposition: relative; on parent. prntscr.com/h3pbpf Most of the time we use position:relative; on parent to control absolute elements. and FYI the question is "WHY TOP:50%; IS NOT WORKING" so what's wrong with answering "YOU NEED A HEIGHT IN YOUR PARENT"?
@JomarSevillejo I would never like your comment if I feel that offensive :) but sorry if that looks offensive as I'm not good in English.
34

To answer your question why top: 50% is not working, when you use property top on an element, the parent of that element needs to have a static height set in place. This should be in px or a unit other than percent. If you really need to use percent in your parent as well, then you can move on to the next parent (which is the parent of that parent) and have that one a fixed static height.

To vertically centering anything. I prefer to use this method

The use of CSS transform since you don't have to know what the width of height your element has.

position: relative; top: 50%; left: 50%; -webkit-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); -o-transform: translate(-50%, -50%); transform: translate(-50%, -50%); 

Don't forget to add browser/vendor prefixes.

You can refer here for vendor prefixes.


If you don't know the height of your parent. You have two options:

  1. Using JavaScript take the natural height of the parent element and then set the height property of that parent element to the value you just took. You can use this method when the height of the parent element is caused by another child element that is sibling to the element you are centering.

$('.parent').height( $(this).height() );
.parent { /* Unkown height */ } .child { /* Create columns */ width: 50%; float: left; } .child-1 { position: relative; top: 50%; text-align: center; -webkit-transform: translateY(-50%); -moz-transform: translateY(-50%); -ms-transform: translateY(-50%); -o-transform: translateY(-50%); transform: translateY(-50%); }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!-- Example Start --> <div class="parent"> <div class="child child-1"> Lorem ipsum </div> <div class="child child-2"> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </div> </div>

Tip: If you are taking responsive into concern, just set height again in JavaScript on browser resize. You can get the new natural height by setting height to auto in JavaScript and do the process again.

  1. You can scratch the ideas above and use centering with display: table instead. CSS-Tricks has a very good example here.

2 Comments

"when you us property top on an element, the parent of that element needs to have a static height set" -- This was the answer to the question. Solved my issue in safari.
RE: "the parent of that element needs to have a static height set." Note 1: HTML and body can both be considered parents if there is no parent div. Note 2: A % will work too. For example amp.css contains the line: html,body{height: auto !important;} This can cause ads to be decapitated when you roll your own remote.html/frame.max.amp.html unless you add this css therein: html,body{height:100% !important;} That will allow the top:50% to work.
15

The CSS property top works exactly as left. It pushes the div from that direction. When you write top:50%, the div will be pushed down 50% from the top. You want it to be centered vertically, so you need to counter this by pulling it back up. This can be done using margin-top: -300px just like you used margin-left: -600px to pull it left.

position: absolute; width: 1200px; height: 600px; top: 50%; margin-top: -300px; left: 50%; margin-left: -600px; 

1 Comment

This works for fixed height elements. For variable heights, use this.
4

top:50%; works fine, but wont "center" the item, it will place it's top edge 50% of the page's height from the top. Similarly to how you have margin-left:-600px; you should also add margin-top:-300px;

2 Comments

Sorry that doesn't work... it just sticks it -300px from the top of the page... Do I need to have any styling on outer divs or inner divs?
Are you experiencing this in a specific browser? So long as it's position:absolute, the styles on the containing elements shouldn't matter unless the selector you're using is more specific and is overriding the style you listed above.
3

You can use

calc(%50 - (items_height/2)); 

to center.

2 Comments

I would have added more context around that statement, but this is what I was about to suggest.
Note, it should be 50% rather than %50. And don't forget to add "px" after the second value. The format should be something like calc(50% - 5px);. For example this won't work: calc(50% - (10/2)px);
1

css "top" property gets correctly calculated based on the container element's height - effectively rendering the target element below the midline. What this means is the element needs to be pushed half-way up as explained in the linked question.

Unfortunately such a seemingly straightforward task cannot be accomplished by adjusting top margin etc. without using absolute pixel-based values (+1 for Kristian Antonsen's answer) - one would imagine setting margin-top to "-50%" would mean just that, but according to css spec, margin values even on the vertical axis are calculated as a percentage always relative to the width of the containing block

Comments

0

I believe this may somewhat mimic the answer Kristian gave, but here's my two cents, which includes using percentages and also demonstrates one inside another:

#parent { position: absolute; top: 50%; left: 50%; width: 120px; height: 60px; margin: -60px 0 0 -30px; background: blue; } #center { position: absolute; width: 50%; height: 50%; top: 50%; left: 50%; margin: -12.5% 0 0 -25%; background: green; } 

http://jsfiddle.net/userdude/MYD27/

EDIT

Looking at it further, I think you might run into issues if you're trying to do this with an element not container within a positioned element. For instance:

Full View | Code View

I don't think works the way you intended. When I add position: relative (or alternatively position: absolute), it does work I think as you intended:

Full View | Code View

1 Comment

+1 for the explanation about the position: relative (or absolute) in the parent DIV. That is what made it work for me.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.