107

Say you have the following CSS applied to a div tag

.divtagABS {
    position: absolute;
    margin-left: auto;  
    margin-right: auto;
}

the margin-left and margin-right does not take effect

but if you have relative, it works fine i.e.

.divtagREL {
    position: relative;
    margin-left: auto;  
    margin-right: auto;
}

Why is that? I just want to center an element.

Can someone explain why setting margins to auto in absolute position does not work?

bad_coder
  • 11,289
  • 20
  • 44
  • 72
user1118019
  • 3,819
  • 8
  • 40
  • 46

9 Answers9

205

EDIT : this answer used to claim that it isn't possible to center an absolutely positioned element with margin: auto;, but this simply isn't true. Because this is the most up-voted and accepted answer, I guessed I'd just change it to be correct.

When you apply the following CSS to an element

position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;

And then give the element a fixed width and height, such as 200px or 40%, the element will center itself.

Here's a Fiddle that demonstrates the effect.

Gust van de Wal
  • 5,211
  • 1
  • 24
  • 48
Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
  • 3
    url: http://www.vision.to/articles/margins-and-absolute-positioning.php is not working, please replace – chrmod May 21 '13 at 10:49
  • courtesy of wayback machine: http://web.archive.org/web/20130117135705/http://www.vision.to/articles/margins-and-absolute-positioning.php – eflat Nov 06 '13 at 23:11
  • 2
    "An element with position absolute cannot be centered..." Actually, this is _not_ true: The key is to set all `top/bottom/left/right` properties to `0` and declare `width` and `height`, then `margin: auto` will automatically center the absolutely positioned element. See: [Absolute Centering technique](http://codepen.io/shshaw/details/gEiDt); it's also on [Smashing Magazine](https://www.smashingmagazine.com/2013/08/absolute-horizontal-vertical-centering-css/). – DynamicDispatch Apr 19 '16 at 00:20
  • 2
    And in order to make a width pseudo-dynamic, use `width: 100%;` and (i.e.) `max-width: 500px;`. – WoodrowShigeru Jan 24 '17 at 12:28
  • 1
    Yep you need to add `width: 100%` to make it work with edge and IE9-11. – Huelfe Feb 21 '17 at 13:21
  • 2
    I think you only need to set left, right and a (max)width for it to center, No need for bottom or top for horizontal alignment. Although for best practice you should set at least one of those so browsers cant misinterpret – Empi May 02 '18 at 08:36
  • 1
    I managed to center my element thanks to this answer BUT setting `top` AND `bottom` poses a problem for me. It makes the element not the right height (content overflows). Better to set only one of them. Actually just `left` and `right` are needed for the horizontal centering with `margin: X auto`. – foxesque May 13 '21 at 07:54
  • And you can use `inset: 0` instead of setting all 4 values (top - right - bottom - left) to 0. Not available for IE, unfortunately. – Oğuz K Dec 11 '22 at 21:07
71

I've used this trick to center an absolutely positioned element. Though, you have to know the element's width.

.divtagABS {
    width: 100px;
    position: absolute;
    left: 50%;
    margin-left: -50px;
  }

Basically, you use left: 50%, then back it out half of it's width with a negative margin.

bad_coder
  • 11,289
  • 20
  • 44
  • 72
chipcullen
  • 6,840
  • 1
  • 21
  • 17
  • Yep, this is what you should use if the element has a fixed width. – Bantros Apr 07 '12 at 17:03
  • 1
    You can use margin-left:-25%; to center it instead of hard-coding a number. – Aaron Butacov Oct 09 '13 at 19:31
  • 5
    @AaronHarun - sadly, no that won't work the way you expect. I think the 25% will be based on the parent's width. I set up a code pen to test it out: http://codepen.io/chippper/pen/xwKIl - you can toggle the last line of CSS to see what I mean. – chipcullen Oct 09 '13 at 19:41
  • This triggered me into [a similar trick](https://github.com/cauerego/cregox-scripts/commit/f75fcbb9f1fa9beaad351095f5814af0ce811591) but using `margin-left: -50%;`. Oddly enough, it fixed a very weird alignment issue for me! – cregox May 12 '15 at 19:28
  • @chipcullen @AaronHarun You can use `transform: translateX(-25%)` which uses it's own width. http://stackoverflow.com/a/35723851/2054731 (As you noted, @chipcullen, `width: -25%` will use the parent element's width, typically not what you want.) – ArneHugo Mar 01 '16 at 13:54
  • @ArneHugo - I think that is what the previous comment was alluding to. At the time I wrote this answer, transform wasn't well supported - thankfully that has changed! :) – chipcullen Mar 04 '16 at 16:39
  • This works fine with max-width too. So it's flexible enough. – kJamesy Apr 27 '16 at 11:10
39

if the absolute element has a width,you can use the code below

.divtagABS{
    width:300px;
    positon:absolute;
    left:0;
    right:0;
    margin:0 auto;
}
GilbertSun
  • 600
  • 5
  • 9
  • 1
    Brilliant ! But why isn't it working unless left and right are set ? – geoffroy Jun 03 '14 at 13:43
  • 1
    Very nice solution. Works also with width:100% under Bootstrap ;) – Andrei Hardau Dec 13 '14 at 13:56
  • If you want to make it centre vertically and horizontally then just expand this to top: 0; bottom: 0; combine this with a CSS 3 transition for width and height and you have a pretty nice effect – Daniel Worthington-Bodart Dec 16 '14 at 10:24
  • 1
    I think this is the horizontal case of the [Absolute Centering technique](http://codepen.io/shshaw/details/gEiDt) (also: [Smashing Magazine](https://www.smashingmagazine.com/2013/08/absolute-horizontal-vertical-centering-css/)), which uses `margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0;` (with declared `width` and `height`) for both horizontal and vertical centering. The linked articles explain how this method works and compares it to other centering methods. – DynamicDispatch Apr 19 '16 at 01:01
  • @geoffroy because `left`, `right`, `top`, and `bottom` are setted to `auto` by default and this, together with an absolute layout, actually prevent `margin: auto` to be noticeable – asdru Jan 22 '20 at 17:08
23

Working JSFiddle below. When using position absolute, margin: 0 auto will not work, but you can do like this (will also scale):

left: 50%;
transform: translateX(-50%);

Update: Working JSFiddle

bad_coder
  • 11,289
  • 20
  • 44
  • 72
Baked Inhalf
  • 3,375
  • 1
  • 31
  • 45
  • Best work with Absolute position div's but have some issue in IE10 when positioning div has width more than parent width... :( – iTux Aug 25 '16 at 12:34
1

I already had this same issue and I've got the solution writing a container (.divtagABS-container, in your case) absolutely positioned and then relatively positioning the content inside it (.divtagABS, in your case).

Done! The margin-left and margin-right AUTO for your .divtagABS will now work.

1

All answers were just a suggested solutions or workarounds. But still don't get answer to the question: why margin:auto works with position:relative but does not with position:absolute.

Following explanation was helpful for me:

"Margins make little sense on absolutely positioned elements since such elements are removed from the normal flow, thus they cannot push away any other elements on the page. Using margins like this can only affect the placement of the element to which the margin is applied, not any other element." http://www.justskins.com/forums/css-margins-and-absolute-82168.html

Alex Vovchuk
  • 2,828
  • 4
  • 19
  • 40
1

This issue can be confusing until you realize some nuances of different positionings.

Margins work similarly for relative and absolute elements, but margins are relative to a 'bounding box.' You have to consider what is the bounding box of the element, to apply margins against.

  • For a relative positioned element, the bounding box is its parent element.
  • For an absolute positioned element, the bounding box is itself.
  • For a relative positioned element, left/right/top/bottom rules position the element itself.
  • For an absolute positioned element, left/right/top/bottom rules position the element's bounding box.

This is why to center a relative positioned element, you only have to set margins and it works.

To center an absolute positioned element, you have to set the margins, and also set the bounding box (left/right/top/bottom).

michaeljsalo
  • 523
  • 4
  • 16
-1

If the element is position absolutely, then it isn't relative, or in reference to any object - including the page itself. So margin: auto; can't decide where the middle is.

Its waiting to be told explicitly, using left and top where to position itself.

You can still center it programatically, using javascript or somesuch.

Codecraft
  • 8,291
  • 4
  • 28
  • 45
-5

When you are defining styles for division which is positioned absolutely, they specifying margins are useless. Because they are no longer inside the regular DOM tree.

You can use float to do the trick.

.divtagABS {
    float: left;
    margin-left: auto;  
    margin-right:auto;
 }
Starx
  • 77,474
  • 47
  • 185
  • 261