243
#menu {
    position: fixed;
    width: 800px;
    background: rgb(255, 255, 255); /* The Fallback */
    background: rgba(255, 255, 255, 0.8);
    margin-top: 30px;
}

I know this question is a million times out there, however I can't find a solution to my case. I've got a div, which should be fixed on the screen, even if the page is scrolled it should always stay CENTERED in the middle of the screen!

The div should have 500px width, should be 30px away from the top (margin-top), should be horizontally centered in the middle of the page for all browser sizes and should not move when scrolling the rest of the page.

Is that possible?

Barry Michael Doyle
  • 9,333
  • 30
  • 83
  • 143
matt
  • 42,713
  • 103
  • 264
  • 397

9 Answers9

783

The answers here are outdated. Now you can easily use a CSS3 transform without hardcoding a margin. This works on all elements, including elements with no width or dynamic width.

Horizontal center:

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

Vertical center:

top: 50%;
transform: translateY(-50%);

Both horizontal and vertical:

left: 50%;
top: 50%;
transform: translate(-50%, -50%);

Compatibility is not an issue: http://caniuse.com/#feat=transforms2d

Preston Badeer
  • 2,658
  • 1
  • 20
  • 21
Maciej Krawczyk
  • 14,825
  • 5
  • 55
  • 67
  • I implemented your answer, with a draggable element, and a problem came up. I posted the question here: http://stackoverflow.com/questions/34073485/center-a-fixed-draggable-div – Jessica Dec 03 '15 at 19:30
  • 4
    This makes a blur effects in box shadow in content elements. – rab Jul 03 '16 at 11:13
  • 5
    Yes, Chrome incorrectly blurs content that is transformed. Text is also blurred. But this is the only solution to have a fixed element centered without hardcoding and using wrapper elements. If you don't care about pointer events of the background, you can achieve same effect with a full screen wrapper and flexbox, or @salomvary's solution below. – Maciej Krawczyk Jul 03 '16 at 13:19
  • This seems to set a max width on the centered element that wasn't there before. I'm using this to center a fixed bootstrap panel, and it's forcing the width down smaller than before. Is there a way to overcome this? The content is dynamic (action buttons for my form), so I can't hardcode the width. – Sam Jones Apr 20 '18 at 15:36
  • 1
    This work fine but the element I'm trying to center already has an animation, this animate the `translateX(-50%)`... – dguay Nov 14 '18 at 15:57
  • 1
    This precludes you from having a `fixed` position child. – Emperor Eto Oct 21 '19 at 21:16
166
left: 50%;
margin-left: -400px; /* Half of the width */
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 3
    @Bahodir: Are you sure? It looks right to me on resize. I think this `-400` is due to the width of the div being set to `800`. – Merlyn Morgan-Graham Dec 11 '11 at 11:19
  • works when width defined but if i use padding to adjust the text given by user then??? – Waqas Tahir Jun 19 '15 at 14:36
  • 1
    @PrestonBadeer — Like the one that the question is asking about? – Quentin Feb 17 '16 at 15:24
  • 1
    @Quentin, this holds no advantage over using a transform and has limited usage. A transform would work better and is a better practice. In a responsive age it's bad practice to teach people to hard code these values. I agree that in 2010 this was the correct answer, it just isn't anymore. – Preston Badeer Feb 17 '16 at 15:29
  • 9
    Completely agree - this is **NOT** a solution! *Never* hard code something in this manner. -1 – Nate I May 04 '16 at 23:49
  • 1
    @NateI — This answer is from over half a decade ago, browser support for better alternatives was terrible. – Quentin May 05 '16 at 06:53
  • 1
    @Quentin Regardless, new visitors should see that this is **not** the way to do things now. PS - you responded to this in February defending it - that's one motivating factor to me downvoting and informing users that this is an absolutely horrible way to accomplish this task. – Nate I May 05 '16 at 16:14
  • 4
    I've voted this down NOT because it was a bad answer for its day - it was a good answer, but because it no longer is, and the next-highest answer needs all the help it can get to be seen as the best answer NOW. Quentin: I think it would be a good idea to edit in a comment to that effect in the answer itself - I'd then reverse my down vote. – Nick Rice May 30 '16 at 13:29
  • What if you don't know the dimensions at design time? – Emperor Eto Oct 21 '19 at 21:17
  • @PeterMoore — Then you have a different problem to the one being asked about here. You might want to look at some of the other questions here though. – Quentin Oct 21 '19 at 22:16
61

If using inline-blocks is an option I would recommend this approach:

.container { 
    /* fixed position a zero-height full width container */
    position: fixed;
    top: 0; /* or whatever position is desired */
    left: 0;
    right: 0;
    height: 0;
    /* center all inline content */
    text-align: center;
}

.container > div {
    /* make the block inline */
    display: inline-block;
    /* reset container's center alignment */
    text-align: left;
} 

I wrote a short post on this here: http://salomvary.github.com/position-fixed-horizontally-centered.html

salomvary
  • 1,072
  • 9
  • 13
39

Edit September 2016: Although it's nice to still get an occasional up-vote for this, because the world has moved on, I'd now go with the answer that uses transform (and which has a ton of upvotes). I wouldn't do it this way any more.

Another way not to have to calculate a margin or need a sub-container:

#menu {
    position: fixed;   /* Take it out of the flow of the document */
    left: 0;           /* Left edge at left for now */
    right: 0;          /* Right edge at right for now, so full width */ 
    top: 30px;         /* Move it down from top of window */
    width: 500px;      /* Give it the desired width */ 
    margin: auto;      /* Center it */
    max-width: 100%;   /* Make it fit window if under 500px */ 
    z-index: 10000;    /* Whatever needed to force to front (1 might do) */
}
Nick Rice
  • 1,163
  • 1
  • 13
  • 21
  • @Joey What does the bottom:0 do? ie why is it needed? (It's some time since I looked at this!) – Nick Rice Dec 11 '14 at 11:29
  • `bottom:0` would ensure the menu is always vertically centered, but I see now that's not what the OP asked for. :) – Jordan H Dec 11 '14 at 16:48
  • I tried to use this in a different context byt figured out it doesn't center in FF if the elements height is higher than the window(viewport) height – Philipp Werminghausen May 11 '15 at 17:29
  • Because the world has moved on, I'd now go with the answer that uses transform. (I made this comment before, referencing the name that answerer used - but they changed that name so my comment no longer made sense and I deleted it - just search on this page for transform instead.) – Nick Rice May 30 '16 at 13:20
10

It is possible to horisontally center the div this way:

html:

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

css:

.container {
    left: 0;
    right: 0;
    bottom: 0; /* or top: 0, or any needed value */
    position: fixed;
    z-index: 1000; /* or even higher to prevent guarantee overlapping */
}

.inner {
    max-width: 600px; /* just for example */
    margin: 0 auto;
}

Using this way you will have always your inner block centered, in addition it can be easily turned to true responsive (in the example it will be just fluid on smaller screens), therefore no limitation in as in the question example and in the chosen answer.

Denis V
  • 3,290
  • 1
  • 28
  • 40
7

Here's another two-div solution. Tried to keep it concise and not hardcoded. First, the expectable html:

<div id="outer">
  <div id="inner">
    content
  </div>
</div>

The principle behind the following css is to position some side of "outer", then use the fact that it assumes the size of "inner" to relatively shift the latter.

#outer {
  position: fixed;
  left: 50%;          // % of window
}
#inner {
  position: relative;
  left: -50%;         // % of outer (which auto-matches inner width)
}

This approach is similar to Quentin's, but inner can be of variable size.

Anonymous
  • 71
  • 1
  • 1
5

... or you can wrap you menu div in another:

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


#wrapper{
         width:800px;
         background: rgba(255, 255, 255, 0.8);
         margin:30px auto;
         border:1px solid red;
    }

    #menu{
        position:fixed;
        border:1px solid green;
        width:300px;
        height:30px;
    }
Meduza
  • 442
  • 2
  • 7
0
div {
   left: calc((100vw - 100%) / 2);
}
  • 1
    Your answer could be improved by adding more information on what the code does and how it helps the OP. – Tyler2P Jun 12 '22 at 13:39
-2

Here's a flexbox solution when using a full screen wrapper div. justify-content centers it's child div horizontally and align-items centers it vertically.

<div class="full-screen-wrapper">
    <div class="center"> //... content</div>
</div>

.full-screen-wrapper { 
  position: fixed;
  display: flex;
  justify-content: center;
  width: 100vw;
  height: 100vh;
  top: 0;
  align-items: center;
}

.center {
  // your styles
}
Vien Tang
  • 553
  • 1
  • 5
  • 11
  • The problem with this solution is that it makes anything in the whitespace (left and right of the div) unclickable – Burawi Apr 14 '21 at 10:47