36

I am using this script to center my div horizontally and vertically.

When the page loads the div gets centered vertically, not horizontally until I resize the browser.

What am I doing wrong?

$(document).ready(function (){
    $(window).resize(function (){
        $('.className').css({
            position:'absolute',
            left: ($(window).width() - $('.className').outerWidth())/2,
            top: ($(window).height() - $('.className').outerHeight())/2
        });
    });
    $(window).resize();
});
Pranav 웃
  • 8,469
  • 6
  • 38
  • 48
user1807777
  • 365
  • 1
  • 3
  • 10

9 Answers9

63

I normally use this "technique":

$(function() {
    $('.className').css({
        'position' : 'absolute',
        'left' : '50%',
        'top' : '50%',
        'margin-left' : -$('.className').width()/2,
        'margin-top' : -$('.className').height()/2
    });
});

UPDATE:

I'm updating the solution, as suggested by the user Fred K, using .outerWidth() and .outerHeight() to have a more precise centering.

$(function() {
    $('.className').css({
        'position' : 'absolute',
        'left' : '50%',
        'top' : '50%',
        'margin-left' : -$('.className').outerWidth()/2,
        'margin-top' : -$('.className').outerHeight()/2
    });
});

Some additional notes from jQuery' documentation (.outerWidth(), .outerHeight()):

  • The number returned by dimensions-related APIs, including .outerWidth(), may be fractional in some cases. Code should not assume it is an integer. Also, dimensions may be incorrect when the page is zoomed by the user; browsers do not expose an API to detect this condition.

  • The value reported by .outerWidth() is not guaranteed to be accurate when the element's parent is hidden. To get an accurate value, you should show the parent first, before using .outerWidth().


UPDATE 2:

A simple update to show how you could use this inside the css() method in case there are more elements with the same class tag with different sizes.

$(function() {
    $('.className').css({
        'position' : 'absolute',
        'left' : '50%',
        'top' : '50%',
        'margin-left' : function() {return -$(this).outerWidth()/2},
        'margin-top' : function() {return -$(this).outerHeight()/2}
    });
});
Community
  • 1
  • 1
Dim13i
  • 1,961
  • 1
  • 17
  • 20
  • 2
    This works for me, but only if I replace the (this) with ('.classname'), probly cuz i am centering a div within another div and 'this' is currently the window size. How do you get 'this' to be the element that youre working on? – Doug Cassidy Dec 06 '13 at 15:10
  • What if I have multiple elements, with different sizes? – Corey Jun 01 '14 at 16:40
  • 1
    Its a good solution, if $(this) doesnt change size. But for example for responsive design elements its another story, if they change size due to screen size decrease, this method fails. – Jānis Gruzis Jul 23 '14 at 09:31
  • Use `outerWidth()` and `outerHeight()` to be sure to get the center – Fred K Feb 23 '15 at 20:17
  • @FredK thatnks for the suggestion, I've updated the solution. – Dim13i Feb 26 '15 at 09:33
  • If you have more than one element, $('.className').outerHeight() is not referring to the current one, IMHO it is better using $(this) inside a .each() – mabi Feb 10 '16 at 10:09
  • 1
    @mabi yes, of course if the `class` tag is not specific enough one could pass a function as parameter in the `css()` method to avoid using the `each()` method. I'll add a quick update. – Dim13i Feb 10 '16 at 12:43
20

use this to center:

$.fn.center = function () {
   this.css("position","absolute");
   this.css("top", ( $(window).height() - this.height() ) / 2  + "px");
   this.css("left", ( $(window).width() - this.width() ) / 2 + "px");
   return this;
}

$('yourElem').center();
Jai
  • 74,255
  • 12
  • 74
  • 103
10

Wrap the handler code in a function so you can call that function both on page load as well as handler for $(window).resize()

/* use as handler for resize*/
$(window).resize(adjustLayout);
/* call function in ready handler*/
$(document).ready(function(){
    adjustLayout();
    /* your other page load code here*/
})

function adjustLayout(){
    $('.className').css({
        position:'absolute',
        left: ($(window).width() - $('.className').outerWidth())/2,
        top: ($(window).height() - $('.className').outerHeight())/2
    });

}
charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • This is great, but it do not work for me on first load of page. It stays at the left side of page. Than, when I start resize the page it jumps in the middle of page. Any idea why? – Pavel Binar Jan 01 '14 at 22:17
  • 1
    @Pavel create a demo in jsfiddle.net that replicates problem – charlietfl Jan 02 '14 at 03:03
  • 2
    $(window).resize(adjustLayout).resize(); should eliminate the mentioned problem. – Tim G Feb 07 '14 at 06:14
3

Related to your code snippet, you need to set the position first:

$(window).resize(function (){
    var $el = $('.className');
    $el.css('position', 'absolute').css({
        left: ($(window).width() - $el.width()) / 2,
        top: ($(window).height() - $el.height()) / 2
    });
});

Maybe you could set the position attribute via a static CSS style.

Matthias
  • 7,432
  • 6
  • 55
  • 88
1

based on @dimi's answer, works better with multiple elements

$(".className").each(
    function () {
       $( this ).css("position","absolute");
       $( this ).css("left","50%");
       $( this ).css("margin-left", - $( this ).outerWidth()/2 );
       $( this ).css("top","50%");
       $( this ).css("margin-top", - $( this ).outerHeight()/2 );
       return this;
    }
);
mabi
  • 522
  • 1
  • 6
  • 20
0

I use this JQuery.center plugin to center my DOM elements. The code will be something like this:

$("#child").center()

The prior code will center relative to its direct parent, if you need to center relative to another parent, it will be:

$("#child").center($("#parent"))

There are customized options, if you need other form of centralization.

Mustafah
  • 4,447
  • 2
  • 24
  • 24
0

I have recently been trying to place a box in the middle of a browser window. I created the code below. The jQuery script is quite long because I took into account all paddings and margins of html and body tags, if someone have set them. If one does not care about the backgrounds, then only winwidth, winheight, toppx, leftpx, and "#container" have to be set. The rest may be deleted.

<!DOCTYPE html>
<html>
<head>
    <title>Test of centre of container</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <style>
        html {
            background-color: #444;
            margin: 30px;
        }
        #wrapper {
            background-color: #777;
            width: 75%;
            margin: 0 auto;
            padding: 0;
        }
        #container {
            background-color: #ddd;
            border-radius: 10px;
            box-shadow: 0 0 2px #222;
            width: 200px;
            height: 100px;
            position: absolute;
            vertical-align: middle;
        }
        #extext {
            text-align: center;
            padding: 0;
        }
    </style>
</head>
<body>
    <script>
        function setDimensions() {
            var winwidth = $(window).width();
            var winheight = $(window).height();
            var htmlmv = parseInt($("html").css("margin-top")) + parseInt($("html").css("margin-bottom"));
            var htmlpv = parseInt($("html").css("padding-top")) + parseInt($("html").css("padding-bottom"));
            var htmlmh = parseInt($("html").css("margin-left")) + parseInt($("html").css("margin-right"));
            var htmlph = parseInt($("html").css("padding-left")) + parseInt($("html").css("padding-right"));
            var bodymv = parseInt($("body").css("margin-top")) + parseInt($("body").css("margin-bottom"));
            var bodypv = parseInt($("body").css("padding-top")) + parseInt($("body").css("padding-bottom"));
            var bodymh = parseInt($("body").css("margin-left")) + parseInt($("body").css("margin-right"));
            var bodyph = parseInt($("body").css("padding-left")) + parseInt($("body").css("padding-right"));
            var vspace = htmlmv + htmlpv + bodymv + bodypv;
            var hspace = htmlmh + htmlph + bodymh + bodyph;
            var wrapheight = winheight - vspace;
            var wrapwidth = winwidth - hspace;
            $("#wrapper").height(wrapheight);
            // $("#wrapper").width(wrapwidth);

            var toppx = (winheight - parseInt($("#container").css("height"))) / 2;
            var leftpx = (winwidth - parseInt($("#container").css("width"))) / 2;
            $("#container").css("top", toppx.toString() + "px");
            $("#container").css("left", leftpx.toString() + "px");
        }

        $(document).ready(function () {
            setDimensions();
        });
        $(window).resize(function () {
            setDimensions();
        });
    </script>
    <div id="wrapper">
        <div id="container">
            <p id="extext">Example text</p>
        </div>
    </div>
</body>
</html>





EDIT: I found much better solution for this on CSS Tricks website and it uses only CSS :). The code's below:

<!DOCTYPE html>
<html>
<head>
    <title>
        Test centring!
    </title>
    <style>
        body div {
            background-color: red;
            box-shadow: 0 0 15px #222;
            border-radius: 10px;
            padding: 10px;
            margin: -150px auto auto -200px;
            width: 380px;
            height: 280px;
            position: absolute;
            top: 50%;
            left: 50%;
            text-align: center;
            line-height: 140px;
        }
        body div h2 {
            color: yellow;
            margin: 0;
            padding: 0;
        }
    </style>
</head>
<body>
    <div>
        <h2>
            Example text<br />
            Example Text
        </h2>
    </div>
</body>
</html>
Celdor
  • 2,437
  • 2
  • 23
  • 44
0

my div with class center has to be centered horizontally in the middle and it's position is fixed. I use this small code to make it happen:

$(window).on('resize load', function () {
    $('.center').each(function () {
        $(this).css({
            'margin-left': ($('body').width() - $(this).width()) / 2
        });
    });
});

you can use same tactics for horizontal alignment too. Take a look that it handles at once on load and on resize events, so this div is always in the middle.

Lukas Liesis
  • 24,652
  • 10
  • 111
  • 109
0

You can use that plugin it is very simple to use https://github.com/tenbullstech/jquery-make-me-center

$("div.box").makemecenter();
Khanakia
  • 723
  • 1
  • 8
  • 20