1226

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?

Jesse Nickles
  • 548
  • 1
  • 4
  • 17
Ish
  • 24,560
  • 11
  • 57
  • 75
  • 4
    You have an example in [Absolute center examples](http://css-tricks.com/snippets/css/absolute-center-vertical-horizontal-an-image/) that can be generalized in different situations. – Mihai8 Jan 09 '13 at 22:56
  • 2
    There is a better answer to this question at http://stackoverflow.com/questions/17976995/how-to-center-absolute-div-horizontally-using-css – Andrew Swift Dec 30 '14 at 14:38

35 Answers35

1934

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>
Mike
  • 640
  • 12
  • 35
Matthias Weiler
  • 19,614
  • 1
  • 12
  • 12
  • +1 I just used this for Chrome, Opera and Firefox and worked like a charm! great answer – BBog Jun 15 '12 at 08:04
  • 45
    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. – Joseph Ravenwolfe Aug 16 '12 at 01:33
  • @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. – Matthias Weiler Aug 21 '12 at 16:59
  • Ok, the answer works, but if you could take some time to explain why it works, that would make this a very good answer. – Brian Webster Jan 09 '13 at 22:53
  • 63
    the width of the div to be centered has to be set - won't work automagically with, say, a button with text on it. – Stefan Jan 27 '13 at 11:12
  • 2
    @Joshua This will only center horizontally, not vertically like the other answer. – ygoe Jan 31 '13 at 19:22
  • 3
    I prefer this solution as it doesn't increase the viewport size. – iceydee Mar 04 '13 at 11:39
  • 1
    Very good solution! Didn't know that yet, usually work with relative positioning, this time forced to do absolute. Works fine! – TheLD Apr 29 '13 at 17:53
  • 2
    I had to use `display: table;` with this too – Chris Edwards Jan 22 '14 at 14:44
  • 1
    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. – Andre Jan 26 '14 at 18:39
  • @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: http://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 Mar 19 '14 at 20:25
  • For me it fills the full width – alex88 Apr 01 '14 at 09:38
  • 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! – mgrenier Jun 06 '14 at 18:15
  • 15
    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. – Onur Yıldırım Jun 27 '14 at 16:12
  • @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. ) – Ideogram Jul 25 '14 at 07:26
  • I tried doing it this way but ie10 is not liking this ... :( had to go accepted one – Riskbreaker Nov 05 '14 at 17:43
  • if the width of div to be centered has to be set then we do not need position absolute – Carlos Mar 27 '15 at 12:43
  • 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 Jun 08 '15 at 11:37
  • Just found out that adding `text-align:center;` would do the trick if this div has children, as children will center aligned. – Janaka Dombawela Jun 08 '15 at 11:41
  • Worked for me. Just make sure the div you are centering has a set width. – Gene Kelly Sep 22 '15 at 15:31
  • 1
    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. – Craigo Oct 12 '15 at 04:59
  • agreed with other coders, this will work if you set the width – Brian Ogden Nov 05 '15 at 21:05
  • 1
    Try to use: margin: 0 auto; – raison Mar 08 '16 at 15:09
  • To horizontally & vertically center, you can also add a `top: 0; bottom: 0;` and use the shorthand `margin: auto`. – NaN Jul 27 '16 at 21:39
  • 1
    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. – Alexander Goncharov Aug 17 '16 at 02:11
  • This doesn't answer the original question, which states the solution must work for a container of unknown/variable width. – Arvind Thyagarajan Nov 14 '17 at 19:55
  • Nice solution for horizontal centering. Thank you – Gendrith Jan 24 '18 at 17:31
  • Amazing Nice solution. – Abdullah Feb 28 '18 at 12:28
  • 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. – Anthony McGrath Jul 20 '18 at 03:30
  • This doesn't answer the question, which explicitly states 'width is unknown'. – jdgregson Sep 18 '18 at 18:08
  • it works with 100% width for me. you just need to width the main wrapper. thats all. – Anthony Kal Sep 24 '18 at 22:44
  • This is the absolute best solution and much better than using transforms which introduce different problems. – Peter Moore Oct 23 '19 at 22:58
  • 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. – JD Gamboa Oct 29 '19 at 04:41
  • Also you don't need a specific pixel value for width - you can use `max-content` and `min-content` as well in most browsers. – Peter Moore Oct 29 '19 at 13:36
1448

<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>
Lionel Paulus
  • 311
  • 3
  • 5
bobince
  • 498,320
  • 101
  • 621
  • 807
  • 83
    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 – BoomShaka Oct 26 '11 at 10:28
  • 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 Sep 01 '12 at 05:45
  • 2
    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 Sep 01 '12 at 05:49
  • 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); }` – PUG Sep 01 '12 at 06:39
  • This works great so long as you aren't trying to put content in the div that's wider than the screen resolution. – sage88 Sep 12 '13 at 10:37
  • 3
    There is a minor issue I encountered using this technique. Because the outer div takes up 50% of the screen, some shifting occurs when the text is wider than the 50% screensize. I solved this by setting the outer div to "width: 100%" and removing the left property. For the inner div, I simply set my text-align to center. This solves the issue. – Nicky L. Jan 22 '14 at 16:14
  • This solution is definitely the best I've seen for my use case. Especially if your container is a element hovering over a google map. If you use width:100% on and center to accomplish the centering, then your "invisible" div might extend over the google map controls, preventing any clicks on that control. This solution completely bypasses that with a elegant, mathematical workaround. Love it. – Andre Jan 26 '14 at 18:35
  • don't you know why this does not work with vertical centering? When I use `top: -50%` inner div does not move. http://jsfiddle.net/skR4m/1/ – Dmitry Koroliov Feb 25 '14 at 00:31
  • 3
    Percentage height is relative to the containing block, in this case ``. But the `` element doesn't have a `height` specified so it takes the height of all the content in the document, which is nothing because the only content is absolutely-positioned (taken out of content flow). Adding `height: 100%` to the `` element makes a difference to this. – bobince Feb 25 '14 at 09:19
  • @BoomShaka alternatively, you can add the following: `html, body { overflow: hidden; }` – reformed Aug 29 '14 at 03:58
  • In case of centering inline elements, the inner element (which receives the `position: relative;` style) should also set to `display: block;` … to work with IE11 (and maybe others). – biziclop Oct 12 '15 at 12:41
  • It works on mobile as well as desktop. Simple, and straight to point. I usually don't just answer saying it work or thank you but this one I really had to say Thank you! – Nour Lababidi Nov 02 '17 at 03:31
  • @atilkan that solution still requires a declared height – Arvind Thyagarajan Nov 14 '17 at 19:56
  • Good in theory. The parent is relative to the body, and the child is relative to the parent. However, https://stackoverflow.com/a/23384995/493828 below achieves this with a single div container, which is elegant. – Arvind Thyagarajan Nov 14 '17 at 20:01
  • Why don't you just specify `left: 25%;` :| – Mehdi Karimi Nov 15 '18 at 04:23
  • Thanks a lot. Works perfectly for me! – Shailesh Jun 03 '20 at 05:33
  • Remember: this hack will work better when the element width is less than or equal to the half of parent width. Else you have to specify the min width of the element to make the element, say button's UI consistent. – Abhishek Jun 18 '20 at 11:56
  • This can break the viewport on smaller devices. – ihodonald Feb 27 '21 at 05:52
921

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%);

Community
  • 1
  • 1
ProblemsOfSumit
  • 14,940
  • 9
  • 43
  • 60
  • 34
    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. – aleemb Nov 21 '14 at 06:09
  • 58
    By far the best answer, this works if the box the div is contained in is smaller than the child. – Case Nov 23 '14 at 13:14
  • Once IE8 support isn't required, this should be the solution, but IE8 support hasn't been dropped by most sites just yet. – Justin Jan 13 '15 at 22:32
  • @Justin build via progressive enhancement! Build an IE8 solution and use this one for newer browsers defined by feature detection (modernizr). – ProblemsOfSumit Jan 23 '15 at 11:56
  • 2
    @ChadJohnson of course it does. Try it with the `webkit-` prefix as I suggested. – ProblemsOfSumit Feb 12 '15 at 09:59
  • 2
    Ah, I missed your note about -webkit. Awesome. – Chad Johnson Feb 12 '15 at 19:20
  • Is there a pretty solution for IE8 without JS? I found [this](http://www.useragentman.com/IETransformsTranslator/), workin with `filter`, but it requires `margin-left` and `margin-right` to set the transform-origin to the middle... – cheich Feb 26 '15 at 18:58
  • @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. – ProblemsOfSumit Feb 26 '15 at 19:01
  • I wanted floated content elements (of any width) inside `.inner` to sum to the calculated inner div width. http://jsfiddle.net/b1tav6xx/6/ However, when the screen width is small, the inputs wrap under the buttons. – poshest Mar 14 '15 at 00:03
  • @poshest that's a totally different problem. You need to use flexbox, tables or javascript. – ProblemsOfSumit Mar 14 '15 at 07:47
  • Thanks Sumit! :) You're right. http://jsfiddle.net/b1tav6xx/11/ in case anyone's interested. – poshest Mar 16 '15 at 13:31
  • 3
    `transform: translate` seems to make `position: fixed` unusable in children. The accepted answer works better in this case. – dmvianna Apr 01 '15 at 04:44
  • @dmvianna yes, all `transform` properties will change behaviour for `fixed` children. That is a much discussed behaviour but easy to work around. – ProblemsOfSumit Apr 01 '15 at 07:39
  • 1
    Is the accepted answer the recommended workaround, or can you point me in the right direction? – dmvianna Apr 01 '15 at 07:42
  • @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. – ProblemsOfSumit Apr 01 '15 at 07:55
  • try this if you have sass/compass `@include vendor(transform, translate(-50%, -50%));` – Adam Spence Apr 01 '15 at 11:16
  • 1
    This is exactly what I'm looking for. It handle the element which are not equal to the width of his parent ! Thanks dude ! – C0ZEN Apr 03 '16 at 13:31
  • Links (anchors) don't work for me if i do it this way, i can't click on them. – Jo Smo Sep 21 '16 at 12:05
  • I had to handle multiple absolutely positioned and different sized modals all being centered with different viewports, and this worked so beautifully! cheers! – jacoballenwood Dec 23 '16 at 01:01
  • liked the "only one element modified" approach – Alejandro Sanz Díaz Jan 12 '17 at 14:00
  • 1
    Great solution, the best of it is that you don't need to nest unnecessary DIVs! – Marcos Buarque Jul 28 '17 at 20:00
  • 1
    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. – RandomEngy Sep 20 '17 at 20:09
  • Thanks to nowadays CSS3, it's possible without width specified!! – Eric Nov 20 '17 at 11:00
  • Perhaps I am missing something here but why not use flexbox to centre the absolute positioned element in the container? https://stackoverflow.com/a/49743637/1010918 – lowtechsun Apr 10 '18 at 00:50
  • @lowtechsun you're not missing anything. Flexbox wasn't around (or widely supported) when I wrote this answer ;-) – ProblemsOfSumit Apr 11 '18 at 17:48
  • This will unintentionally set the maximum size of the inner element to 50% of the parent. – Anne van Rossum Apr 30 '19 at 15:14
  • @AnnevanRossum no it won't. As I wrote, this works even when the child is bigger than the parent. – ProblemsOfSumit May 02 '19 at 18:03
  • @ProblemsOfSumit Correction. It's limited to 50% of the viewport. – Anne van Rossum May 06 '19 at 10:25
  • @AnnevanRossum no it's not. There is no limit in anything. https://jsfiddle.net/x8pugz9a/ – ProblemsOfSumit May 09 '19 at 07:33
  • @AnnevanRossum your parent was missing `position: relative;` https://jsfiddle.net/8z9a3fbr/ If you are refering to the text wrapping behaviour, that is no limit. Here's the text in one line: https://jsfiddle.net/8z9a3fbr/1/ You can also give the child any witdth or min-width. As I said, there is no limiting factor here. – ProblemsOfSumit May 11 '19 at 10:48
  • 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. – Paul Razvan Berg May 12 '19 at 14:31
  • @ProblemsOfSumit with hardcoding "nowrap" you will have suddenly different wrapping behavior overflowing the parent/viewport, https://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. – Anne van Rossum May 15 '19 at 14:11
  • @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. – ProblemsOfSumit May 24 '19 at 19:03
  • Least hacky solution. IE10 let alone IE8 needs to stop being supported nowadays. – Amir Asyraf Apr 13 '20 at 12:12
  • If you're applying this CSS to a draggable element, in your mousemove handler you'll need to set `draggableElement.style.transform = 'initial';`. – Ruby Tunaley Oct 24 '20 at 03:41
49

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
pratikabu
  • 1,584
  • 13
  • 17
  • 27
    `"because the width is unknown"` ... this doesn't answer the question – Michel Ayres Oct 03 '13 at 13:20
  • 15
    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.. :) – pratikabu Oct 23 '13 at 13:08
  • 1
    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. – Sean Kendle Mar 19 '14 at 20:30
35

Absolute Centre

HTML:

<div class="parent">
  <div class="child">
    <!-- content -->
  </div>
</div>

CSS:

.parent {
  position: relative;
}

.child {
  position: absolute;
  
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;

  margin: auto;
}

Demo: http://jsbin.com/rexuk/2/

It was tested in Google Chrome, Firefox, and Internet Explorer 8.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Ijas Ameenudeen
  • 8,343
  • 3
  • 36
  • 50
  • This doesn't work, please check the following codepen http://codepen.io/anon/pen/YqWxjJ – Mark Mar 11 '16 at 03:20
  • 1
    Sorry I think this will work but you need to include a fixed height and width http://codepen.io/anon/pen/WwxEYQ – Mark Mar 11 '16 at 03:36
  • 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? – Robert Rocha May 16 '21 at 15:24
32

This works for vertical and horizontal:

#myContent{
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
}

And if you want make an element center of the parent, set the position of the parent relative:

#parentElement{
    position: relative
}
  • For vertical center align, set the height to your element. Thanks to Raul.

  • If you want make an element center of the parent, set the position of the parent to relative

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Mohsen Abdollahi
  • 851
  • 13
  • 14
31
<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.

Utkarsh Tyagi
  • 413
  • 2
  • 10
30

Responsive solution

Assuming the element in the div, is another div...

This solution works fine:

<div class="container">
  <div class="center"></div>
</div>

The container can be any size (must be position relative):

.container {
    position: relative; /* Important */
    width: 200px; /* Any width */
    height: 200px; /* Any height */
    background: red;
}

The element (div) can also be any size (must be smaller than the container):

.center {
    position: absolute; /* Important */
    top: 50%; /* Position Y halfway in */
    left: 50%; /* Position X halfway in */
    transform: translate(-50%,-50%); /* Move it halfway back(x,y) */
    width: 100px; /* Any width */
    height: 100px; /* Any height */
    background: blue;
}

The result will look like this. Run the code snippet:

.container {
    position: relative;
    width: 200px;
    height: 200px;
    background: red;
}

.center {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 100px;
    height: 100px;
    background: blue;
}
<div class="container">
    <div class="center"></div>
</div>

I found it very helpful.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
RealMJDev
  • 985
  • 9
  • 11
24

Searching for a solution, I got the previous answers and could make content centered with Matthias Weiler's answer, but using text-align:

#content{
  position: absolute;
  left: 0;
  right: 0;
  text-align: center;
}

It worked with Google Chrome and Firefox.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
cavila
  • 7,567
  • 4
  • 17
  • 19
24

If you need to center horizontally and vertically too:

left: 50%;
top: 50%;
transform: translate(-50%, -50%);
michal.jakubeczy
  • 4,457
  • 1
  • 30
  • 43
16

I understand this question already has a few answers, but I've never found a solution that would work in almost all classes that also makes sense and is elegant, so here's my take after tweaking a bunch:

.container {
    position: relative;
}

.container .cat-link {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate3d(-50%,-50%,0);
    z-index: 100;
    text-transform: uppercase; /* Forces CSS to treat this as text, not a texture, so no more blurry bugs */
    background-color: white;
}

.color-block {
  height: 250px;
  width: 100%;
  background-color: green;
}
<div class="container">
  <a class="cat-link" href="">Category</a>
  <div class="color-block"></div>
</div>

It is saying give me a top: 50% and a left: 50%, then transform (create space) on both the X/Y axis to the -50% value, in a sense "create a mirror space".

As such, this creates an equal space on all the four points of a div, which is always a box (has four sides).

This will:

  1. Work without having to know the parent's height / width.
  2. Work on responsive.
  3. Work on either X or Y axis. Or both, as in my example.
  4. I can't come up with a situation where it doesn't work.
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Daniel Moss
  • 357
  • 1
  • 3
  • 15
14

This works on any random unknown width of the absolute positioned element you want to have in the centre of your container element:

Demo

<div class="container">
  <div class="box">
    <img src="https://picsum.photos/200/300/?random" alt="">
  </div>
</div>

.container {
  position: relative;
  width: 100%;
}

.box {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
lowtechsun
  • 1,644
  • 3
  • 22
  • 49
14

Flexbox can be used to center an absolute positioned div.

display: flex;
align-items: center;
justify-content: center;

.relative {
  width: 275px;
  height: 200px;
  background: royalblue;
  color: white;
  margin: auto;
  position: relative;
}

.absolute-block {
  position: absolute;
  height: 36px;
  background: orange;
  padding: 0px 10px;
  bottom: -5%;
  border: 1px solid black;
}

.center-text {
  display: flex;
  justify-content: center;
  align-items: center;
  box-shadow: 1px 2px 10px 2px rgba(0, 0, 0, 0.3);
}
<div class="relative center-text">
  Relative Block
  <div class="absolute-block center-text">Absolute Block</div>
</div>
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Dhaval Jardosh
  • 6,258
  • 4
  • 22
  • 57
14

This is a mix of other answers, which worked for us:

.el {
   position: absolute;
   top: 50%;
   margin: auto;
   transform: translate(-50%, -50%);
}
Simon
  • 1,924
  • 23
  • 34
Crashalot
  • 31,452
  • 56
  • 235
  • 393
8

As far as I know, this is impossible to achieve for an unknown width.

You could - if that works in your scenario - absolutely position an invisible element with 100% width and height, and have the element centered in there using margin: auto and possibly vertical-align. Otherwise, you'll need JavaScript to do that.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Pekka
  • 418,526
  • 129
  • 929
  • 1,058
  • +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) – Steg Nov 21 '09 at 22:23
  • 1
    it is possible for an unknown width (and height) if IE8 isn't an issue. See my answer for details. – ProblemsOfSumit Sep 08 '14 at 16:35
7

I'd like to add on to bobince's answer:

<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>

Improved: /// This makes the horizontal scrollbar not appear with large elements in the centered div.

<body>
    <div style="width:100%; position: absolute; overflow:hidden;">
        <div style="position:fixed; 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>
    </div>
</body>
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Vial
  • 193
  • 1
  • 7
5

Here's a useful jQuery plugin to do this. I found it here. I don't think it's possible purely with CSS.

/**
 * @author: Suissa
 * @name: Absolute Center
 * @date: 2007-10-09
 */
jQuery.fn.center = function() {
    return this.each(function(){
            var el = $(this);
            var h = el.height();
            var w = el.width();
            var w_box = $(window).width();
            var h_box = $(window).height();
            var w_total = (w_box - w)/2; //400
            var h_total = (h_box - h)/2;
            var css = {"position": 'absolute', "left": w_total + "px", "top":
h_total + "px"};
            el.css(css)
    });
};
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Ben Shelock
  • 17,728
  • 26
  • 88
  • 122
5

Sass/Compass version of a previous responsive solution:

#content {
  position: absolute;
  left: 50%;
  top: 50%;
  @include vendor(transform, translate(-50%, -50%));
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Adam Spence
  • 2,412
  • 1
  • 18
  • 15
  • 4
    `transform: translate(-50%, -50%)` makes text and all other content blurry on OS X using webkit browsers. http://keithclark.co.uk/articles/gpu-text-rendering-in-webkit/ – Yasha Dec 15 '15 at 20:21
  • Just use the type of antialiasing that you like `-webkit-font-smoothing: antialiased;` I've gleaned that from the article you posted btw! – Adam Spence Dec 22 '15 at 07:22
5

This worked for me:

<div class="container><p>My text</p></div>

.container{
    position: absolute;
    left: 0;
    right: 0;
    margin-left: auto;
    margin-right: auto;
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Alan
  • 67
  • 1
  • 8
4

My preferred centering method:

position: absolute;
margin: auto;
width: x%
  • absolute block element positioning
  • margin auto
  • same left/right, top/bottom

A JSFiddle is here.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
vp_arth
  • 12,796
  • 4
  • 33
  • 59
3
#container
{
  position: relative;
  width: 100%;
  float: left
}

#container .item
{
  width: 50%;
  position: absolute;
  margin: auto;
  left: 0;
  right: 0;
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
3

HTML:

<div id='parent'>
  <div id='child'></div>
</div>

CSS:

#parent {
  display: table;
}
#child {
  display: table-cell;
  vertical-align: middle;
}

I know I already provided an answer, and my previous answer, along with others given, work just fine. But I have used this in the past and it works better on certain browsers and in certain situations. So I thought I'd give this answer as well. I did not "Edit" my previous answer and add it because I feel this is an entirely separate answer and the two I have provided are not related.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Dustin Poissant
  • 2,710
  • 1
  • 17
  • 22
3

The accepted solution of this question didn't work for my case...

I'm doing a caption for some images and I solved it using this:

top: 0;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;

display: flex;
align-items: center;

figure {
    position: relative;
    width: 325px;
    display: block
}


figcaption{
    position: absolute;
    background: #FFF;
    width: 120px;
    padding: 20px;

    -webkit-box-shadow: 0 0 30px grey;
    box-shadow: 0 0 30px grey;
    border-radius: 3px;
    display: block;

    top: 0;
    left: 0;
    right: 0;
    margin-left: auto;
    margin-right: auto;

    display: flex;
    align-items: center;
}
<figure>
    <img  src="https://picsum.photos/325/600">
    <figcaption>
        But as much
    </figcaption>
</figure>
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Marcogomesr
  • 2,238
  • 3
  • 25
  • 37
2

HTML

<div id='parent'>
  <div id='centered-child'></div>
</div>

CSS

#parent {
  position: relative;
}
#centered-child {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto auto;
}

http://jsfiddle.net/f51rptfy/

Dustin Poissant
  • 2,710
  • 1
  • 17
  • 22
1

This is a trick I figured out for getting a DIV to float exactly in the center of a page. It is really ugly of course, but it works in all browsers.

Dots and Dashes

<div style="border: 5 dashed red;position:fixed;top:0;bottom:0;left:0;right:0;padding:5">
    <table style="position:fixed;" width="100%" height="100%">
        <tr>
            <td style="width:50%"></td>
            <td style="text-align:center">
                <div style="width:200;border: 5 dashed green;padding:10">
                    Perfectly Centered Content
                </div>
            </td>
            <td style="width:50%"></td>
        </tr>
    </table>
</div>

Cleaner

Wow, those five years just flew by, didn't they?

<div style="position:fixed;top:0px;bottom:0px;left:0px;right:0px;padding:5px">
    <table style="position:fixed" width="100%" height="100%">
        <tr>
            <td style="width:50%"></td>
            <td style="text-align:center">
                <div style="padding:10px">
                    <img src="Happy.PM.png">
                    <h2>Stays in the Middle</h2>
                </div>
            </td>
            <td style="width:50%"></td>
        </tr>
    </table>
</div>
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Mr. B
  • 2,374
  • 1
  • 18
  • 30
1

HTML:

<div class="wrapper">
    <div class="inner">
        content
    </div>
</div>

CSS:

.wrapper {
    position: relative;

    width: 200px;
    height: 200px;

    background: #ddd;
}

.inner {
    position: absolute;
    top: 0; bottom: 0;
    left: 0; right: 0;
    margin: auto;

    width: 100px;
    height: 100px;

    background: #ccc;
}

This and more examples here.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
1

This solution works if the element has width and height

.wrapper {
  width: 300px;
  height: 200px;
  background-color: tomato;
  position: relative;
}

.content {
  width: 100px;
  height: 100px;
  background-color: deepskyblue;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  margin: auto;
}
<div class="wrapper">
  <div class="content"></div>
</div>
Mo.
  • 21,971
  • 31
  • 138
  • 201
1
.center {
  position: absolute
  left: 50%;
  bottom: 5px;
}

.center:before {
    content: '';
    display: inline-block;
    margin-left: -50%;
}
AndreyP
  • 1,962
  • 1
  • 23
  • 14
0

#content { margin:0 auto; display:table; float:none;}
<body>
  <div>
    <div id="content">
      I'm the content
    </div>
  </div>
</body>
amit bende
  • 238
  • 3
  • 4
0

A simple approach that worked for me to horizontally center a block of unknown width:

<div id="wrapper">
  <div id="block"></div>
</div>

#wrapper {
    position: absolute;
    width: 100%;
    text-align: center;
}

#block {
    display: inline-block;
}

A text-align property may be added to the #block ruleset to align its content independently of the alignment of the block.

This worked on recent versions of Firefox, Chrome, Internet Explorer, Edge and Safari.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
0

You can also create the middleware div#centered box centered with absolute, left and right properties and without width property and then set the main content div as its child with display:inline-block box and center it with text-align:center set for its middleware parent box

#container {
  position: relative;
  width: 300px;
  height: 300px;
  border: solid 1px blue;
  color: #DDDDDD;
}

#centered {
  position: absolute;
  text-align: center;
  margin: auto;
  top: 20px;
  left: 0;
  right: 0;
  border: dotted 1px red;
  padding: 10px 0px;
}

#centered>div {
  border: solid 1px red;
  display: inline-block;
  color: black;
}
<div id="container">
  hello world hello world
  hello world hello world
  hello world hello world
  hello world hello world
  hello world hello world
  hello world hello world
  hello world hello world
  hello world hello world

  <div id="centered">
    <div>
      hello world <br/>
      I don't know my width<br/>
      but I'm still absolute!
    </div>
  </div>
</div>
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Paweł
  • 3,261
  • 2
  • 14
  • 31
0

None of the solutions worked for me since I didn't want to change the styling of the container/wrapper element. This code worked for me:

position: absolute;
left: 50%;
margin-left: -50px;
top: 50%;
margin-top: -50px;
Nick.K
  • 210
  • 4
  • 11
-1

You can place the image in a div and add a div id and have the CSS for that div have a text-align:center:

HTML:

<div id="intro_img">

    <img src="???" alt="???">

</div>

CSS:

#intro_img {
    text-align: center;
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
-4

I have used a similar solution:

#styleName {
    position: absolute;
    margin-left: -"X"px;
}

Where "X" is half of the width of a div I want to display. It works fine for me in all browsers.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Bartosz
  • 4,192
  • 9
  • 40
  • 66
-4

Try not to use the dark side of the CSS. Avoid using negative values for margins. I know that sometimes you are forced to do awful things like a margin-left: -450px, but probably you could do something like right: 450px. It's just my way to work.

brasofilo
  • 23,940
  • 15
  • 86
  • 168
  • 4
    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. – ProblemsOfSumit Nov 19 '14 at 11:25