How can I center an absolutely positioned element in a div?
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>
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.
Comments
-
Ish almost 2 years
I need to place a
div
(withposition: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?
-
Mihai8 over 11 yearsYou have an example in Absolute center examples that can be generalized in different situations.
-
Andrew Swift over 9 yearsThere is a better answer to this question at stackoverflow.com/questions/17976995/…
-
Andy over 2 yearsI think some of us oldies need to look at flex
-
-
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 over 12 yearsAwesome. 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 almost 12 years+1 I just used this for Chrome, Opera and Firefox and worked like a charm! great answer
-
Joseph Ravenwolfe almost 12 yearsI 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 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 over 11 yearswhat 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 over 11 yearsone 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 over 11 yearsSolution 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 over 11 yearsthis is the better way, and especially with repsonsive design.
-
Brian Webster over 11 yearsOk, the answer works, but if you could take some time to explain why it works, that would make this a very good answer.
-
Stefan over 11 yearsthe width of the div to be centered has to be set - won't work automagically with, say, a button with text on it.
-
ygoe over 11 years@Joshua This will only center horizontally, not vertically like the other answer.
-
iceydee about 11 yearsI prefer this solution as it doesn't increase the viewport size.
-
TheLD about 11 yearsVery good solution! Didn't know that yet, usually work with relative positioning, this time forced to do absolute. Works fine!
-
Tobias almost 11 yearsI think you don't need the "text-align: center"
-
Michel Ayres over 10 years
"because the width is unknown"
... this doesn't answer the question -
pratikabu over 10 yearshi @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 over 10 yearsWould be trivial if jQuery was used in any case
-
Chris Edwards over 10 yearsI had to use
display: table;
with this too -
Andre over 10 yearsThis 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 over 10 yearsYou need a "left:50%" in there too to make this work.
-
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 about 10 yearsNot 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 about 10 yearsFor me it fills the full width
-
ProblemsOfSumit about 10 yearsthis 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 almost 10 yearsthank 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 almost 10 yearsFor cross-browser support:
width
should be set to a specific value for this to work.auto
and100%
will not center the element.display: block;
is a must.position: absolute;
is NOT a must. All values will work. Parent element'sposition
should be set to something other thanstatic
. Settingleft
andright
to0
is unnecessary.margin-left: auto; margin-right: auto;
will do the work. -
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 over 9 yearsit is possible for an unknown width (and height) if IE8 isn't an issue. See my answer for details.
-
Riskbreaker over 9 yearsI tried doing it this way but ie10 is not liking this ... :( had to go accepted one
-
ProblemsOfSumit over 9 yearsnegative values are no "dark side" of CSS. They're just as valid as positive values. And your suggestion of swapping
margin-left
withright
doesn't make any sense if the goal is to center an element. -
aleemb over 9 yearsWith 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 over 9 yearsBy far the best answer, this works if the box the div is contained in is smaller than the child.
-
Raul over 9 yearsI think you need to add height for vertical to work.
-
Justin over 9 yearsOnce IE8 support isn't required, this should be the solution, but IE8 support hasn't been dropped by most sites just yet.
-
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 over 9 years@ChadJohnson of course it does. Try it with the
webkit-
prefix as I suggested. -
Chad Johnson over 9 yearsAh, I missed your note about -webkit. Awesome.
-
cheich about 9 yearsIs there a pretty solution for IE8 without JS? I found this, workin with
filter
, but it requiresmargin-left
andmargin-right
to set the transform-origin to the middle... -
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 thetransform
solution for modern browsers. That of course works only for centering the x-axis. -
poshest about 9 yearsI 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 about 9 years@poshest that's a totally different problem. You need to use flexbox, tables or javascript.
-
poshest about 9 yearsThanks Sumit! :) You're right. jsfiddle.net/b1tav6xx/11 in case anyone's interested.
-
Jitender about 9 yearsif the width of div to be centered has to be set then we do not need position absolute
-
dmvianna about 9 years
transform: translate
seems to makeposition: fixed
unusable in children. The accepted answer works better in this case. -
ProblemsOfSumit about 9 years@dmvianna yes, all
transform
properties will change behaviour forfixed
children. That is a much discussed behaviour but easy to work around. -
dmvianna about 9 yearsIs the accepted answer the recommended workaround, or can you point me in the right direction?
-
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 about 9 yearstry this if you have sass/compass
@include vendor(transform, translate(-50%, -50%));
-
ProblemsOfSumit about 9 years@yckart and in this case the tool is CSS.
-
Janaka Dombawela almost 9 yearsThis 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 almost 9 yearsJust found out that adding
text-align:center;
would do the trick if this div has children, as children will center aligned. -
Gene Kelly over 8 yearsWorked for me. Just make sure the div you are centering has a set width.
-
Craigo over 8 yearsThis 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 over 8 yearsagreed with other coders, this will work if you set the width
-
Günter Zöchbauer over 8 yearsLooks like this positions in the center of the page, not the center of another element.
-
Mohsen Abdollahi over 8 years@GünterZöchbauer yes, if you want make element center of parent, set position of parent relative.
-
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 over 8 yearsJust use the type of antialiasing that you like
-webkit-font-smoothing: antialiased;
I've gleaned that from the article you posted btw! -
ejntaylor about 8 yearsTry to use: margin: 0 auto;
-
Mark about 8 yearsThis doesn't work, please check the following codepen codepen.io/anon/pen/YqWxjJ
-
Mark about 8 yearsSorry I think this will work but you need to include a fixed height and width codepen.io/anon/pen/WwxEYQ
-
C0ZEN about 8 yearsThis is exactly what I'm looking for. It handle the element which are not equal to the width of his parent ! Thanks dude !
-
NaN almost 8 yearsTo horizontally & vertically center, you can also add a
top: 0; bottom: 0;
and use the shorthandmargin: auto
. -
Alexander Goncharov almost 8 yearsIt 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 over 7 yearsThis fixed my problem here. Thanks!
-
Jo Smo over 7 yearsLinks (anchors) don't work for me if i do it this way, i can't click on them.
-
aloisdg over 7 yearsIt's @Matthias Weiler answer 5 years later.
-
jacoballenwood over 7 yearsI 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 over 7 yearsliked the "only one element modified" approach
-
Marcos Buarque almost 7 yearsGreat solution, the best of it is that you don't need to nest unnecessary DIVs!
-
RandomEngy over 6 yearsI 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 over 6 yearsThis doesn't answer the original question, which states the solution must work for a container of unknown/variable width.
-
Eric over 6 yearsThanks to nowadays CSS3, it's possible without width specified!!
-
Daniel Moss over 6 yearsPlease 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 over 6 yearstransform / translate will causes safari to render text blurred on certain scale
-
Gendrith over 6 yearsNice solution for horizontal centering. Thank you
-
lowtechsun about 6 yearsPerhaps 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 about 6 years@lowtechsun you're not missing anything. Flexbox wasn't around (or widely supported) when I wrote this answer ;-)
-
Anthony McGrath almost 6 yearsIn 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 almost 6 years@DanielMoss any reason to not use
translate(-50%,-50%);
? -
jdgregson over 5 yearsThis doesn't answer the question, which explicitly states 'width is unknown'.
-
Anthony Kal over 5 yearsit works with 100% width for me. you just need to width the main wrapper. thats all.
-
Nat over 5 yearsI 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 about 5 yearsThis will unintentionally set the maximum size of the inner element to 50% of the parent.
-
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 about 5 years@ProblemsOfSumit Correction. It's limited to 50% of the viewport.
-
ProblemsOfSumit about 5 years@AnnevanRossum no it's not. There is no limit in anything. jsfiddle.net/x8pugz9a
-
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 about 5 yearsThis 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 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 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 over 4 yearsThis is the absolute best solution and much better than using transforms which introduce different problems.
-
JD Gamboa over 4 yearsI 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 over 4 yearsAlso you don't need a specific pixel value for width - you can use
max-content
andmin-content
as well in most browsers. -
Webwoman about 4 yearson my screen -Firefox 68.x, it just doesn't align, the absolute block appears at the bottom of the relative block
-
Dhaval Jardosh about 4 yearsCan you try this
display: -webkit-flex;
? -
Amir Asyraf about 4 yearsLeast hacky solution. IE10 let alone IE8 needs to stop being supported nowadays.
-
Utkarsh Tyagi almost 4 yearsAccording to me this is the best way of doing this..also the most commonly used
-
Peter Mortensen almost 4 years
-
Ruby Tunaley over 3 yearsIf you're applying this CSS to a draggable element, in your mousemove handler you'll need to set
draggableElement.style.transform = 'initial';
. -
BergListe over 3 yearsI have a slightly different case and I'm very glad about your hint to
transform: translate()
! -
APu about 3 yearsIt'll not work for
absolute
positioned items -
Robert about 3 yearsI 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 over 2 yearsWe should limit the usage of transform because this is conflicting with animations.
-
alexventuraio over 2 yearsThe last chunk of code was the solution for me, thank you!
-
PACE over 2 yearsthanks, it works
-
Maseed about 2 yearsWas a great answer.
-
Alex78191 almost 2 yearsThe best answer! It works better, than
transform: translate
.