Center fixed div with dynamic width (CSS)
Asked Answered
L

5

94

I have a div that will have this CSS:

#some_kind_of_popup
{
    position: fixed;
    top: 100px;
    min-height: 300px;
    width: 90%;
    max-width: 900px;
}

Now, how can i make this div centered? I can use margin-left: -450px; left: 50%; but this will only work when the screen is > 900 pixels. After that (when the window is < 900 pixels), it will no longer be centered.

I can of course do this with some kind of js, but is there a "more correct" of doing this with CSS?

Lubeck answered 12/6, 2013 at 15:28 Comment(8)
@Liam - I disagree, I think this question is an outright on its own. Those questions don't answer this one in regards to having a div of no fixed width centred.Belomancy
What Joshua said, that is for centering a div in another.Lubeck
@Liam - Further to that, you can't use a margin: 0 auto on a position: fixed div. Did you even read the question?Belomancy
^nope. i've tried that as well. :pLubeck
the point is @JoshuaM, everyone wants to do this. It's been discussed on meta before (meta.stackexchange.com/questions/116673/…). There are hundreds of answers for this question already on SO and yet another does not contribute to the siteKatheykathi
@Katheykathi this question is a bit different from the ones you linked here. The technique used is similar but not the same because it is applied on a fixed positioned element.Alkanet
@JoshuaM Your assertion isn't 100% correct. See my answer.Alkanet
@Alkanet I stand (mostly) corrected!Belomancy
A
238

You can center a fixed or absolute positioned element setting right and left to 0, and then margin-left & margin-right to auto as if you were centering a static positioned element.

#example {
    position: fixed;
    /* center the element */
    right: 0;
    left: 0;
    margin-right: auto;
    margin-left: auto;
    /* give it dimensions */
    min-height: 10em;
    width: 90%;
}

See this example working on this fiddle.

Alkanet answered 12/6, 2013 at 15:55 Comment(15)
Just to mention... It's not that unexpected, but it fails in IE7. It's positioned 0px from left here. It does how ever work perfect in IE 8.Lubeck
This doesn't work when the width of the element is greater than the width of the screen.. would be nice to have it work in that situation.Cedilla
@Cedilla you could apply an equally negative margin both on right and left of at least a value >= witdth / 2, as seen on jsfiddle.net/PvfFy/168, but is non an elegant approach IMHO. I have tested it on chrome for fun, I don't know if it will work on the restAlkanet
Outside the scope of the question, this depends on setting the element's width, so it's not great if you have dynamic content whose width is varying or unknown. Leaving centering aside, I'd normally do that with display: inline-block and no set width. Does anyone have a no-js solution for that case?Flump
@Flump Are you asking for a solution to make a fixed or absolute positioned element "adapt" its width to its content width?Alkanet
Just because it works in one contrived example doesn't mean CSS isn't a broken and disgusting mess.Inanna
Yes it does work! Just set the width of the div to a % value, but not a fixed pixel value. E.g. width: 95%.Audre
@SpYk3HH Maybe the question title leads to a misunderstanding due to the term "dynamic width". The OP asks with an example of a div with a % width set - which actually is "dynamic" because it adapts to the viewport with. What you are asking for could also be called "dynamic", as it adapts to the content size, so maybe the question title isn't enought descriptive.Alkanet
For anyone interested on clarification for the meaning of dynamic width, please visit Terminology: Does the meaning of “dynamic width” have a consensus?Alkanet
The problem with ‘position: fixed’ is that then the window doesn’t scroll (at least not on Safari on Mac or iPhone). ‘Position: absolute’ is OK in this respect.Foreknow
The question says dynamic width, that's the whole problem, you can't just ignore that.Larimore
It's an old post but could you elaborate on "as if you were centering a static positioned element"? Simply setting the margins to auto does not center a static element, and properties like left and right don't apply to static elements.Amargo
@Amargo any static positioned element will center when left and right margins are set to auto and has with != auto. You can't center an element which has full-with of its containerAlkanet
Oh, the missing bit was that it needs to have an explicit width. Not all elements automatically fill the width of their parent (e.g. <img>) so that maybe a given for divs but not in general.Amargo
@Amargo I think position don't works on inline elements. Don't remember if it does within inline-block elements. You are welcome ;)Alkanet
D
61

Here's another method if you can safely use CSS3's transform property:

.fixed-horizontal-center
{
    position: fixed;
    top: 100px; /* or whatever top you need */
    left: 50%;
    width: auto;
    -webkit-transform: translateX(-50%);
    -moz-transform: translateX(-50%);
    -ms-transform: translateX(-50%);
    -o-transform: translateX(-50%);
    transform: translateX(-50%);
}

...or if you want both horizontal AND vertical centering:

.fixed-center
{
    position: fixed;
    top: 50%;
    left: 50%;
    width: auto;
    height: auto;
    -webkit-transform: translate(-50%,-50%);
    -moz-transform: translate(-50%,-50%);
    -ms-transform: translate(-50%,-50%);
    -o-transform: translate(-50%,-50%);
    transform: translate(-50%,-50%);
}
Detergency answered 1/7, 2015 at 23:18 Comment(4)
As long as it's for a modern browser, this is the BEST solution on this answer! The only one that is like a true `float: center', in that you can click around wrapping element and not be stuck having to fish ways around it. Love this answer!Eatage
Careful, do not use translation in percentage to center text as it will be smoothed if the resulting value is a float. Ho boy, you don't want that, no you don't.Izak
Using CSS transforms can cause smoothing to occur on more than just text; I'm getting funky borders as a result of the transformation.Selfreproach
Potential to contract early when changing screen size (depending on the size of the division), resulting in large boarders around the edge of the division.Karriekarry
A
9

This works regardless of the size of its contents

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

source: https://css-tricks.com/quick-css-trick-how-to-center-an-object-exactly-in-the-center/

Algometer answered 1/2, 2018 at 10:36 Comment(3)
beware: transform: translate(-50%, -50%); causes text to be blurry (at least on chrome)Ilo
@Jiří not in my caseTopsyturvydom
for me also not anymore, maybe it was a bug... but I remember clearly that the whole container became blurred after this, if only slightly... let's delete this discussion?Ilo
A
8
<div id="container">
    <div id="some_kind_of_popup">
        center me
    </div>
</div>

You'd need to wrap it in a container. here's the css

#container{
    position: fixed;
    top: 100px;
    width: 100%;
    text-align: center;
}
#some_kind_of_popup{
    display:inline-block;
    width: 90%;
    max-width: 900px;  
    min-height: 300px;  
}
Austere answered 12/6, 2013 at 15:38 Comment(6)
Ah, i like your thinking. The fixed div will only be a container for another div with the actual result? I'll try this one!Lubeck
While I do like the intuitiveness of your answer I do not see how it would allow support of ie6/7.Austere
@MathewBerg, good point about ie6/7. In that case your answer should work best. This is a little OT, but personally i think developers should'nt spend time fixing stuff for <= ie7. I think actually developers should block those browsers to force people and companies with old systems to upgrade. It is how ever hard to sell that idea to a paying customer! ;)Lubeck
Yes, but unfortunately some companies require support for legacy browsers no matter how far into the future we get. Go ahead and accept either mine or laconbass' answer depending on your needs.Austere
@MathewBerg I agree both with your last comment and the gubbfett one. If the client wants to support ie6/7 it must be done, and the solution you propose effectively does the job.Alkanet
this also doesn't work as you still can't click through "container"Eatage
S
1

This approach will not limit element's width when using margins in flexbox

top: 0; left: 0;
transform: translate(calc(50vw - 50%));

Also for centering it vertically

top: 0; left: 0;
transform: translate(calc(50vw - 50%), calc(50vh - 50%));
Soundboard answered 13/1, 2021 at 1:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.