How can I center an absolutely positioned element in a div?

1,565,229

Solution 1

<body>
  <div style="position: absolute; left: 50%;">
    <div style="position: relative; left: -50%; border: dotted red 1px;">
      I am some centered shrink-to-fit content! <br />
      tum te tum
    </div>
  </div>
</body>

Solution 2

This works for me:

#content {
  position: absolute; 
  left: 0; 
  right: 0; 
  margin-left: auto; 
  margin-right: auto; 
  width: 100px; /* Need a specific value to work */
}
<body>
  <div>
    <div id="content">
      I'm the content
    </div>
  </div>
</body>

Solution 3

Responsive Solution

Here is a good solution for responsive design or unknown dimensions in general if you don't need to support IE8 and lower.

.centered-axis-x {
    position: absolute;
    left: 50%;
    transform: translate(-50%, 0);
}

.outer {
    position: relative; /* or absolute */
    
    /* unnecessary styling properties */
    margin: 5%;
    width: 80%;
    height: 500px;
    border: 1px solid red;
}

.inner {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    
    /* unnecessary styling properties */
    max-width: 50%;
    text-align: center;
    border: 1px solid blue;
}
<div class="outer">
    <div class="inner">I'm always centered<br/>doesn't matter how much text, height or width i have.<br/>The dimensions or my parent are irrelevant as well</div>
</div>

Here is a JS Fiddle

The clue is, that left: 50% is relative to the parent while the translate transform is relative to the elements width/height.

This way you have a perfectly centered element, with a flexible width on both child and parent. Bonus: this works even if the child is bigger than the parent.

You can also center it vertically with this (and again, width and height of parent and child can be totally flexible (and/or unknown)):

.centered-axis-xy {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%);
}

Keep in mind that you might need transform vendor prefixed as well. For example -webkit-transform: translate(-50%,-50%);

Solution 4

<div style='position:absolute; left:50%; top:50%; transform: translate(-50%, -50%)'>
  This text is centered.
</div>

This will center all the objects inside div with position type static or relative.

Solution 5

I just wanted to add if someone wants to do it with a single div tag then here is the way out:

Taking width as 900px.

#styleName {
    position: absolute;
    left: 50%;
    width: 900px;
    margin-left: -450px;
}

In this case one should know the width beforehand.

Share:
1,565,229
Ish
Author by

Ish

Ping this droid at /^ish1301\@gmail\.com$/i

Updated on July 08, 2022

Comments

  • Ish
    Ish almost 2 years

    I need to place a div (with position:absolute;) element in the center of my window. But I am having problems doing so, because the width is unknown.

    I tried this. But it needs to be adjusted as the width is responsive.

    .center {
      left: 50%;
      bottom: 5px;
    }
    

    How can I do it?

  • Steg
    Steg over 14 years
    +1 for the "margin: auto" thing. I've tried this before to horizontally centre a div using the line "margin: 0 auto" - the "0" applying to the vertical margins and the "auto" the horizontal. I think this is what StackOverflow uses for the very top level div to get the 2 thick white borders down the sides of the page. However, the W3Schools page on CSS margin states for the auto value that "The result of this is dependant of the browser" - I've not personally tried it across many different browsers, so I can't really comment on this point (but it obviously does the trick in some of them)
  • BoomShaka
    BoomShaka over 12 years
    Awesome. Worked for me! One problem I had: The image I was centering was quite big, this caused the outer div to go beyond the right edge of the page and cause horizontal scrolling. I swapped out the "left" css property for "right", and so far it works better since going over the left edge of the screen doesnt cause scrolling
  • BBog
    BBog almost 12 years
    +1 I just used this for Chrome, Opera and Firefox and worked like a charm! great answer
  • Joseph Ravenwolfe
    Joseph Ravenwolfe almost 12 years
    I just want to get across that negative margins are perfectly valid CSS and should not be viewed as a "dirty hack". Negative margins are mentioned in the W3C box model specification. Some individuals seem to arbitrarily decide it is a hack because they a) are ignorant to them, or b) are using them to fix their bad CSS.
  • Matthias Weiler
    Matthias Weiler almost 12 years
    @JosephJaber: Thanks. I didn't do a lot of CSS and I'm not qualified to rate other solutions. It did just "seemed like a dirty hack" from my layman point-of-view. I'll edit my answer.
  • PUG
    PUG over 11 years
    what if user has scrolled the page down, overylay appears on the top, do you think it will be a good idea to use jquery to fix scroll issue
  • PUG
    PUG over 11 years
    one solution for scroll issue can be position: fixed but what if height is unknown of overlay, scroll bars for overlay will have to be implemented
  • PUG
    PUG over 11 years
    Solution for scrolling can be this, did not test it enough though, wht do you guys think of this solution? var scrolled =$(window).scrollTop(); if(scrolled>0) { var offset = $('#containerOverlay').offset(); $('#containerOverlay').css('top',($(window).height() * 0.05) + scrolled); }
  • m4tm4t
    m4tm4t over 11 years
    this is the better way, and especially with repsonsive design.
  • Brian Webster
    Brian Webster over 11 years
    Ok, the answer works, but if you could take some time to explain why it works, that would make this a very good answer.
  • Stefan
    Stefan over 11 years
    the width of the div to be centered has to be set - won't work automagically with, say, a button with text on it.
  • ygoe
    ygoe over 11 years
    @Joshua This will only center horizontally, not vertically like the other answer.
  • iceydee
    iceydee about 11 years
    I prefer this solution as it doesn't increase the viewport size.
  • TheLD
    TheLD about 11 years
    Very good solution! Didn't know that yet, usually work with relative positioning, this time forced to do absolute. Works fine!
  • Tobias
    Tobias almost 11 years
    I think you don't need the "text-align: center"
  • Michel Ayres
    Michel Ayres over 10 years
    "because the width is unknown" ... this doesn't answer the question
  • pratikabu
    pratikabu over 10 years
    hi @Michel actually when you google search for something related to centering the absolute div, this link comes as the first link. That's why I added this solution, in case someone like me is in search for the above solution.. :)
  • Code Whisperer
    Code Whisperer over 10 years
    Would be trivial if jQuery was used in any case
  • Chris Edwards
    Chris Edwards over 10 years
    I had to use display: table; with this too
  • Andre
    Andre over 10 years
    This is not a good solution for all cases. See my comment in the accepted answer. This is normally a very good method, and have used it a lot. But it specifically stopped working when I was trying to hover elements over a google map, and the "invisible" full width container prevented click-throughs to the map controls underneath. So, in summary, this works and is the preferred method in some cases to prevent extra markup, but be aware of limitations and other solutions.
  • Ivan Durst
    Ivan Durst over 10 years
    You need a "left:50%" in there too to make this work.
  • Sean Kendle
    Sean Kendle about 10 years
    @Andre - Keep an eye on the pointer-events CSS value. It's not official yet, but it may be in CSS 4. Using jQuery (or JS) you can capture the click, send it on down to the "lower" element. pointer-events: css-tricks.com/almanac/properties/p/pointer-events jQuery "hacky" way: $(".parentElement").bind("click", function(){ $(".parentElement").find("a").trigger("click"); }); Might be considered hacky, but it works for me in a production environment. Might have to trigger a google.maps.events("click") in your case or some other combination of events.
  • Sean Kendle
    Sean Kendle about 10 years
    Not very useful for responsive design, but it worked for me until I started doing responsive designs. This is a valid answer for centering absolutely positioned known width elements.
  • alex88
    alex88 about 10 years
    For me it fills the full width
  • ProblemsOfSumit
    ProblemsOfSumit about 10 years
    this is NOT the better way. It's always better to use CSS whenever possible. Centering a DIV is possible with CSS in every axis and also for responsive pages. There is no need for JavaScript!
  • mgrenier
    mgrenier almost 10 years
    thank you so much, struggle with this for 2 hours wondering why margin: 0 auto; wouldn't center my div. I was missing the left: 0 and right: 0!
  • Onur Yıldırım
    Onur Yıldırım almost 10 years
    For cross-browser support: width should be set to a specific value for this to work. auto and 100% will not center the element. display: block; is a must. position: absolute; is NOT a must. All values will work. Parent element's position should be set to something other than static. Setting left and right to 0 is unnecessary. margin-left: auto; margin-right: auto; will do the work.
  • Ideogram
    Ideogram almost 10 years
    @OnurYıldırım THANKS for your elaborate comment. I'm curious about the 'why' behind every aspect of your answer. Would you mind elaborating on it in a separate answer? It seems to be quite a complex issue and your reasoning could be very valuable for everybody who finds this page. ( BTW, The answer we comment on right now, does work for me, in Chrome and IE. )
  • ProblemsOfSumit
    ProblemsOfSumit over 9 years
    it is possible for an unknown width (and height) if IE8 isn't an issue. See my answer for details.
  • Riskbreaker
    Riskbreaker over 9 years
    I tried doing it this way but ie10 is not liking this ... :( had to go accepted one
  • ProblemsOfSumit
    ProblemsOfSumit over 9 years
    negative values are no "dark side" of CSS. They're just as valid as positive values. And your suggestion of swapping margin-left with right doesn't make any sense if the goal is to center an element.
  • aleemb
    aleemb over 9 years
    With IE7 support no longer necessary, this should be the de facto solution. This solution is better than the left:0/right:0 technique since that makes the elements full width while this retains the width and works on elements of unknown widths.
  • Case
    Case over 9 years
    By far the best answer, this works if the box the div is contained in is smaller than the child.
  • Raul
    Raul over 9 years
    I think you need to add height for vertical to work.
  • Justin
    Justin over 9 years
    Once IE8 support isn't required, this should be the solution, but IE8 support hasn't been dropped by most sites just yet.
  • ProblemsOfSumit
    ProblemsOfSumit over 9 years
    @Justin build via progressive enhancement! Build an IE8 solution and use this one for newer browsers defined by feature detection (modernizr).
  • ProblemsOfSumit
    ProblemsOfSumit over 9 years
    @ChadJohnson of course it does. Try it with the webkit- prefix as I suggested.
  • Chad Johnson
    Chad Johnson over 9 years
    Ah, I missed your note about -webkit. Awesome.
  • cheich
    cheich about 9 years
    Is there a pretty solution for IE8 without JS? I found this, workin with filter, but it requires margin-left and margin-right to set the transform-origin to the middle...
  • ProblemsOfSumit
    ProblemsOfSumit about 9 years
    @Chris yes, work with feature detection (modernizr for example). Then, you can use the margin: 0 auto solution for IE8 and the transform solution for modern browsers. That of course works only for centering the x-axis.
  • poshest
    poshest about 9 years
    I wanted floated content elements (of any width) inside .inner to sum to the calculated inner div width. jsfiddle.net/b1tav6xx/6 However, when the screen width is small, the inputs wrap under the buttons.
  • ProblemsOfSumit
    ProblemsOfSumit about 9 years
    @poshest that's a totally different problem. You need to use flexbox, tables or javascript.
  • poshest
    poshest about 9 years
    Thanks Sumit! :) You're right. jsfiddle.net/b1tav6xx/11 in case anyone's interested.
  • Jitender
    Jitender about 9 years
    if the width of div to be centered has to be set then we do not need position absolute
  • dmvianna
    dmvianna about 9 years
    transform: translate seems to make position: fixed unusable in children. The accepted answer works better in this case.
  • ProblemsOfSumit
    ProblemsOfSumit about 9 years
    @dmvianna yes, all transform properties will change behaviour for fixed children. That is a much discussed behaviour but easy to work around.
  • dmvianna
    dmvianna about 9 years
    Is the accepted answer the recommended workaround, or can you point me in the right direction?
  • ProblemsOfSumit
    ProblemsOfSumit about 9 years
    @dmvianna well you could use another way to center your elements BUT I'd suggest you re-think the HTML structure so you don't have a nested fixed element.
  • Adam Spence
    Adam Spence about 9 years
    try this if you have sass/compass @include vendor(transform, translate(-50%, -50%));
  • ProblemsOfSumit
    ProblemsOfSumit about 9 years
    @yckart and in this case the tool is CSS.
  • Janaka Dombawela
    Janaka Dombawela almost 9 years
    This does not work in all cases, specially with responsive frameworks. Unless the parent container's width is defined explicitly, this will likely to fail.
  • Janaka Dombawela
    Janaka Dombawela almost 9 years
    Just found out that adding text-align:center; would do the trick if this div has children, as children will center aligned.
  • Gene Kelly
    Gene Kelly over 8 years
    Worked for me. Just make sure the div you are centering has a set width.
  • Craigo
    Craigo over 8 years
    This is fine if the width is known. However, as the questions states, the width is not known. Therefore, the accepted solution is the only one that worked for me.
  • Brian Ogden
    Brian Ogden over 8 years
    agreed with other coders, this will work if you set the width
  • Günter Zöchbauer
    Günter Zöchbauer over 8 years
    Looks like this positions in the center of the page, not the center of another element.
  • Mohsen Abdollahi
    Mohsen Abdollahi over 8 years
    @GünterZöchbauer yes, if you want make element center of parent, set position of parent relative.
  • Yasha
    Yasha over 8 years
    transform: translate(-50%, -50%) makes text and all other content blurry on OS X using webkit browsers. keithclark.co.uk/articles/gpu-text-rendering-in-webkit
  • Adam Spence
    Adam Spence over 8 years
    Just use the type of antialiasing that you like -webkit-font-smoothing: antialiased; I've gleaned that from the article you posted btw!
  • ejntaylor
    ejntaylor about 8 years
    Try to use: margin: 0 auto;
  • Mark
    Mark about 8 years
    This doesn't work, please check the following codepen codepen.io/anon/pen/YqWxjJ
  • Mark
    Mark about 8 years
    Sorry I think this will work but you need to include a fixed height and width codepen.io/anon/pen/WwxEYQ
  • C0ZEN
    C0ZEN about 8 years
    This is exactly what I'm looking for. It handle the element which are not equal to the width of his parent ! Thanks dude !
  • NaN
    NaN almost 8 years
    To horizontally & vertically center, you can also add a top: 0; bottom: 0; and use the shorthand margin: auto.
  • Alexander Goncharov
    Alexander Goncharov almost 8 years
    It isn't work in Google Chrome with table element and width:auto . Today better the varriant with left: 50%; transform: translate(-50%, 0); I think.
  • Volomike
    Volomike over 7 years
    This fixed my problem here. Thanks!
  • Jo Smo
    Jo Smo over 7 years
    Links (anchors) don't work for me if i do it this way, i can't click on them.
  • aloisdg
    aloisdg over 7 years
    It's @Matthias Weiler answer 5 years later.
  • jacoballenwood
    jacoballenwood over 7 years
    I had to handle multiple absolutely positioned and different sized modals all being centered with different viewports, and this worked so beautifully! cheers!
  • Alejandro Sanz Díaz
    Alejandro Sanz Díaz over 7 years
    liked the "only one element modified" approach
  • Marcos Buarque
    Marcos Buarque almost 7 years
    Great solution, the best of it is that you don't need to nest unnecessary DIVs!
  • RandomEngy
    RandomEngy over 6 years
    I would change this to use right: 50%; transform: translate(50%, 0);. If the pre-transform div goes over the right edge of the page, it can cause a horizontal scrollbar to appear, but it does not make a scrollbar appear if it goes over the left edge of the page.
  • Arvind Thyagarajan
    Arvind Thyagarajan over 6 years
    This doesn't answer the original question, which states the solution must work for a container of unknown/variable width.
  • Eric
    Eric over 6 years
    Thanks to nowadays CSS3, it's possible without width specified!!
  • Daniel Moss
    Daniel Moss over 6 years
    Please do let me know if you find a situation where this doesn't work so I could edit the question with your input.
  • James Tan
    James Tan over 6 years
    transform / translate will causes safari to render text blurred on certain scale
  • Gendrith
    Gendrith over 6 years
    Nice solution for horizontal centering. Thank you
  • lowtechsun
    lowtechsun about 6 years
    Perhaps I am missing something here but why not use flexbox to centre the absolute positioned element in the container? stackoverflow.com/a/49743637/1010918
  • ProblemsOfSumit
    ProblemsOfSumit about 6 years
    @lowtechsun you're not missing anything. Flexbox wasn't around (or widely supported) when I wrote this answer ;-)
  • Anthony McGrath
    Anthony McGrath almost 6 years
    In this example, you can remove the margin and width styles and use text-align center instead. The width should automatically be the width of the relative parent element.
  • Mark Baijens
    Mark Baijens almost 6 years
    @DanielMoss any reason to not use translate(-50%,-50%);?
  • jdgregson
    jdgregson over 5 years
    This doesn't answer the question, which explicitly states 'width is unknown'.
  • Anthony Kal
    Anthony Kal over 5 years
    it works with 100% width for me. you just need to width the main wrapper. thats all.
  • Nat
    Nat over 5 years
    I needed the "text-align: center", and this worked where the solution suggested by @ProblemsOfSumit didn't work as it made my text wrap.
  • Anne van Rossum
    Anne van Rossum about 5 years
    This will unintentionally set the maximum size of the inner element to 50% of the parent.
  • ProblemsOfSumit
    ProblemsOfSumit about 5 years
    @AnnevanRossum no it won't. As I wrote, this works even when the child is bigger than the parent.
  • Anne van Rossum
    Anne van Rossum about 5 years
    @ProblemsOfSumit Correction. It's limited to 50% of the viewport.
  • ProblemsOfSumit
    ProblemsOfSumit about 5 years
    @AnnevanRossum no it's not. There is no limit in anything. jsfiddle.net/x8pugz9a
  • ProblemsOfSumit
    ProblemsOfSumit about 5 years
    @AnnevanRossum your parent was missing position: relative; jsfiddle.net/8z9a3fbr If you are refering to the text wrapping behaviour, that is no limit. Here's the text in one line: jsfiddle.net/8z9a3fbr/1 You can also give the child any witdth or min-width. As I said, there is no limiting factor here.
  • Paul Razvan Berg
    Paul Razvan Berg about 5 years
    This works great with normal tags but, when applying css animations, it breaks. The tag is shifted to the right and downwards by half of its width and height, respectively.
  • Anne van Rossum
    Anne van Rossum about 5 years
    @ProblemsOfSumit with hardcoding "nowrap" you will have suddenly different wrapping behavior overflowing the parent/viewport, jsfiddle.net/b4esa580 In other words you have artifacts due to the shifting to the right half of the viewport and shifting back with half of the component's calculated size.
  • ProblemsOfSumit
    ProblemsOfSumit almost 5 years
    @AnnevanRossum it was an example to show you that there are no limitations by using this technique. Wrapping behaviour depends on your contents flow and the available space, as usual.
  • Peter Moore
    Peter Moore over 4 years
    This is the absolute best solution and much better than using transforms which introduce different problems.
  • JD Gamboa
    JD Gamboa over 4 years
    I liked this one better than the accepted solution. I imagine both answers are applicable in different contexts and eventually none is better than the other.
  • Peter Moore
    Peter Moore over 4 years
    Also you don't need a specific pixel value for width - you can use max-content and min-content as well in most browsers.
  • Webwoman
    Webwoman about 4 years
    on my screen -Firefox 68.x, it just doesn't align, the absolute block appears at the bottom of the relative block
  • Dhaval Jardosh
    Dhaval Jardosh about 4 years
    Can you try this display: -webkit-flex;?
  • Amir Asyraf
    Amir Asyraf about 4 years
    Least hacky solution. IE10 let alone IE8 needs to stop being supported nowadays.
  • Utkarsh Tyagi
    Utkarsh Tyagi almost 4 years
    According to me this is the best way of doing this..also the most commonly used
  • Peter Mortensen
    Peter Mortensen almost 4 years
    Re "059%": Do you mean "50%"? If so, please respond by editing your answer, not here in comments.
  • Ruby Tunaley
    Ruby Tunaley over 3 years
    If you're applying this CSS to a draggable element, in your mousemove handler you'll need to set draggableElement.style.transform = 'initial';.
  • BergListe
    BergListe over 3 years
    I have a slightly different case and I'm very glad about your hint to transform: translate()!
  • APu
    APu about 3 years
    It'll not work for absolute positioned items
  • Robert
    Robert about 3 years
    I don't understand why setting left and right to 0 means in this context when it's used with margin auto. Care to explain?
  • Loenix
    Loenix over 2 years
    We should limit the usage of transform because this is conflicting with animations.
  • alexventuraio
    alexventuraio over 2 years
    The last chunk of code was the solution for me, thank you!
  • PACE
    PACE over 2 years
    thanks, it works
  • Maseed
    Maseed about 2 years
    Was a great answer.
  • Alex78191
    Alex78191 almost 2 years
    The best answer! It works better, than transform: translate.