views:

22263

answers:

9

The title says it all really.

+10  A: 

Center it how? Horizontally, vertically, both? Do you want the div itself centered, or just the content?

To center horizontally:

.mydiv { margin-left: auto; margin-right: auto; }
John Millikin
I've always found this solution to be adequate. Can someone explain why the jQuery approach that calculates exact values has more votes? What happens if the window is resized with that solution, for example?
Drew Noakes
@Drew, The jQuery answer above centers vertically and horizontally which is probably why it has more votes. If you are concerned about adjusting on a browser window resize, you can write a function that binds to the browser window resize event that adjusts the div.
Mike Grace
@Mike, of course. Makes sense, thanks. But isn't it still possible to center vertically using only CSS (that is, without calculating window sizes?) What does using jQuery for this add, and what happens when the window is resized?
Drew Noakes
+4  A: 

Vertically

Chris MacDonald
Took a bit of experimentation to get it working, but this is good.
Marcus Downing
+87  A: 

I like adding functions to jQuery so this function would help:

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

Now we can just write:

$(element).center();
Tony L.
I can't edit but note the missing dot on line 4; change "2+$(window)scrollTop()" to "2+$(window).scrollTop()"
eddiegroves
thanx!! it works for me...
shruti
One change I'd suggest: You should use this.outerHeight() and this.outerWidth() instead of just this.height() and this.width(). Otherwise, if the object has a border or padding, it will end up slightly off-center.
Trevor Burnham
Thanks, just what I needed
Mark Milford
I found that this worked great except in IE7/IE8 compatibility mode, where my element was shunted to the right by a fair bit. molokoloco's below solution worked cross-browser for me.
Rich
A: 

This is untested, but something like this should work.

var myElement = $('#myElement');
myElement.css({
    position: 'absolute',
    left: '50%',
    'margin-left': 0 - (myElement.width() / 2)
});
Andrew Hedges
+10  A: 

I put a jquery plugin here http://plugins.jquery.com/project/autocenter

VERY SHORT VERSION

$('#myDiv').css({top:'50%',left:'50%',margin:'-'+($('#myDiv').height() / 2)+'px 0 0 -'+($('#myDiv').width() / 2)+'px'});

SHORT VERSION

(function($){
    $.fn.extend({
        center: function () {
            return this.each(function() {
                var top = ($(window).height() - $(this).outerHeight()) / 2;
                var left = ($(window).width() - $(this).outerWidth()) / 2;
                $(this).css({position:'absolute', margin:0, top: (top > 0 ? top : 0)+'px', left: (left > 0 ? left : 0)+'px'});
            });
        }
    }); 
})(jQuery);

Activated by this code :

$('#mainDiv').center();

PLUGIN VERSION

(function($){
     $.fn.extend({
          center: function (options) {
               var options =  $.extend({ // Default values
                    inside:window, // element, center into window
                    transition: 0, // millisecond, transition time
                    minX:0, // pixel, minimum left element value
                    minY:0, // pixel, minimum top element value
                    withScrolling:true, // booleen, take care of the scrollbar (scrollTop)
                    vertical:true, // booleen, center vertical
                    horizontal:true // booleen, center horizontal
               }, options);
               return this.each(function() {
                    var props = {position:'absolute'};
                    if (options.vertical) {
                         var top = ($(options.inside).height() - $(this).outerHeight()) / 2;
                         if (options.withScrolling) top += $(options.inside).scrollTop() || 0;
                         top = (top > options.minY ? top : options.minY);
                         $.extend(props, {top: top+'px'});
                    }
                    if (options.horizontal) {
                          var left = ($(options.inside).width() - $(this).outerWidth()) / 2;
                          if (options.withScrolling) left += $(options.inside).scrollLeft() || 0;
                          left = (left > options.minX ? left : options.minX);
                          $.extend(props, {left: left+'px'});
                    }
                    if (options.transition > 0) $(this).animate(props, options.transition);
                    else $(this).css(props);
                    return $(this);
               });
          }
     });
})(jQuery);

Activated by this code :

$(document).ready(function(){
    $('#mainDiv').center();
    $(window).bind('resize', function() {
        $('#mainDiv').center({transition:300});
    });
);

is that right ?

molokoloco
+1  A: 

The transition component of this function worked really poorly for me in Chrome (didn't test elsewhere). I would resize the window a bunch and my element would sort of scoot around slowly, trying to catch up.

So the following function comments that part out. In addition, I added parameters for passing in optional x & y booleans, if you want to center vertically but not horizontally, for example:

// Center an element on the screen
(function($){
  $.fn.extend({
    center: function (x,y) {
      // var options =  $.extend({transition:300, minX:0, minY:0}, options);
      return this.each(function() {
                if (x == undefined) {
                    x = true;
                }
                if (y == undefined) {
                    y = true;
                }
                var $this = $(this);
                var $window = $(window);
                $this.css({
                    position: "absolute",
                });
                if (x) {
                    var left = ($window.width() - $this.outerWidth())/2+$window.scrollLeft();
                    $this.css('left',left)
                }
                if (!y == false) {
            var top = ($window.height() - $this.outerHeight())/2+$window.scrollTop();   
                    $this.css('top',top);
                }
        // $(this).animate({
        //   top: (top > options.minY ? top : options.minY)+'px',
        //   left: (left > options.minX ? left : options.minX)+'px'
        // }, options.transition);
        return $(this);
      });
    }
  });
})(jQuery);
Eric D. Fields
A: 

For some reason he suggests using 300 as the speed parameter which is crazy. When I tried it out I had it set to 5 to get a reasonably smooth effect.

Mike
+2  A: 

I dont think having an absolute position would be best if you want an element always centered in the middle of the page. You probably want a fixed element. I found another jquery centering plugin that used fixed positioning. It is called fixed center.

Fred
Looks good, I will check it out.
Craig
This is good. I've implemented it on one of my blogs and seems to be working well.
Ciaran
A: 

you're getting that poor transition because you're adjusting the position of the element every time the document is scrolled. What you want is to use fixed positioning. I tried that fixed center plugin listed above and that seems to do solve the problem nicely. Fixed positioning allows you to center an element once, and the CSS property will take care of maintaining that position for you every time you scroll.

phpguy