How to center a div with position: fixed?

7

I wonder if it's possible to center a div with position:fixed ? Currently I tried to centralize it using margin:0 auto but it did not work ... unfortunately as the width of my div fixed will be dynamic I can not use left and margin-left negative T.

CSS Code:

.container {
    background: #F00;
    width:100%;
    height:300px;    
}

.fixo {
    width:100px;
    height:50px;
    background:#000;
    position:fixed;
    top:0px;
    margin:0 auto;
}

HTML code:

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

Follow the code with the example: link

Thank you in advance

    
asked by anonymous 22.09.2014 / 23:15

5 answers

9

You have two options:

JavaScript:

var container = document.querySelector('.fixo'),
    w = window,
    d = document,
    e = d.documentElement,
    g = d.getElementsByTagName('body')[0],
    x = w.innerWidth || e.clientWidth || g.clientWidth,
    y = w.innerHeight|| e.clientHeight|| g.clientHeight;

container.style.top = (y / 2) - (container.clientHeight / 2) + 'px';
container.style.left = (x / 2) - (container.clientWidth / 2) + 'px';

Example: link

CSS:

.fixo {
    width:100px;
    height:50px;
    background:#000;
    position:fixed;
    top:50%; left: 50%;
}

Example: link

The javascript version calculates the height and width of the screen, divides by half and subtracts half the width or height of the element.

The CSS version is approximate. You can adjust if the measurements are +/- static. For modern browsers the @bfavaretto solution is ideal.

Edit:

In cases where it is necessary to support browsers before I suggest using feature-detection. That is, to detect if the Browser supports calc() in CSS ( as @bfavaretto suggested ), and case negative positioning via JavaScript.

Example:

CSS

.fixo {
    width:100px;
    height:50px;
    background:#000;
    position:fixed;
    top:0;
    left: calc(50% - 50px);
}

JavaScript

// usando o feature detect do Modrnizer
var calc = (function(){
    var dummy = document.createElement('div');
    var props = ['calc', '-webkit-calc', '-moz-calc', '-o-calc'];
    for (var i=0; i<props.length; ++i) {
        var prop = props[i];
        dummy.style.cssText = 'width:' + prop + '(1px);';
        if (dummy.style.length)
            return prop;
    }
})();

if (!calc) {
    var container = document.querySelector('.fixo'),
        w = window,
        d = document,
        e = d.documentElement,
        g = d.getElementsByTagName('body')[0],
        x = w.innerWidth || e.clientWidth || g.clientWidth,
        y = w.innerHeight|| e.clientHeight|| g.clientHeight;

    container.style.top = (y / 2) - (container.clientHeight / 2) + 'px';
    container.style.left = (x / 2) - (container.clientWidth / 2) + 'px';
}
    
22.09.2014 / 23:22
4

If your browser gives support you can do so:

left: calc(50% - 50px);

link

That is, place the div on the left half of the width of the container less half the width of the fixed div.

    
22.09.2014 / 23:21
2

If the width of the div is to be dynamic, just to do with CSS, just set the container with 100% width, height 0 (for the leftovers not to be over the page links) and align the centralized text, and the div with the content places it as inline-block and sets the rest of the properties, something like this:

.container {
    position:fixed;
    top:0;
    width:100%;
    height: 0;
    text-align: center;
}
.container .fixo {
    display: inline-block;
    background:#000;
    color: #fff;
    height: 50px;
    line-height: 50px;
    padding: 0 10px;
}

See working at JSFiddle

    
23.09.2014 / 02:33
1

You can do it using only CSS: JSFiddle

This is the "trick":

top:50%; /* Metade da altura da tela */
left:50%; /* Metade da largura da tela */
margin-top:-25px; /* Metade da altura do elemento */
margin-left:-50px; /* Metade da largura do elemento */

Or with relative dimension, using JS / jQuery: JSFiddle

$('.fixo').css({
    'margin-top' : '-' + ($('.fixo').height()/2) + 'px',
    'margin-left' : '-' + ($('.fixo').width()/2) + 'px'
});
    
09.10.2014 / 15:08
0

A modern alternative that does not require the use of JavaScript is as follows:

.container .fixo{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
    
22.02.2016 / 17:17